263 lines
7.0 KiB
JavaScript
263 lines
7.0 KiB
JavaScript
#!/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() |