初始化
Some checks failed
Some checks failed
This commit is contained in:
263
frontend/scripts/test.js
Normal file
263
frontend/scripts/test.js
Normal file
@@ -0,0 +1,263 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const { spawn } = require('child_process')
|
||||
const path = require('path')
|
||||
const fs = require('fs')
|
||||
|
||||
// 颜色输出函数
|
||||
const colors = {
|
||||
reset: '\x1b[0m',
|
||||
bright: '\x1b[1m',
|
||||
red: '\x1b[31m',
|
||||
green: '\x1b[32m',
|
||||
yellow: '\x1b[33m',
|
||||
blue: '\x1b[34m',
|
||||
magenta: '\x1b[35m',
|
||||
cyan: '\x1b[36m'
|
||||
}
|
||||
|
||||
function colorLog(color, message) {
|
||||
console.log(`${colors[color]}${message}${colors.reset}`)
|
||||
}
|
||||
|
||||
// 解析命令行参数
|
||||
const args = process.argv.slice(2)
|
||||
const options = {
|
||||
unit: args.includes('--unit'),
|
||||
e2e: args.includes('--e2e'),
|
||||
coverage: args.includes('--coverage'),
|
||||
watch: args.includes('--watch'),
|
||||
verbose: args.includes('--verbose'),
|
||||
component: args.includes('--component'),
|
||||
api: args.includes('--api'),
|
||||
store: args.includes('--store'),
|
||||
ci: args.includes('--ci')
|
||||
}
|
||||
|
||||
// 如果没有指定测试类型,默认运行所有测试
|
||||
if (!options.unit && !options.e2e && !options.component && !options.api && !options.store) {
|
||||
options.unit = true
|
||||
options.e2e = true
|
||||
}
|
||||
|
||||
// 构建测试命令
|
||||
function buildTestCommand(type) {
|
||||
let command = 'npx'
|
||||
let args = []
|
||||
|
||||
if (type === 'unit') {
|
||||
args.push('vitest', 'run')
|
||||
|
||||
if (options.coverage) {
|
||||
args.push('--coverage')
|
||||
}
|
||||
|
||||
if (options.watch) {
|
||||
args = args.filter(arg => arg !== 'run')
|
||||
args.push('--watch')
|
||||
}
|
||||
|
||||
if (options.verbose) {
|
||||
args.push('--verbose')
|
||||
}
|
||||
|
||||
// 添加特定的测试文件模式
|
||||
if (options.component) {
|
||||
args.push('--dir', 'tests/unit/components')
|
||||
} else if (options.api) {
|
||||
args.push('--dir', 'tests/unit/services')
|
||||
} else if (options.store) {
|
||||
args.push('--dir', 'tests/unit/stores')
|
||||
}
|
||||
} else if (type === 'e2e') {
|
||||
args.push('playwright', 'test')
|
||||
|
||||
if (options.ci) {
|
||||
args.push('--reporter=line')
|
||||
} else {
|
||||
args.push('--reporter=list')
|
||||
args.push('--reporter=html')
|
||||
}
|
||||
|
||||
if (options.verbose) {
|
||||
args.push('--verbose')
|
||||
}
|
||||
}
|
||||
|
||||
return { command, args }
|
||||
}
|
||||
|
||||
// 运行测试命令
|
||||
function runTestCommand(type) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const { command, args } = buildTestCommand(type)
|
||||
|
||||
colorLog('cyan', `运行 ${type} 测试...`)
|
||||
colorLog('blue', `${command} ${args.join(' ')}`)
|
||||
|
||||
const testProcess = spawn(command, args, {
|
||||
stdio: 'inherit',
|
||||
shell: true,
|
||||
cwd: path.resolve(__dirname, '..')
|
||||
})
|
||||
|
||||
testProcess.on('close', (code) => {
|
||||
if (code === 0) {
|
||||
colorLog('green', `${type} 测试通过!`)
|
||||
resolve(code)
|
||||
} else {
|
||||
colorLog('red', `${type} 测试失败!`)
|
||||
reject(new Error(`${type} 测试失败,退出码: ${code}`))
|
||||
}
|
||||
})
|
||||
|
||||
testProcess.on('error', (error) => {
|
||||
colorLog('red', `运行 ${type} 测试时出错: ${error.message}`)
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 运行代码质量检查
|
||||
function runCodeQualityChecks() {
|
||||
return new Promise((resolve, reject) => {
|
||||
colorLog('cyan', '运行代码质量检查...')
|
||||
|
||||
// 运行ESLint
|
||||
const eslintProcess = spawn('npx', ['eslint', '--ext', '.js,.vue,.ts', 'src/', 'tests/'], {
|
||||
stdio: 'inherit',
|
||||
shell: true,
|
||||
cwd: path.resolve(__dirname, '..')
|
||||
})
|
||||
|
||||
eslintProcess.on('close', (code) => {
|
||||
if (code === 0) {
|
||||
colorLog('green', 'ESLint 检查通过!')
|
||||
|
||||
// 运行Prettier检查
|
||||
const prettierProcess = spawn('npx', ['prettier', '--check', 'src/**/*.{js,vue,ts,css,scss,json,md}'], {
|
||||
stdio: 'inherit',
|
||||
shell: true,
|
||||
cwd: path.resolve(__dirname, '..')
|
||||
})
|
||||
|
||||
prettierProcess.on('close', (prettierCode) => {
|
||||
if (prettierCode === 0) {
|
||||
colorLog('green', 'Prettier 检查通过!')
|
||||
resolve()
|
||||
} else {
|
||||
colorLog('red', 'Prettier 检查失败!')
|
||||
reject(new Error(`Prettier 检查失败,退出码: ${prettierCode}`))
|
||||
}
|
||||
})
|
||||
|
||||
prettierProcess.on('error', (error) => {
|
||||
colorLog('red', `运行 Prettier 检查时出错: ${error.message}`)
|
||||
reject(error)
|
||||
})
|
||||
} else {
|
||||
colorLog('red', 'ESLint 检查失败!')
|
||||
reject(new Error(`ESLint 检查失败,退出码: ${code}`))
|
||||
}
|
||||
})
|
||||
|
||||
eslintProcess.on('error', (error) => {
|
||||
colorLog('red', `运行 ESLint 检查时出错: ${error.message}`)
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 生成测试报告
|
||||
function generateTestReports() {
|
||||
return new Promise((resolve) => {
|
||||
colorLog('cyan', '生成测试报告...')
|
||||
|
||||
// 确保报告目录存在
|
||||
const reportsDir = path.resolve(__dirname, '../reports')
|
||||
if (!fs.existsSync(reportsDir)) {
|
||||
fs.mkdirSync(reportsDir, { recursive: true })
|
||||
}
|
||||
|
||||
// 创建测试报告摘要
|
||||
const summaryPath = path.join(reportsDir, 'test-summary.json')
|
||||
const summary = {
|
||||
timestamp: new Date().toISOString(),
|
||||
tests: {
|
||||
unit: options.unit,
|
||||
e2e: options.e2e,
|
||||
component: options.component,
|
||||
api: options.api,
|
||||
store: options.store
|
||||
},
|
||||
coverage: options.coverage,
|
||||
watch: options.watch,
|
||||
verbose: options.verbose
|
||||
}
|
||||
|
||||
fs.writeFileSync(summaryPath, JSON.stringify(summary, null, 2))
|
||||
colorLog('green', '测试报告已生成!')
|
||||
resolve()
|
||||
})
|
||||
}
|
||||
|
||||
// 主函数
|
||||
async function main() {
|
||||
try {
|
||||
colorLog('bright', '开始运行自动化测试和代码质量检查...')
|
||||
|
||||
// 运行代码质量检查
|
||||
await runCodeQualityChecks()
|
||||
|
||||
// 运行单元测试
|
||||
if (options.unit) {
|
||||
await runTestCommand('unit')
|
||||
}
|
||||
|
||||
// 运行E2E测试
|
||||
if (options.e2e) {
|
||||
await runTestCommand('e2e')
|
||||
}
|
||||
|
||||
// 生成测试报告
|
||||
await generateTestReports()
|
||||
|
||||
colorLog('bright', colorLog('green', '所有测试和代码质量检查通过!'))
|
||||
process.exit(0)
|
||||
} catch (error) {
|
||||
colorLog('red', `测试或代码质量检查失败: ${error.message}`)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// 显示帮助信息
|
||||
function showHelp() {
|
||||
colorLog('bright', '自动化测试和代码质量检查工具')
|
||||
console.log('')
|
||||
console.log('用法: node scripts/test.js [选项]')
|
||||
console.log('')
|
||||
console.log('选项:')
|
||||
console.log(' --unit 运行单元测试')
|
||||
console.log(' --e2e 运行端到端测试')
|
||||
console.log(' --component 运行组件测试')
|
||||
console.log(' --api 运行API服务测试')
|
||||
console.log(' --store 运行状态管理测试')
|
||||
console.log(' --coverage 生成测试覆盖率报告')
|
||||
console.log(' --watch 监视模式运行测试')
|
||||
console.log(' --verbose 详细输出')
|
||||
console.log(' --ci CI模式运行测试')
|
||||
console.log('')
|
||||
console.log('示例:')
|
||||
console.log(' node scripts/test.js --unit --coverage')
|
||||
console.log(' node scripts/test.js --e2e --verbose')
|
||||
console.log(' node scripts/test.js --component --watch')
|
||||
}
|
||||
|
||||
// 检查是否需要显示帮助信息
|
||||
if (args.includes('--help') || args.includes('-h')) {
|
||||
showHelp()
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
// 运行主函数
|
||||
main()
|
||||
Reference in New Issue
Block a user