第九章:质量保障体系
OpenMatrix 的质量保障体系通过七个质量门禁确保代码质量,是可信交付的核心保障。
9.1 质量门禁总览
七个质量门禁
graph TD
A[代码提交] --> B1[Build 检查]
B1 --> B2[Test 运行]
B2 --> B3[Coverage 检查]
B3 --> B4[Lint 检查]
B4 --> B5[Security 扫描]
B5 --> B6[E2E 测试]
B6 --> B7[Acceptance 标准]
B7 --> C{全部通过?}
C --> |"是"| D[进入 Accept 阶段]
C --> |"否"| E[返回失败报告]
门禁与质量等级
| 门禁 | strict | balanced | fast |
|---|---|---|---|
| Build | ✓ | ✓ | ✓ |
| Test | ✓ | ✓ | ✓ |
| Coverage >80% | ✓ | ✗ | ✗ |
| Coverage >60% | ✗ | ✓ | ✗ |
| Strict Lint | ✓ | ✗ | ✗ |
| Standard Lint | ✗ | ✓ | ✗ |
| Security | ✓ | ✓ | ✗ |
| E2E | Optional | Optional | ✗ |
| AI Review | ✓ | ✓ | ✗ |
质量评分公式
OpenMatrix 使用加权评分模型计算综合质量得分:
其中:
- 为第 个门禁的权重
- 为第 个门禁的得分(0-100)
权重配置:
| 门禁 | strict | balanced | fast |
|---|---|---|---|
| Build | 0.20 | 0.25 | 0.50 |
| Test | 0.20 | 0.25 | 0.50 |
| Coverage | 0.15 | 0.15 | 0 |
| Lint | 0.10 | 0.10 | 0 |
| Security | 0.15 | 0.15 | 0 |
| E2E | 0.10 | 0.10 | 0 |
| AI Review | 0.10 | 0.10 | 0 |
得分阈值:
- :通过
- :警告(可接受)
- :失败
9.2 Build 检查
目的
确保代码可以成功编译/构建。
执行命令
npm run build
检查内容
| 检查项 | 说明 | 错误示例 |
|---|---|---|
| TypeScript 编译 | 无类型错误 | TS2339: Property 'x' does not exist |
| 依赖解析 | 所有导入有效 | Cannot find module 'xxx' |
| 输出生成 | dist/ 目录正确生成 | ENOENT: no such file or directory |
实际输出案例
成功输出:
✓ Build Check Passed
─────────────────────────────
Compiler: TypeScript 5.3.3
Duration: 12.5s
Output: dist/
├── index.js (45.2 KB)
├── index.d.ts (12.8 KB)
└── utils/
└── helpers.js (8.3 KB)
Files compiled: 23
Warnings: 0
Errors: 0
失败输出:
✗ Build Check Failed
─────────────────────────────
Errors: 2
[1] src/models/user.ts:42:10
TS2339: Property 'validate' does not exist on type 'User'.
[2] src/api/auth.ts:15:5
TS2307: Cannot find module '../config' or its corresponding declarations.
Duration: 2.3s
Files with errors: 2
Fix suggestions:
1. Add 'validate' method to User class
2. Check import path: '../config' → './config'
调优建议
- 增量编译:使用
tsc --incremental加速 - 并行编译:配置
typescript的maxNodeModuleJsDepth - 缓存利用:启用
tsconfig.json中的composite: true
{
"compilerOptions": {
"incremental": true,
"composite": true,
"tsBuildInfoFile": ".tsbuildinfo"
}
}
9.3 Test 运行
目的
确保所有测试通过。
执行命令
npm test
支持的测试框架
| 框架 | 检测方式 | 配置文件 |
|---|---|---|
| Vitest | vitest in dependencies | vitest.config.ts |
| Jest | jest in dependencies | jest.config.js |
| Mocha | mocha in dependencies | .mocharc.json |
实际输出案例
成功输出:
✓ Test Check Passed
─────────────────────────────
Framework: Vitest 1.6.0
Duration: 3.5s
Test Files 12 passed (12)
Tests 156 passed (156)
Start at 14:32:15
Duration 3.52s (transform 0.8s, setup 0.3s, collect 0.5s, tests 1.9s)
Coverage:
Statements: 85.2%
Branches: 78.6%
Functions: 90.1%
Lines: 84.8%
失败输出:
✗ Test Check Failed
─────────────────────────────
Framework: Vitest 1.6.0
Duration: 5.2s
Test Files 10 passed, 2 failed (12)
Tests 145 passed, 11 failed (156)
Failed Tests:
[1] tests/auth.test.ts:45 - "should validate JWT token"
AssertionError: expected false to be true
at tests/auth.test.ts:48:12
[2] tests/user.test.ts:102 - "should hash password"
Error: Cannot read property 'hash' of undefined
at src/utils/crypto.ts:15:8
Failures Summary:
- Auth: 3 failures
- User: 8 failures
Rerun with: npm test -- --reporter=verbose
调优建议
- 并行执行:配置测试框架并行运行
- 测试隔离:确保测试之间无状态依赖
- 快照更新:定期更新快照避免假失败
// vitest.config.ts
export default defineConfig({
test: {
pool: 'threads',
poolOptions: {
threads: {
singleThread: false,
minThreads: 2,
maxThreads: 4
}
}
}
});
9.4 Coverage 检查
目的
确保代码覆盖率达到阈值。
执行命令
npm test -- --coverage
覆盖率类型详解
| 类型 | 说明 | 计算公式 |
|---|---|---|
| Line | 行覆盖率 | |
| Function | 函数覆盖率 | |
| Branch | 分支覆盖率 | |
| Statement | 语句覆盖率 |
实际输出案例
成功输出:
✓ Coverage Check Passed
─────────────────────────────
Threshold: 80%
Coverage Report:
┌─────────────────┬────────┬────────┬────────┬────────┐
│ File │ Lines │ Branch │ Func │ Stmt │
├─────────────────┼────────┼────────┼────────┼────────┤
│ src/index.ts │ 95.2% │ 88.0% │ 100% │ 95.0% │
│ src/models/ │ 88.5% │ 75.0% │ 90.0% │ 87.2% │
│ src/api/ │ 82.1% │ 70.5% │ 85.0% │ 81.8% │
│ src/utils/ │ 91.3% │ 82.0% │ 95.0% │ 90.5% │
├─────────────────┼────────┼────────┼────────┼────────┤
│ TOTAL │ 85.2% │ 78.6% │ 90.1% │ 84.8% │
└─────────────────┴────────┴────────┴────────┴────────┘
Uncovered Lines:
- src/api/auth.ts: 45-52 (error handling)
- src/models/user.ts: 120-125 (edge case)
失败输出:
✗ Coverage Check Failed
─────────────────────────────
Threshold: 80%
Actual: 72.5%
Gap: 7.5%
Uncovered Areas:
High Priority (0% coverage):
- src/api/websocket.ts: Entire file
- src/utils/logger.ts: 15-45
Medium Priority (<50% coverage):
- src/models/config.ts: 45-80
- src/api/upload.ts: 30-60
Improvement Suggestions:
1. Add tests for websocket.ts (estimated +5%)
2. Add tests for logger.ts error paths (estimated +2%)
3. Add integration tests for config.ts (estimated +1.5%)
调优建议
- 排除配置:排除不需要覆盖的文件
{
"coverage": {
"exclude": [
"**/*.d.ts",
"**/dist/**",
"**/node_modules/**",
"**/*.config.ts",
"**/*.test.ts"
]
}
}
-
增量覆盖:只检查变更文件的覆盖率
-
覆盖率报告:生成 HTML 报告便于分析
npm test -- --coverage --reporter=html
9.5 Lint 检查
目的
确保代码符合规范。
执行命令
npm run lint
支持的 Lint 工具
| 工具 | 检测方式 | 速度 | 功能 |
|---|---|---|---|
| ESLint | eslint in dependencies | 中等 | 插件丰富 |
| Biome | biome in dependencies | 快速 | 格式化+Lint |
| Standard | standard in dependencies | 中等 | 零配置 |
Strict vs Standard 配置
// Strict 配置示例
module.exports = {
rules: {
'no-unused-vars': 'error',
'no-console': 'error',
'@typescript-eslint/explicit-function-return-type': 'error',
'complexity': ['error', 10]
}
};
// Standard 配置示例
module.exports = {
rules: {
'no-unused-vars': 'warn',
'no-console': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'complexity': 'off'
}
};
实际输出案例
成功输出:
✓ Lint Check Passed
─────────────────────────────
Linter: ESLint 8.57.0
Config: .eslintrc.strict.js
Duration: 2.1s
Files checked: 45
Errors: 0
Warnings: 3
Warnings (low priority):
- src/utils/helpers.ts:25 - Consider adding JSDoc
- src/api/routes.ts:120 - Function complexity 8/10
- src/models/user.ts:80 - Missing return type annotation
失败输出:
✗ Lint Check Failed
─────────────────────────────
Linter: ESLint 8.57.0
Duration: 1.8s
Files checked: 45
Errors: 5
Warnings: 12
Errors:
[1] src/api/auth.ts:45:10
no-unused-vars: 'temp' is defined but never used
Fix: Remove unused variable or prefix with underscore
[2] src/models/user.ts:80:5
@typescript-eslint/explicit-function-return-type: Missing return type
Fix: Add ': User | null' return type annotation
[3] src/utils/helpers.ts:120:1
complexity: Function has complexity of 15 (max: 10)
Fix: Break down into smaller functions
[4] src/api/routes.ts:200:1
no-console: Unexpected console statement
Fix: Use logger instead
[5] src/config/index.ts:15:1
no-process-env: Do not use process.env directly
Fix: Use config.get('VAR_NAME')
Auto-fix available for 3 errors. Run: npm run lint -- --fix
调优建议
- 自动修复:配置 pre-commit hook 自动修复
{
"lint-staged": {
"*.ts": ["eslint --fix", "prettier --write"]
}
}
-
增量检查:只检查变更文件
-
性能优化:启用缓存
module.exports = {
cache: true,
cacheLocation: '.eslintcache'
};
9.6 Security 扫描
目的
检查依赖中的安全漏洞。
执行命令
npm audit
漏洞级别与处理
| 级别 | CVSS 分数 | 说明 | 处理方式 |
|---|---|---|---|
| Critical | 9.0-10.0 | 可被远程利用 | 立即修复 |
| High | 7.0-8.9 | 可导致数据泄露 | 优先修复 |
| Moderate | 4.0-6.9 | 需要特定条件 | 计划修复 |
| Low | 0.1-3.9 | 影响有限 | 可忽略 |
实际输出案例
成功输出:
✓ Security Check Passed
─────────────────────────────
Scanner: npm audit
Duration: 1.2s
Dependencies: 245 direct, 1,234 transitive
Vulnerabilities found: 0
Known advisories checked: 2,456
失败输出:
✗ Security Check Failed
─────────────────────────────
Scanner: npm audit
Duration: 1.5s
Vulnerabilities Summary:
┌───────────┬───────────┬───────────┬───────────┐
│ Critical │ High │ Moderate │ Low │
├───────────┼───────────┼───────────┼───────────┤
│ 1 │ 2 │ 5 │ 8 │
└───────────┴───────────┴───────────┴───────────┘
Critical Vulnerabilities:
[1] lodash < 4.17.21
CVE-2021-23337: Prototype Pollution
CVSS: 9.8 (Critical)
Package: lodash@4.17.15
Fixed in: lodash@4.17.21
Path: app > express > lodash
Fix: npm install lodash@latest
High Vulnerabilities:
[1] axios < 0.21.2
CVE-2021-3749: SSRF
CVSS: 7.5 (High)
Package: axios@0.21.1
Fixed in: axios@0.21.2
Fix: npm install axios@latest
Fix Commands:
npm audit fix # Auto-fix safe updates
npm audit fix --force # Include breaking changes
调优建议
- 审计配置:配置忽略已知且可接受的漏洞
{
"audit": {
"ignore": [
{
"id": "CVE-XXXX-XXXX",
"reason": "Not used in production",
"until": "2024-12-31"
}
]
}
}
-
定期扫描:配置 CI 每日安全扫描
-
依赖锁定:使用 lockfile 固定版本
9.7 E2E 测试
目的
进行端到端集成测试。
执行命令
npm run e2e
支持的 E2E 工具
| 工具 | 优势 | 适用场景 |
|---|---|---|
| Playwright | 跨浏览器、快速 | Web 应用 |
| Cypress | 调试友好、API 简洁 | Web 应用 |
| Puppeteer | Chrome 原生支持 | Chrome 专用 |
实际输出案例
成功输出:
✓ E2E Check Passed
─────────────────────────────
Runner: Playwright 1.42.0
Browsers: chromium, firefox, webkit
Duration: 45.2s
Test Suites: 5
Tests: 32 passed, 32 total
Results by Browser:
┌─────────────┬────────┬────────┬────────┐
│ Browser │ Passed │ Failed │ Time │
├─────────────┼────────┼────────┼────────┤
│ chromium │ 32 │ 0 │ 12.5s │
│ firefox │ 32 │ 0 │ 15.3s │
│ webkit │ 32 │ 0 │ 17.4s │
└─────────────┴────────┴────────┴────────┘
Key Scenarios:
✓ User registration flow
✓ Login with OAuth
✓ Shopping cart operations
✓ Payment processing
✓ Order tracking
失败输出:
✗ E2E Check Failed
─────────────────────────────
Runner: Playwright 1.42.0
Duration: 52.1s
Test Suites: 5
Tests: 28 passed, 4 failed, 32 total
Failed Tests:
[1] tests/e2e/checkout.spec.ts:45
"should complete payment"
Browser: chromium
Error: Timeout waiting for element '#payment-success'
Screenshot: screenshots/checkout-fail-1.png
[2] tests/e2e/auth.spec.ts:120
"should handle OAuth callback"
Browser: firefox
Error: Navigation to /callback timed out
Screenshot: screenshots/auth-fail-1.png
Screenshots saved to: test-results/screenshots/
Trace viewer: npx playwright show-trace trace.zip
调优建议
- 并行执行:配置多 Worker 并行
// playwright.config.ts
export default defineConfig({
workers: process.env.CI ? 4 : 2,
fullyParallel: true
});
- 重试策略:配置失败重试
export default defineConfig({
retries: process.env.CI ? 2 : 0
});
- 选择性执行:只运行相关测试
npm run e2e -- --grep "checkout"
9.8 Acceptance 标准
目的
验证任务特定的接受标准。
标准定义与验证
interface AcceptanceCriteria {
items: AcceptanceItem[];
custom?: CustomCriterion[];
}
interface AcceptanceItem {
id: string;
description: string;
type: 'functional' | 'performance' | 'security' | 'ux';
verification: VerificationMethod;
}
实际输出案例
成功输出:
✓ Acceptance Criteria Met
─────────────────────────────
Task: TASK-001 - User Authentication
Criteria:
✓ AC-001: User can register with email
✓ AC-002: Password must be at least 8 characters
✓ AC-003: Login returns JWT token
✓ AC-004: Token expires after 7 days
✓ AC-005: Logout invalidates token
Performance Criteria:
✓ P-001: Login response < 200ms (actual: 145ms)
✓ P-002: Registration < 500ms (actual: 320ms)
Security Criteria:
✓ S-001: Password hashed with bcrypt
✓ S-002: No sensitive data in logs
✓ S-003: Rate limiting enabled
UX Criteria:
✓ U-001: Clear error messages
✓ U-002: Password strength indicator
All 12 criteria verified ✓
失败输出:
✗ Acceptance Criteria Not Met
─────────────────────────────
Task: TASK-001 - User Authentication
Passed: 9/12
Failed Criteria:
[AC-003] Login returns JWT token
Expected: JWT with 7 day expiry
Actual: JWT with 1 day expiry
Impact: High - affects user experience
[P-001] Login response < 200ms
Expected: < 200ms
Actual: 450ms
Impact: Medium - performance issue
[S-002] No sensitive data in logs
Issue: Password visible in debug logs
Location: src/api/auth.ts:45
Impact: Critical - security vulnerability
Remediation Required:
1. Update JWT expiry to 7 days
2. Optimize login query (add index)
3. Remove password from debug logs
9.9 AI Review
目的
使用 AI 进行代码质量审查。
审查维度与评分
评分标准详解
| 分数 | 描述 | 标准 |
|---|---|---|
| 9-10 | 优秀 | 代码质量高,无明显问题,可直接合并 |
| 7-8 | 良好 | 有小问题但不影响功能,建议改进 |
| 5-6 | 一般 | 有明显问题需要改进,不阻塞合并 |
| 3-4 | 较差 | 有严重问题,必须改进后才能合并 |
| 1-2 | 严重 | 代码质量不合格,必须重写 |
实际输出案例
成功输出:
✓ AI Review Passed
─────────────────────────────
Model: Claude 3.5 Sonnet
Duration: 5.2s
Review Scores:
┌─────────────────┬───────┬───────────────────────────┐
│ Dimension │ Score │ Notes │
├─────────────────┼───────┼───────────────────────────┤
│ Code Quality │ 9/10 │ Well-structured │
│ Best Practices │ 8/10 │ Minor improvements needed │
│ Security │ 8/10 │ Good validation │
│ Documentation │ 7/10 │ Could add more JSDoc │
├─────────────────┼───────┼───────────────────────────┤
│ OVERALL │ 8/10 │ APPROVED │
└─────────────────┴───────┴───────────────────────────┘
Strengths:
✓ Clear separation of concerns
✓ Proper error handling
✓ Consistent naming conventions
✓ Good test coverage
Improvements:
→ Add JSDoc for public methods (3 locations)
→ Consider extracting validation logic to utils
→ Add more inline comments for complex logic
Recommendation: Approve with minor improvements
失败输出:
✗ AI Review Failed
─────────────────────────────
Model: Claude 3.5 Sonnet
Duration: 4.8s
Review Scores:
┌─────────────────┬───────┬───────────────────────────┐
│ Dimension │ Score │ Issues │
├─────────────────┼───────┼───────────────────────────┤
│ Code Quality │ 4/10 │ Complex, hard to read │
│ Best Practices │ 5/10 │ Violates SOLID │
│ Security │ 3/10 │ SQL injection risk │
│ Documentation │ 2/10 │ No comments │
├─────────────────┼───────┼───────────────────────────┤
│ OVERALL │ 3.5/10│ NOT APPROVED │
└─────────────────┴───────┴───────────────────────────┘
Blockers:
⛔ SQL injection vulnerability at auth.ts:45
⛔ Hardcoded credentials in config.ts:12
⛔ Missing input validation at user.ts:80
Required Changes:
1. Use parameterized queries for SQL
2. Move credentials to environment variables
3. Add input validation middleware
Recommendation: Do not merge until blockers resolved
调优建议
-
自定义规则:配置项目特定的审查规则
-
审查历史:跟踪审查结果趋势
-
集成 PR:自动评论到 PR
9.10 质量报告整合
综合质量报告
interface QualityReport {
build: BuildResult;
test: TestResult;
coverage: CoverageResult;
lint: LintResult;
security: SecurityResult;
e2e: E2EResult;
acceptance: AcceptanceResult;
aiReview: AIReviewResult;
overallStatus: 'pass' | 'fail';
qualityScore: number; // 0-100
passedGates: string[];
failedGates: string[];
summary: string;
}
完整报告示例
╔══════════════════════════════════════════════════════════════╗
║ OpenMatrix Quality Report ║
║ Task: TASK-001 - User Authentication ║
╠══════════════════════════════════════════════════════════════╣
║ Configuration ║
║ Quality Level: strict ║
║ Threshold: 80% ║
╠══════════════════════════════════════════════════════════════╣
║ Gate Results ║
╠══════════════════════════════════════════════════════════════╣
║ ✓ Build │ PASS │ 12.5s │ 0 errors, 0 warnings ║
║ ✓ Test │ PASS │ 3.5s │ 156 passed ║
║ ✓ Coverage │ PASS │ - │ 85.2% (threshold: 80%) ║
║ ✓ Lint │ PASS │ 2.1s │ 0 errors, 3 warnings ║
║ ✓ Security │ PASS │ 1.2s │ 0 vulnerabilities ║
║ ○ E2E │ SKIP │ - │ Not configured ║
║ ✓ Acceptance │ PASS │ - │ 12/12 criteria met ║
║ ✓ AI Review │ PASS │ 5.2s │ Score: 8/10 ║
╠══════════════════════════════════════════════════════════════╣
║ Summary ║
║ Overall Status: ✓ PASS ║
║ Quality Score: 87/100 ║
║ Passed Gates: 7/7 ║
║ Duration: 24.5s ║
╠══════════════════════════════════════════════════════════════╣
║ Recommendations ║
║ → Add JSDoc for public methods ║
║ → Consider E2E tests for critical flows ║
║ → Monitor coverage trend ║
╚══════════════════════════════════════════════════════════════╝
下一章将详细讲解 工作流程 的完整执行过程。