当前位置:   article > 正文

AI工具赋能自动生成单测用例_ai单测生成工具

ai单测生成工具

2024软件测试面试刷题,这个小程序(永久刷题),靠它快速找到工作了!(刷题APP的天花板)_软件测试刷题小程序-CSDN博客文章浏览阅读3k次,点赞86次,收藏13次。你知不知道有这么一个软件测试面试的刷题小程序。里面包含了面试常问的软件测试基础题,web自动化测试、app自动化测试、接口测试、性能测试、自动化测试、安全测试及一些常问到的人力资源题目。最主要的是他还收集了像阿里、华为这样的大厂面试真题,还有互动交流板块……_软件测试刷题小程序​编辑https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502​编辑https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502​编辑https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502​编辑https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502​编辑https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502​编辑https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502icon-default.png?t=N7T8https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502

流程图:

泳道图 (2) (1).png

痛点:

  • ChatGPT单次对话有长度限制
  • 生成内容的不可控性,可能会生成不准确、误导性或者不合适的内容,需要进行后续处理
  • 多轮对话时,要确保有效的维护和处理对话的上下文
  • 接口吞吐过程中的错误处理和反馈

整体代码:

  1. const fs = require('fs').promises
  2. const path = require('path')
  3. const base = process.cwd()
  4. const axios = require('axios')
  5. const categoryToFilter = ['node_modules', '.git', '.husky', '.vscode'] // 要排除的类目名称
  6. let FILE_NAME = 'packages'
  7. let globalSystemPrompt = null
  8. async function init(state) {
  9. await import('inquirer').then(async (inquirerModule) => {
  10. const inquirer = inquirerModule.default
  11. const globalSystemRolePrompt = [
  12. {
  13. name: '你是一名前端开发工程师',
  14. value: '你是一名前端开发工程师'
  15. },
  16. {
  17. name: '你是一名后端开发工程师',
  18. value: '你是一名后端开发工程师'
  19. },
  20. {
  21. name: '自定义角色',
  22. value: ''
  23. }
  24. ]
  25. const arr = [
  26. {
  27. type: 'list',
  28. name: 'globalSystemRolePrompt',
  29. message: '⚡️⚡️⚡️预制您的角色(多选)⚡️⚡️⚡️',
  30. choices: globalSystemRolePrompt,
  31. default: ''
  32. },
  33. {
  34. type: 'input',
  35. name: 'globalSystemPromptContent',
  36. message: '请输入您对于本次的预制Prompt:',
  37. // default: '接下来的对话,我们使用vue3基于antd组件进行了二次开发。在此基础上进行单元测试代码的输出。'
  38. default: '你的工作主要是,基于antd组件进行了二次开发组件的单元测试代码的输出。'
  39. }
  40. ]
  41. await inquirer.prompt(state ? arr : [arr[arr.length - 1]]).then(async (answer) => {
  42. if (!answer.globalSystemRolePrompt && !answer.globalSystemPromptContent) {
  43. return
  44. }
  45. globalSystemPrompt = ` ${globalSystemPrompt || ''} ${answer.globalSystemRolePrompt || ''} ${
  46. answer.globalSystemPromptContent || ''
  47. }`
  48. await use_ai('你是什么角色?你都能做什么事情?回答是否可以开始工作', false, null)
  49. })
  50. })
  51. }
  52. const service = axios.create({
  53. // 在这里可以添加其他配置
  54. timeout: 500000
  55. })
  56. // 禁用 Axios 自动重试
  57. service.defaults.retry = 0 // 设置最大重试次数为 0
  58. async function use_ai(question, filePath, allItem) {
  59. const url = API 地址
  60. const api_key = 'API 密钥' // 替换为实际的 API 密钥
  61. const headers = {
  62. 'Content-Type': 'application/json',
  63. 'api-key': api_key
  64. }
  65. const data = {
  66. temperature: 0,
  67. messages: [
  68. { role: 'system', content: globalSystemPrompt },
  69. { role: 'user', content: question }
  70. ]
  71. }
  72. console.log('\x1b[31muser:==>', `\x1b[0m${question}`)
  73. let spinner = null
  74. import('ora').then((ora) => {
  75. spinner = ora.default('Loading...').start()
  76. })
  77. await axios
  78. .post(url, data, { headers })
  79. .then(async (response) => {
  80. const mes = allItem?.name ? `${allItem?.name} 组件` : ''
  81. spinner.succeed(`已完成 ${mes} `)
  82. const response_json = response.data
  83. const regex = /```javascript([\s\S]*?)```/
  84. const content = response_json.choices[0]?.message?.content.replace(regex, (match, code) => {
  85. return code.trim() // 去掉代码块两端的空白字符
  86. })
  87. console.log('\x1b[32mGPT:==>', `\x1b[0m${response_json.choices[0]?.message?.content}`)
  88. // const content = response_json.choices[0]?.message?.content
  89. // console.log(content)
  90. if (filePath) {
  91. await fs.writeFile(filePath, content, 'utf-8')
  92. } else {
  93. import('inquirer').then(async (inquirerModule) => {
  94. const inquirer = inquirerModule.default
  95. await inquirer
  96. .prompt([
  97. {
  98. type: 'list',
  99. name: 'isInquire',
  100. // message: '⚡️⚡️⚡️选择需要的预制Prompt(多选)⚡️⚡️⚡️',
  101. message: '⚡️⚡️⚡️是否要继续补充Prompt⚡️⚡️⚡️',
  102. choices: [
  103. {
  104. name: '是',
  105. value: 1
  106. },
  107. {
  108. name: '否',
  109. value: 0
  110. }
  111. ],
  112. default: ''
  113. }
  114. ])
  115. .then(async (answer) => {
  116. console.log('\x1b[31m预制Prompt:==>', `\x1b[0m${globalSystemPrompt}`)
  117. console.log('\x1b[32mGPT:==>', `\x1b[0m${content}`)
  118. if (answer.isInquire) {
  119. await init(0)
  120. } else {
  121. await inquirerFun()
  122. }
  123. })
  124. })
  125. }
  126. })
  127. .catch((error) => {
  128. spinner.stop()
  129. console.error('Error:', error)
  130. })
  131. }
  132. // 通过chatgpt接口获取需要单测的内容信息及写入文件
  133. /**
  134. *
  135. * @param {Array} vueFiles 需要单测的数据
  136. * @param {String} choicesQuestion 预制的prompt
  137. */
  138. async function fetchDataAndWriteToFile(vueFiles, choicesQuestion) {
  139. for (const item of vueFiles) {
  140. try {
  141. const folderPath = `${base}/tests/${item.name}` // 文件夹路径
  142. const filePath = path.join(folderPath, `${item.name}.test.js`) // 文件路径
  143. await fs.mkdir(folderPath, { recursive: true })
  144. let pathMes = `单测组件的引入路径为${item.componentPath}`
  145. await use_ai(`${item.content} ${choicesQuestion} ${pathMes}`, filePath, item)
  146. } catch (error) {
  147. console.error('Error:', error)
  148. }
  149. }
  150. }
  151. // 获取需要单测的vue文件内容
  152. /**
  153. * @param {String} directory 根路径
  154. * @returns {Array} vueFiles 获取单测目录的信息
  155. */
  156. async function readVueFilesRecursively(directory) {
  157. try {
  158. const items = await fs.readdir(directory, { withFileTypes: true })
  159. const vueFiles = [] // 获取单测目录的信息
  160. for (const item of items) {
  161. const itemPath = path.join(directory, item.name)
  162. if (item.isDirectory()) {
  163. const nestedVueFiles = await readVueFilesRecursively(itemPath)
  164. vueFiles.push(...nestedVueFiles)
  165. } else if (item.isFile() && path.extname(item.name) === '.vue') {
  166. const segments = itemPath.split(path.sep)
  167. const index = segments.indexOf('src') + 1
  168. const vueFilesName = segments[index].split('.')[0]
  169. const fileContent = await fs.readFile(itemPath, 'utf-8')
  170. const withoutStyle = fileContent.replace(/<style[^>]*>[\s\S]*?<\/style>/g, '')
  171. /**
  172. * @param {String} name 文件名
  173. * @param {String} componentPath 组件路径
  174. * @param {String} content 组件vue中提出style样式的内容
  175. */
  176. vueFiles.push({ name: vueFilesName, componentPath: itemPath.split(':')[1] || '', content: withoutStyle })
  177. }
  178. }
  179. return vueFiles
  180. } catch (error) {
  181. console.error(`Error reading directory ${directory}: ${error}`)
  182. return []
  183. }
  184. }
  185. // readVueFilesRecursively(`${base}/${FILE_NAME}`)
  186. // .then(async (vueFiles) => {
  187. // console.log(vueFiles)
  188. // })
  189. // .catch((error) => {
  190. // console.error('Error:', error)
  191. // })
  192. async function inquirerFun() {
  193. // 终端内选择步骤
  194. import('inquirer').then(async (inquirerModule) => {
  195. const inquirer = inquirerModule.default
  196. // 获取项目一级目录
  197. let filesChoices = null
  198. // 获取选择的prompt
  199. let choicesQuestion = null
  200. const questionInformation = [
  201. // {
  202. // name: '已上代码基于ant-design-vue组件二次开发生成单测用例',
  203. // value: '已上代码基于ant-design-vue组件二次开发生成单测用例'
  204. // },
  205. {
  206. name: '断言是否成功挂载组件',
  207. value: '断言是否成功挂载组件'
  208. },
  209. {
  210. name: '断言是否正确传递了属性',
  211. value: '断言是否正确传递了属性'
  212. },
  213. {
  214. name: '断言插槽内容是否被正确渲染',
  215. value: '断言插槽内容是否被正确渲染'
  216. },
  217. {
  218. name: '断言组件 DOM 是否包含指定的类名',
  219. value: '断言组件 DOM 是否包含指定的类名'
  220. },
  221. {
  222. name: '断言点击事件是否被触发',
  223. value: '断言点击事件是否被触发'
  224. },
  225. {
  226. name: '只输出单测代码,禁止输出文字',
  227. value: '只输出单测代码,禁止输出文字'
  228. }
  229. ]
  230. try {
  231. const items = await fs.readdir(base, { withFileTypes: true })
  232. filesChoices = items
  233. .filter((item) => item.isDirectory() && !categoryToFilter.includes(item.name))
  234. .map((item) => {
  235. return {
  236. name: item.name,
  237. value: item.name
  238. }
  239. })
  240. } catch (error) {
  241. console.error(`Error reading directory ${base}: ${error}`)
  242. }
  243. await inquirer
  244. .prompt([
  245. {
  246. type: 'list',
  247. name: 'ExecutionTest',
  248. message: '⚡️⚡️⚡️选择自动化生成单测用例方案⚡️⚡️⚡️',
  249. choices: [
  250. { name: '全量自动化用例', value: 1 },
  251. { name: '单文件自动化用例', value: 2 },
  252. { name: '放弃生成用例', value: 0 }
  253. ],
  254. default: true
  255. },
  256. {
  257. type: 'list',
  258. name: 'ExecutionTestFile',
  259. message: '⚡️⚡️⚡️请选择要访问的文件目录⚡️⚡️⚡️',
  260. choices: filesChoices,
  261. default: '',
  262. when: (answers) => {
  263. return answers.ExecutionTest
  264. }
  265. },
  266. {
  267. type: 'checkbox',
  268. name: 'ExecutionTestQuestion',
  269. // message: '⚡️⚡️⚡️选择需要的预制Prompt(多选)⚡️⚡️⚡️',
  270. message: '⚡️⚡️⚡️预制的提问信息(多选)⚡️⚡️⚡️',
  271. choices: questionInformation,
  272. default: '',
  273. when: (answers) => {
  274. return answers.ExecutionTest && answers.ExecutionTestFile
  275. }
  276. },
  277. {
  278. type: 'input',
  279. name: 'customQuestion',
  280. // message: '请输入您自定义的Prompt:',
  281. message: '请输入您自定义的提问信息:',
  282. when: (answers) => {
  283. return answers.ExecutionTest
  284. }
  285. }
  286. ])
  287. .then(async (answer) => {
  288. // 取消构建
  289. if (answer.ExecutionTest == 0) {
  290. return
  291. }
  292. // 执行的目录 base
  293. FILE_NAME = answer.ExecutionTestFile
  294. // 选择预制提问信息 + 手动输入的提问信息
  295. choicesQuestion = `${answer.ExecutionTestQuestion.join(',')}${
  296. answer.ExecutionTestQuestion.length && answer.customQuestion ? ',' : '。'
  297. } ${answer.customQuestion}`
  298. if (!choicesQuestion) {
  299. console.error('***请选择或者输入Prompt***')
  300. return
  301. }
  302. // 全链路构建
  303. if (answer.ExecutionTest == 1) {
  304. // console.log('全链路自动构建', FILE_NAME, choicesQuestion)
  305. readVueFilesRecursively(`${base}/${FILE_NAME}`)
  306. .then(async (vueFiles) => {
  307. if (!vueFiles.length) {
  308. return
  309. }
  310. await fetchDataAndWriteToFile(vueFiles, choicesQuestion)
  311. })
  312. .catch((error) => {
  313. console.error('Error:', error)
  314. })
  315. }
  316. // 选择性构建
  317. if (answer.ExecutionTest == 2) {
  318. readVueFilesRecursively(`${base}/${FILE_NAME}`)
  319. .then(async (vueFiles) => {
  320. if (!vueFiles.length) {
  321. return
  322. }
  323. await inquirer
  324. .prompt([
  325. {
  326. type: 'checkbox',
  327. name: 'aloneFileName',
  328. message: '⚡️⚡️⚡️请选择单测组件⚡️⚡️⚡️',
  329. choices: vueFiles.map((item) => {
  330. return {
  331. name: item.name,
  332. value: item.name
  333. }
  334. }),
  335. default: ''
  336. }
  337. ])
  338. .then(async (item) => {
  339. if (!item.aloneFileName) {
  340. return
  341. }
  342. const aloneFileArr = vueFiles.filter((file) => file.name == item.aloneFileName)
  343. // console.log('单独构建单测', FILE_NAME, choicesQuestion, item.aloneFileName, aloneFileArr)
  344. await fetchDataAndWriteToFile(aloneFileArr, choicesQuestion)
  345. })
  346. })
  347. .catch((error) => {
  348. console.error('Error:', error)
  349. })
  350. }
  351. })
  352. })
  353. }
  354. init(1)

行动吧,在路上总比一直观望的要好,未来的你肯定会感谢现在拼搏的自己!如果想学习提升找不到资料,没人答疑解惑时,请及时加入群: 759968159,里面有各种测试开发资料和技术可以一起交流哦。

最后: 下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取【保证100%免费】

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。在这里插入图片描述

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/人工智能uu/article/detail/903069
推荐阅读
相关标签
  

闽ICP备14008679号