coverage-strategist
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCoverage Strategist
测试覆盖策略制定指南
Define pragmatic, ROI-focused test coverage strategies.
定义务实、以ROI为核心的测试覆盖策略。
Coverage Philosophy
覆盖策略理念
Goal: Maximum confidence with minimum tests
Principle: 100% coverage is not the goal. Test what matters.
目标:用最少的测试实现最高的信心
原则:100%覆盖并非目标,只测试关键内容。
Critical Path Identification
关键路径识别
typescript
// Critical paths that MUST be tested
const criticalPaths = {
authentication: {
priority: "P0",
coverage: "100%",
paths: [
"User login flow",
"User registration",
"Password reset",
"Token refresh",
"Session management",
],
reasoning: "Security critical, impacts all users",
},
checkout: {
priority: "P0",
coverage: "100%",
paths: [
"Add to cart",
"Update cart",
"Apply coupon",
"Process payment",
"Order confirmation",
],
reasoning: "Revenue critical, business essential",
},
dataIntegrity: {
priority: "P0",
coverage: "100%",
paths: [
"User data CRUD",
"Order creation",
"Inventory updates",
"Database transactions",
],
reasoning: "Data corruption would be catastrophic",
},
};
// Important but not critical
const importantPaths = {
userProfile: {
priority: "P1",
coverage: "80%",
paths: ["Profile updates", "Avatar upload", "Preferences"],
reasoning: "Important UX, but not business critical",
},
search: {
priority: "P1",
coverage: "70%",
paths: ["Product search", "Filters", "Sorting"],
reasoning: "Enhances experience, not essential",
},
};typescript
// Critical paths that MUST be tested
const criticalPaths = {
authentication: {
priority: "P0",
coverage: "100%",
paths: [
"User login flow",
"User registration",
"Password reset",
"Token refresh",
"Session management",
],
reasoning: "Security critical, impacts all users",
},
checkout: {
priority: "P0",
coverage: "100%",
paths: [
"Add to cart",
"Update cart",
"Apply coupon",
"Process payment",
"Order confirmation",
],
reasoning: "Revenue critical, business essential",
},
dataIntegrity: {
priority: "P0",
coverage: "100%",
paths: [
"User data CRUD",
"Order creation",
"Inventory updates",
"Database transactions",
],
reasoning: "Data corruption would be catastrophic",
},
};
// Important but not critical
const importantPaths = {
userProfile: {
priority: "P1",
coverage: "80%",
paths: ["Profile updates", "Avatar upload", "Preferences"],
reasoning: "Important UX, but not business critical",
},
search: {
priority: "P1",
coverage: "70%",
paths: ["Product search", "Filters", "Sorting"],
reasoning: "Enhances experience, not essential",
},
};Layer-Specific Targets
分层覆盖目标
markdown
undefinedmarkdown
undefinedCoverage Targets by Layer
Coverage Targets by Layer
Business Logic / Core Functions: 90-100%
业务逻辑/核心功能:90-100%
Why: High ROI - complex logic, many edge cases
What to test:
- Calculations
- Validations
- State machines
- Algorithms
- Data transformations
原因:投资回报率高——逻辑复杂,存在大量边缘场景
测试内容:
- 计算
- 验证
- 状态机
- 算法
- 数据转换
API Endpoints: 80-90%
API接口:80-90%
Why: Critical integration points
What to test:
- Happy paths
- Error cases
- Validation
- Authentication
- Authorization
原因:关键集成点
测试内容:
- 正常流程
- 异常场景
- 验证逻辑
- 身份认证
- 权限控制
Database Layer: 70-80%
数据库层:70-80%
Why: Data integrity matters
What to test:
- CRUD operations
- Transactions
- Constraints
- Migrations
原因:数据完整性至关重要
测试内容:
- CRUD操作
- 事务处理
- 约束规则
- 数据迁移
UI Components: 50-70%
UI组件:50-70%
Why: Lower ROI - visual changes, less critical
What to test:
- User interactions
- State changes
- Error states
- Critical flows only
原因:投资回报率较低——视觉变化频繁,非核心功能
测试内容:
- 用户交互
- 状态变更
- 错误状态
- 仅关键流程
Utils/Helpers: 80-90%
工具/辅助函数:80-90%
Why: Reused everywhere, high impact
What to test:
- All public functions
- Edge cases
- Error handling
undefined原因:全局复用,影响范围广
测试内容:
- 所有公共函数
- 边缘场景
- 错误处理
undefined"Don't Test This" List
“无需测试内容”清单
typescript
// Explicit list of what NOT to test
const dontTestThese = {
externalLibraries: {
examples: ["React internals", "Next.js router", "Lodash functions"],
reasoning: "Already tested by library authors",
},
trivialCode: {
examples: [
"Simple getters/setters",
"Constants",
"Type definitions",
"Pass-through functions",
],
reasoning: "No logic to test, waste of time",
},
presentationalComponents: {
examples: ["Simple buttons", "Icons", "Layout wrappers"],
reasoning: "Visual regression testing more appropriate",
},
configurationFiles: {
examples: ["webpack.config.js", "next.config.js"],
reasoning: "Configuration, not logic",
},
mockData: {
examples: ["Fixtures", "Test data", "Storybook stories"],
reasoning: "Not production code",
},
};
// Example: Don't test trivial code
// ❌ Don't test this
class User {
constructor(private name: string) {}
getName() {
return this.name;
} // Trivial getter
}
// ✅ But DO test this
class User {
constructor(private name: string) {}
getDisplayName() {
// Business logic
return this.name
.split(" ")
.map((n) => n.charAt(0).toUpperCase() + n.slice(1))
.join(" ");
}
}typescript
// Explicit list of what NOT to test
const dontTestThese = {
externalLibraries: {
examples: ["React internals", "Next.js router", "Lodash functions"],
reasoning: "Already tested by library authors",
},
trivialCode: {
examples: [
"Simple getters/setters",
"Constants",
"Type definitions",
"Pass-through functions",
],
reasoning: "No logic to test, waste of time",
},
presentationalComponents: {
examples: ["Simple buttons", "Icons", "Layout wrappers"],
reasoning: "Visual regression testing more appropriate",
},
configurationFiles: {
examples: ["webpack.config.js", "next.config.js"],
reasoning: "Configuration, not logic",
},
mockData: {
examples: ["Fixtures", "Test data", "Storybook stories"],
reasoning: "Not production code",
},
};
// Example: Don't test trivial code
// ❌ Don't test this
class User {
constructor(private name: string) {}
getName() {
return this.name;
} // Trivial getter
}
// ✅ But DO test this
class User {
constructor(private name: string) {}
getDisplayName() {
// Business logic
return this.name
.split(" ")
.map((n) => n.charAt(0).toUpperCase() + n.slice(1))
.join(" ");
}
}Test Priority Matrix
测试优先级矩阵
typescript
interface TestPriority {
feature: string;
businessImpact: "high" | "medium" | "low";
complexity: "high" | "medium" | "low";
changeFrequency: "high" | "medium" | "low";
priority: "P0" | "P1" | "P2" | "P3";
targetCoverage: string;
}
const testPriorities: TestPriority[] = [
{
feature: "Payment processing",
businessImpact: "high",
complexity: "high",
changeFrequency: "low",
priority: "P0",
targetCoverage: "100%",
},
{
feature: "User authentication",
businessImpact: "high",
complexity: "medium",
changeFrequency: "low",
priority: "P0",
targetCoverage: "100%",
},
{
feature: "Product search",
businessImpact: "medium",
complexity: "medium",
changeFrequency: "medium",
priority: "P1",
targetCoverage: "80%",
},
{
feature: "UI themes",
businessImpact: "low",
complexity: "low",
changeFrequency: "high",
priority: "P3",
targetCoverage: "30%",
},
];
// Priority calculation
function calculatePriority(
businessImpact: number, // 1-10
complexity: number, // 1-10
changeFrequency: number // 1-10
): number {
return businessImpact * 0.5 + complexity * 0.3 + changeFrequency * 0.2;
}typescript
interface TestPriority {
feature: string;
businessImpact: "high" | "medium" | "low";
complexity: "high" | "medium" | "low";
changeFrequency: "high" | "medium" | "low";
priority: "P0" | "P1" | "P2" | "P3";
targetCoverage: string;
}
const testPriorities: TestPriority[] = [
{
feature: "Payment processing",
businessImpact: "high",
complexity: "high",
changeFrequency: "low",
priority: "P0",
targetCoverage: "100%",
},
{
feature: "User authentication",
businessImpact: "high",
complexity: "medium",
changeFrequency: "low",
priority: "P0",
targetCoverage: "100%",
},
{
feature: "Product search",
businessImpact: "medium",
complexity: "medium",
changeFrequency: "medium",
priority: "P1",
targetCoverage: "80%",
},
{
feature: "UI themes",
businessImpact: "low",
complexity: "low",
changeFrequency: "high",
priority: "P3",
targetCoverage: "30%",
},
];
// Priority calculation
function calculatePriority(
businessImpact: number, // 1-10
complexity: number, // 1-10
changeFrequency: number // 1-10
): number {
return businessImpact * 0.5 + complexity * 0.3 + changeFrequency * 0.2;
}Coverage Configuration
覆盖配置
javascript
// jest.config.js
module.exports = {
collectCoverageFrom: [
"src/**/*.{ts,tsx}",
"!src/**/*.d.ts",
"!src/**/*.stories.tsx", // Don't count stories
"!src/mocks/**", // Don't count mocks
"!src/**/__tests__/**", // Don't count tests
],
coverageThresholds: {
global: {
statements: 70,
branches: 65,
functions: 70,
lines: 70,
},
// Critical paths: 90%+
"./src/services/payment/**/*.ts": {
statements: 90,
branches: 85,
functions: 90,
lines: 90,
},
"./src/services/auth/**/*.ts": {
statements: 90,
branches: 85,
functions: 90,
lines: 90,
},
// Utils: 80%+
"./src/utils/**/*.ts": {
statements: 80,
branches: 75,
functions: 80,
lines: 80,
},
// UI components: 50%+ (lower bar)
"./src/components/**/*.tsx": {
statements: 50,
branches: 45,
functions: 50,
lines: 50,
},
},
};javascript
// jest.config.js
module.exports = {
collectCoverageFrom: [
"src/**/*.{ts,tsx}",
"!src/**/*.d.ts",
"!src/**/*.stories.tsx", // Don't count stories
"!src/mocks/**", // Don't count mocks
"!src/**/__tests__/**", // Don't count tests
],
coverageThresholds: {
global: {
statements: 70,
branches: 65,
functions: 70,
lines: 70,
},
// Critical paths: 90%+
"./src/services/payment/**/*.ts": {
statements: 90,
branches: 85,
functions: 90,
lines: 90,
},
"./src/services/auth/**/*.ts": {
statements: 90,
branches: 85,
functions: 90,
lines: 90,
},
// Utils: 80%+
"./src/utils/**/*.ts": {
statements: 80,
branches: 75,
functions: 80,
lines: 80,
},
// UI components: 50%+ (lower bar)
"./src/components/**/*.tsx": {
statements: 50,
branches: 45,
functions: 50,
lines: 50,
},
},
};Test Investment ROI
测试投资ROI分析
typescript
// Calculate ROI of testing
interface TestROI {
feature: string;
testingCost: number; // hours
bugPreventionValue: number; // estimated $ saved
roi: number; // ratio
}
const testROI: TestROI[] = [
{
feature: "Payment processing",
testingCost: 40, // hours
bugPreventionValue: 50000, // Could lose $50k revenue
roi: 1250, // $1,250 per hour invested
},
{
feature: "Authentication",
testingCost: 20,
bugPreventionValue: 10000, // Security breach cost
roi: 500,
},
{
feature: "Theme switcher",
testingCost: 5,
bugPreventionValue: 100, // Minor UX issue
roi: 20,
},
];
// Focus on high ROI tests
const sortedByROI = testROI.sort((a, b) => b.roi - a.roi);typescript
// Calculate ROI of testing
interface TestROI {
feature: string;
testingCost: number; // hours
bugPreventionValue: number; // estimated $ saved
roi: number; // ratio
}
const testROI: TestROI[] = [
{
feature: "Payment processing",
testingCost: 40, // hours
bugPreventionValue: 50000, // Could lose $50k revenue
roi: 1250, // $1,250 per hour invested
},
{
feature: "Authentication",
testingCost: 20,
bugPreventionValue: 10000, // Security breach cost
roi: 500,
},
{
feature: "Theme switcher",
testingCost: 5,
bugPreventionValue: 100, // Minor UX issue
roi: 20,
},
];
// Focus on high ROI tests
const sortedByROI = testROI.sort((a, b) => b.roi - a.roi);Pragmatic Testing Strategy
务实的测试策略
markdown
undefinedmarkdown
undefinedTesting Strategy Document
测试策略文档
Principles
原则
- Business value first: Test what breaks the business
- Edge cases over happy path: Happy path is obvious
- Integration over unit: Test how pieces work together
- Critical flows end-to-end: User journeys matter most
- 业务价值优先:测试可能影响业务运转的内容
- 边缘场景优先于正常流程:正常流程逻辑明确
- 集成测试优先于单元测试:测试组件间协作逻辑
- 关键流程端到端测试:用户全流程体验至关重要
Test Types Distribution
测试类型分配
- 70% Unit tests (fast, isolated)
- 20% Integration tests (API + DB)
- 10% E2E tests (critical flows only)
- 70% 单元测试(快速、独立)
- 20% 集成测试(API+数据库)
- 10% 端到端测试(仅关键流程)
Coverage Goals
覆盖目标
- Overall: 70% (pragmatic goal)
- Critical business logic: 90%+
- API endpoints: 80%+
- UI components: 50%+ (user interactions only)
- 整体:70%(务实目标)
- 核心业务逻辑:90%+
- API接口:80%+
- UI组件:50%+(仅用户交互)
What NOT to Test
无需测试内容
- Third-party libraries
- Trivial getters/setters
- Pure presentational components
- Configuration files
- Mock data and fixtures
- 第三方库
- 简单的getter/setter
- 纯展示型组件
- 配置文件
- 模拟数据和测试用例
Review Criteria
评审标准
Before writing a test, ask:
- What bug would this test prevent?
- How likely is that bug?
- How costly would that bug be?
- Is this already covered by integration tests?
If ROI is low, skip the test.
undefined编写测试前,先思考:
- 该测试能预防什么bug?
- 该bug出现的概率有多大?
- 该bug造成的损失有多严重?
- 集成测试是否已覆盖该场景?
如果投资回报率低,跳过该测试。
undefinedTeam Guidelines
团队指南
typescript
// Code review checklist for test coverage
const reviewChecklist = {
criticalPath: {
question: "Does this change affect a critical path?",
ifYes: "MUST have comprehensive tests (90%+)",
},
businessLogic: {
question: "Is this complex business logic?",
ifYes: "MUST have unit tests with edge cases",
},
apiEndpoint: {
question: "Is this a new API endpoint?",
ifYes: "MUST have integration tests",
},
uiComponent: {
question: "Is this a UI component?",
ifYes: "Optional - test interactions only",
},
bugFix: {
question: "Is this a bug fix?",
ifYes: "MUST have regression test",
},
};typescript
// Code review checklist for test coverage
const reviewChecklist = {
criticalPath: {
question: "Does this change affect a critical path?",
ifYes: "MUST have comprehensive tests (90%+)",
},
businessLogic: {
question: "Is this complex business logic?",
ifYes: "MUST have unit tests with edge cases",
},
apiEndpoint: {
question: "Is this a new API endpoint?",
ifYes: "MUST have integration tests",
},
uiComponent: {
question: "Is this a UI component?",
ifYes: "Optional - test interactions only",
},
bugFix: {
question: "Is this a bug fix?",
ifYes: "MUST have regression test",
},
};Best Practices
最佳实践
- Focus on risk: Test what could go wrong
- Diminishing returns: 100% coverage has low ROI
- Integration over unit: Test behavior, not implementation
- Critical paths first: Payment, auth, data integrity
- Explicit "don't test": Be intentional about skipping
- Review regularly: Adjust targets quarterly
- Measure bugs: Track if tests catch real issues
- 聚焦风险:测试可能出错的内容
- 收益递减:100%覆盖投资回报率极低
- 集成优先于单元:测试行为而非实现细节
- 关键路径优先:支付、认证、数据完整性
- 明确“无需测试”范围:有意跳过非必要测试
- 定期评审:每季度调整覆盖目标
- 跟踪bug:统计测试是否捕获实际问题
Output Checklist
输出检查清单
- Critical paths identified
- Layer-specific targets defined
- "Don't test this" list created
- Priority matrix established
- Coverage thresholds configured
- ROI analysis performed
- Testing strategy documented
- Team guidelines defined
- 已识别关键路径
- 已定义分层覆盖目标
- 已创建“无需测试内容”清单
- 已建立优先级矩阵
- 已配置覆盖阈值
- 已完成ROI分析
- 已文档化测试策略
- 已定义团队指南