赞
踩
- const fs = require('fs').promises
- const path = require('path')
- const base = process.cwd()
- const axios = require('axios')
-
- const categoryToFilter = ['node_modules', '.git', '.husky', '.vscode'] // 要排除的类目名称
- let FILE_NAME = 'packages'
-
- let globalSystemPrompt = null
- async function init(state) {
- await import('inquirer').then(async (inquirerModule) => {
- const inquirer = inquirerModule.default
- const globalSystemRolePrompt = [
- {
- name: '你是一名前端开发工程师',
- value: '你是一名前端开发工程师'
- },
- {
- name: '你是一名后端开发工程师',
- value: '你是一名后端开发工程师'
- },
- {
- name: '自定义角色',
- value: ''
- }
- ]
- const arr = [
- {
- type: 'list',
- name: 'globalSystemRolePrompt',
- message: '⚡️⚡️⚡️预制您的角色(多选)⚡️⚡️⚡️',
- choices: globalSystemRolePrompt,
- default: ''
- },
- {
- type: 'input',
- name: 'globalSystemPromptContent',
- message: '请输入您对于本次的预制Prompt:',
- // default: '接下来的对话,我们使用vue3基于antd组件进行了二次开发。在此基础上进行单元测试代码的输出。'
- default: '你的工作主要是,基于antd组件进行了二次开发组件的单元测试代码的输出。'
- }
- ]
- await inquirer.prompt(state ? arr : [arr[arr.length - 1]]).then(async (answer) => {
- if (!answer.globalSystemRolePrompt && !answer.globalSystemPromptContent) {
- return
- }
- globalSystemPrompt = ` ${globalSystemPrompt || ''} ${answer.globalSystemRolePrompt || ''} ${
- answer.globalSystemPromptContent || ''
- }`
- await use_ai('你是什么角色?你都能做什么事情?回答是否可以开始工作', false, null)
- })
- })
- }
-
- const service = axios.create({
- // 在这里可以添加其他配置
- timeout: 500000
- })
-
- // 禁用 Axios 自动重试
- service.defaults.retry = 0 // 设置最大重试次数为 0
-
- async function use_ai(question, filePath, allItem) {
- const url = API 地址
-
- const api_key = 'API 密钥' // 替换为实际的 API 密钥
-
- const headers = {
- 'Content-Type': 'application/json',
- 'api-key': api_key
- }
-
- const data = {
- temperature: 0,
- messages: [
- { role: 'system', content: globalSystemPrompt },
- { role: 'user', content: question }
- ]
- }
- console.log('\x1b[31muser:==>', `\x1b[0m${question}`)
-
- let spinner = null
- import('ora').then((ora) => {
- spinner = ora.default('Loading...').start()
- })
- await axios
- .post(url, data, { headers })
- .then(async (response) => {
- const mes = allItem?.name ? `${allItem?.name} 组件` : ''
- spinner.succeed(`已完成 ${mes} `)
- const response_json = response.data
- const regex = /```javascript([\s\S]*?)```/
- const content = response_json.choices[0]?.message?.content.replace(regex, (match, code) => {
- return code.trim() // 去掉代码块两端的空白字符
- })
-
- console.log('\x1b[32mGPT:==>', `\x1b[0m${response_json.choices[0]?.message?.content}`)
- // const content = response_json.choices[0]?.message?.content
- // console.log(content)
- if (filePath) {
- await fs.writeFile(filePath, content, 'utf-8')
- } else {
- import('inquirer').then(async (inquirerModule) => {
- const inquirer = inquirerModule.default
- await inquirer
- .prompt([
- {
- type: 'list',
- name: 'isInquire',
- // message: '⚡️⚡️⚡️选择需要的预制Prompt(多选)⚡️⚡️⚡️',
- message: '⚡️⚡️⚡️是否要继续补充Prompt⚡️⚡️⚡️',
- choices: [
- {
- name: '是',
- value: 1
- },
- {
- name: '否',
- value: 0
- }
- ],
- default: ''
- }
- ])
- .then(async (answer) => {
- console.log('\x1b[31m预制Prompt:==>', `\x1b[0m${globalSystemPrompt}`)
-
- console.log('\x1b[32mGPT:==>', `\x1b[0m${content}`)
-
- if (answer.isInquire) {
- await init(0)
- } else {
- await inquirerFun()
- }
- })
- })
- }
- })
- .catch((error) => {
- spinner.stop()
- console.error('Error:', error)
- })
- }
-
- // 通过chatgpt接口获取需要单测的内容信息及写入文件
- /**
- *
- * @param {Array} vueFiles 需要单测的数据
- * @param {String} choicesQuestion 预制的prompt
- */
- async function fetchDataAndWriteToFile(vueFiles, choicesQuestion) {
- for (const item of vueFiles) {
- try {
- const folderPath = `${base}/tests/${item.name}` // 文件夹路径
- const filePath = path.join(folderPath, `${item.name}.test.js`) // 文件路径
- await fs.mkdir(folderPath, { recursive: true })
- let pathMes = `单测组件的引入路径为${item.componentPath}`
- await use_ai(`${item.content} ${choicesQuestion} ${pathMes}`, filePath, item)
- } catch (error) {
- console.error('Error:', error)
- }
- }
- }
- // 获取需要单测的vue文件内容
- /**
- * @param {String} directory 根路径
- * @returns {Array} vueFiles 获取单测目录的信息
- */
- async function readVueFilesRecursively(directory) {
- try {
- const items = await fs.readdir(directory, { withFileTypes: true })
-
- const vueFiles = [] // 获取单测目录的信息
-
- for (const item of items) {
- const itemPath = path.join(directory, item.name)
-
- if (item.isDirectory()) {
- const nestedVueFiles = await readVueFilesRecursively(itemPath)
- vueFiles.push(...nestedVueFiles)
- } else if (item.isFile() && path.extname(item.name) === '.vue') {
- const segments = itemPath.split(path.sep)
- const index = segments.indexOf('src') + 1
-
- const vueFilesName = segments[index].split('.')[0]
- const fileContent = await fs.readFile(itemPath, 'utf-8')
- const withoutStyle = fileContent.replace(/<style[^>]*>[\s\S]*?<\/style>/g, '')
- /**
- * @param {String} name 文件名
- * @param {String} componentPath 组件路径
- * @param {String} content 组件vue中提出style样式的内容
- */
- vueFiles.push({ name: vueFilesName, componentPath: itemPath.split(':')[1] || '', content: withoutStyle })
- }
- }
-
- return vueFiles
- } catch (error) {
- console.error(`Error reading directory ${directory}: ${error}`)
- return []
- }
- }
- // readVueFilesRecursively(`${base}/${FILE_NAME}`)
- // .then(async (vueFiles) => {
- // console.log(vueFiles)
- // })
- // .catch((error) => {
- // console.error('Error:', error)
- // })
- async function inquirerFun() {
- // 终端内选择步骤
- import('inquirer').then(async (inquirerModule) => {
- const inquirer = inquirerModule.default
- // 获取项目一级目录
- let filesChoices = null
- // 获取选择的prompt
- let choicesQuestion = null
- const questionInformation = [
- // {
- // name: '已上代码基于ant-design-vue组件二次开发生成单测用例',
- // value: '已上代码基于ant-design-vue组件二次开发生成单测用例'
- // },
- {
- name: '断言是否成功挂载组件',
- value: '断言是否成功挂载组件'
- },
- {
- name: '断言是否正确传递了属性',
- value: '断言是否正确传递了属性'
- },
- {
- name: '断言插槽内容是否被正确渲染',
- value: '断言插槽内容是否被正确渲染'
- },
- {
- name: '断言组件 DOM 是否包含指定的类名',
- value: '断言组件 DOM 是否包含指定的类名'
- },
- {
- name: '断言点击事件是否被触发',
- value: '断言点击事件是否被触发'
- },
- {
- name: '只输出单测代码,禁止输出文字',
- value: '只输出单测代码,禁止输出文字'
- }
- ]
- try {
- const items = await fs.readdir(base, { withFileTypes: true })
- filesChoices = items
- .filter((item) => item.isDirectory() && !categoryToFilter.includes(item.name))
- .map((item) => {
- return {
- name: item.name,
- value: item.name
- }
- })
- } catch (error) {
- console.error(`Error reading directory ${base}: ${error}`)
- }
- await inquirer
- .prompt([
- {
- type: 'list',
- name: 'ExecutionTest',
- message: '⚡️⚡️⚡️选择自动化生成单测用例方案⚡️⚡️⚡️',
- choices: [
- { name: '全量自动化用例', value: 1 },
- { name: '单文件自动化用例', value: 2 },
- { name: '放弃生成用例', value: 0 }
- ],
- default: true
- },
- {
- type: 'list',
- name: 'ExecutionTestFile',
- message: '⚡️⚡️⚡️请选择要访问的文件目录⚡️⚡️⚡️',
- choices: filesChoices,
- default: '',
- when: (answers) => {
- return answers.ExecutionTest
- }
- },
- {
- type: 'checkbox',
- name: 'ExecutionTestQuestion',
- // message: '⚡️⚡️⚡️选择需要的预制Prompt(多选)⚡️⚡️⚡️',
- message: '⚡️⚡️⚡️预制的提问信息(多选)⚡️⚡️⚡️',
- choices: questionInformation,
- default: '',
- when: (answers) => {
- return answers.ExecutionTest && answers.ExecutionTestFile
- }
- },
- {
- type: 'input',
- name: 'customQuestion',
- // message: '请输入您自定义的Prompt:',
- message: '请输入您自定义的提问信息:',
- when: (answers) => {
- return answers.ExecutionTest
- }
- }
- ])
- .then(async (answer) => {
- // 取消构建
- if (answer.ExecutionTest == 0) {
- return
- }
- // 执行的目录 base
- FILE_NAME = answer.ExecutionTestFile
-
- // 选择预制提问信息 + 手动输入的提问信息
- choicesQuestion = `${answer.ExecutionTestQuestion.join(',')}${
- answer.ExecutionTestQuestion.length && answer.customQuestion ? ',' : '。'
- } ${answer.customQuestion}`
- if (!choicesQuestion) {
- console.error('***请选择或者输入Prompt***')
- return
- }
-
- // 全链路构建
- if (answer.ExecutionTest == 1) {
- // console.log('全链路自动构建', FILE_NAME, choicesQuestion)
- readVueFilesRecursively(`${base}/${FILE_NAME}`)
- .then(async (vueFiles) => {
- if (!vueFiles.length) {
- return
- }
- await fetchDataAndWriteToFile(vueFiles, choicesQuestion)
- })
- .catch((error) => {
- console.error('Error:', error)
- })
- }
-
- // 选择性构建
- if (answer.ExecutionTest == 2) {
- readVueFilesRecursively(`${base}/${FILE_NAME}`)
- .then(async (vueFiles) => {
- if (!vueFiles.length) {
- return
- }
- await inquirer
- .prompt([
- {
- type: 'checkbox',
- name: 'aloneFileName',
- message: '⚡️⚡️⚡️请选择单测组件⚡️⚡️⚡️',
- choices: vueFiles.map((item) => {
- return {
- name: item.name,
- value: item.name
- }
- }),
- default: ''
- }
- ])
- .then(async (item) => {
- if (!item.aloneFileName) {
- return
- }
- const aloneFileArr = vueFiles.filter((file) => file.name == item.aloneFileName)
- // console.log('单独构建单测', FILE_NAME, choicesQuestion, item.aloneFileName, aloneFileArr)
- await fetchDataAndWriteToFile(aloneFileArr, choicesQuestion)
- })
- })
- .catch((error) => {
- console.error('Error:', error)
- })
- }
- })
- })
- }
-
- init(1)
-
行动吧,在路上总比一直观望的要好,未来的你肯定会感谢现在拼搏的自己!如果想学习提升找不到资料,没人答疑解惑时,请及时加入群: 759968159,里面有各种测试开发资料和技术可以一起交流哦。
最后: 下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取【保证100%免费】
软件测试面试文档
我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。