const fs = require('fs'); const path = require('path'); const resultsDir = 'test-results'; const reportDir = 'test-results'; console.log('📊 生成测试报告...'); if (!fs.existsSync(resultsDir)) { console.log('❌ 测试结果目录不存在'); process.exit(1); } const jsonFiles = fs.readdirSync(resultsDir) .filter(file => file.endsWith('.json') && file.includes('-results.json')); if (jsonFiles.length === 0) { console.log('❌ 未找到测试结果文件'); process.exit(1); } console.log(`📁 找到 ${jsonFiles.length} 个测试结果文件`); const allResults = []; for (const file of jsonFiles) { const filePath = path.join(resultsDir, file); const data = JSON.parse(fs.readFileSync(filePath, 'utf-8')); if (data.suites) { for (const suite of data.suites) { for (const spec of suite.suites) { for (const test of spec.tests) { const result = test.results[0]; allResults.push({ testId: `${spec.file}::${test.title}`, file: spec.file, title: test.title, status: result.status, duration: result.duration, tier: file.includes('fast') ? 'fast' : file.includes('deep') ? 'deep' : 'standard', }); } } } } } const report = { timestamp: new Date().toISOString(), total: { name: 'total', total: allResults.length, passed: allResults.filter(r => r.status === 'passed').length, failed: allResults.filter(r => r.status === 'failed').length, skipped: allResults.filter(r => r.status === 'skipped').length, duration: allResults.reduce((sum, r) => sum + r.duration, 0), }, tiers: { fast: allResults.filter(r => r.tier === 'fast').reduce((acc, r) => ({ name: 'fast', total: acc.total + 1, passed: acc.passed + (r.status === 'passed' ? 1 : 0), failed: acc.failed + (r.status === 'failed' ? 1 : 0), duration: acc.duration + r.duration, }), { name: 'fast', total: 0, passed: 0, failed: 0, duration: 0 }), standard: allResults.filter(r => r.tier === 'standard').reduce((acc, r) => ({ name: 'standard', total: acc.total + 1, passed: acc.passed + (r.status === 'passed' ? 1 : 0), failed: acc.failed + (r.status === 'failed' ? 1 : 0), duration: acc.duration + r.duration, }), { name: 'standard', total: 0, passed: 0, failed: 0, duration: 0 }), deep: allResults.filter(r => r.tier === 'deep').reduce((acc, r) => ({ name: 'deep', total: acc.total + 1, passed: acc.passed + (r.status === 'passed' ? 1 : 0), failed: acc.failed + (r.status === 'failed' ? 1 : 0), duration: acc.duration + r.duration, }), { name: 'deep', total: 0, passed: 0, failed: 0, duration: 0 }), }, failedTests: allResults.filter(r => r.status === 'failed'), slowTests: allResults.filter(r => r.duration > 120000), }; report.total.avgDuration = report.total.duration / report.total.total; const reportPath = path.join(reportDir, 'ci-report.json'); fs.writeFileSync(reportPath, JSON.stringify(report, null, 2)); console.log('✅ 测试报告生成完成'); console.log(` 总测试数: ${report.total.total}`); console.log(` 通过: ${report.total.passed}`); console.log(` 失败: ${report.total.failed}`); console.log(` 总耗时: ${(report.total.duration / 1000).toFixed(2)}s`); if (report.total.failed > 0) { console.log(`\n❌ 发现 ${report.total.failed} 个失败测试`); process.exit(1); }