Test Strategy Selection
Test Types
| Type |
What It Tests |
Speed |
Confidence |
Cost |
| Static analysis |
Types, lint, dead code |
⚡ Instant |
Low |
$0 |
| Unit |
Single function/class in isolation |
⚡ ms |
Low–Medium |
$ |
| Integration |
Multiple components working together |
🐢 seconds |
High |
$$ |
| Contract |
Service boundary compatibility |
🐢 seconds |
Medium–High |
$$ |
| End-to-end |
Full user flow through the system |
🐌 minutes |
Highest |
$$$$ |
The Push-Down Principle
Write tests at the lowest level that gives you the confidence you need.
Is a unit test enough?
YES → Write unit test
NO → Is an integration test enough?
YES → Write integration test
NO → Write E2E test
Unnecessary elevation adds cost and fragility without adding confidence.
Decision Framework: Which Test Type When?
| Question |
Test Type |
| "Does this function do what I expect?" |
Unit |
| "Do these components work together?" |
Integration |
| "Is my API contract still compatible?" |
Contract |
| "Can a user actually do this thing?" |
E2E |
| "Is my code well-typed and lint-free?" |
Static |
| "Is this performance-sensitive path fast enough?" |
Benchmark |
| "Is the migration reversible?" |
Integration |
Risk-Based Framework
Step 1: Rate the Risk
| Dimension |
1 (Low) |
2 (Medium) |
3 (High) |
4 (Critical) |
| Business Impact |
Cosmetic, rarely used |
Minor feature |
Core feature, revenue-impacting |
Safety-critical, financial, PII |
| Failure Probability |
Stable, tested |
Occasional changes |
High churn, complex logic |
New code, external deps, concurrency |
Step 2: Score = Business Impact × Failure Probability
| Score |
Testing Requirement |
| 1-4 |
Minimal — smoke tests, unit only |
| 5-6 |
Standard — unit + integration |
| 7-9 |
Thorough — unit + integration + contract |
| 10-16 |
Extensive — unit + integration + contract + E2E |
Step 3: Allocate Effort
| Category |
Budget |
Examples |
| 🔴 Critical (10-16) |
40% |
Payment, auth, data integrity |
| 🟠 High (7-9) |
30% |
Search, user management |
| 🟡 Medium (5-6) |
20% |
Profiles, notifications |
| 🟢 Low (1-4) |
10% |
Admin panels, logging |
Cost/Benefit Reference
| Dimension |
Unit |
Integration |
Contract |
E2E |
| Execution speed |
⚡ ms |
🐢 seconds |
🐢 seconds |
🐌 minutes |
| Write cost |
$ |
$$ |
$$ |
$$$$ |
| Maintenance cost |
$ |
$$ |
$ |
$$$$ |
| Debugging signal |
✅ Precise |
✅ Good |
✅ Good |
❌ Noisy |
| Flakiness |
🟢 Very low |
🟢 Low |
🟢 Very low |
🔴 High |
Test Shapes
| Shape |
Ratio |
Best For |
| Pyramid |
70% Unit / 20% Integration / 10% E2E |
Monoliths, logic-heavy apps |
| Trophy |
Static + Unit + fat Integration + thin E2E |
Component-driven frontends |
| Honeycomb |
Many Integration + Contract, few Unit + E2E |
Microservices |
The shape debate is mostly semantic. What matters: tests are fast, reliable, and catch meaningful failures.
Strategy by Codebase Context
Greenfield: Start with pyramid (70/20/10). Invest in test infrastructure early — Testcontainers, CI pipeline, sharding.
Legacy (untested): Write a test before every bug fix; write a test before every refactor; start with integration tests — they give more value when boundaries are unclear.
Monolith: Classic pyramid. Resist the temptation to write E2E tests because they're "easy."
Microservices: Contract testing is the linchpin. Unit + Contract dominate; minimize E2E.
CI/CD Integration
| Trigger |
Tests to Run |
| Every commit (branch) |
Lint, unit, type check |
| Pull request open/update |
+ Integration, impact-analyzed regression |
| Merge to main |
+ Contract, component tests |
| Deploy to staging |
+ E2E (critical paths) |
| Deploy to production |
+ Smoke tests |
Hard gates (pipeline fails): test failures, critical security vulns, build errors.
Soft gates (warning only): coverage drops, medium-severity findings.
Coverage Targets
Use as signals, not goals:
| Code Type |
Target |
Test Level |
| Business logic |
90%+ branch |
Unit |
| API handlers |
80%+ line |
Unit + Integration |
| Utility/pure functions |
95%+ |
Unit |
| Critical UI components |
60%+ |
Integration |
Speed budgets:
- Unit: < 30s total, < 10ms per test
- Integration: < 3min total, 50-500ms per test
- E2E: < 10min total, 2-30s per test
Core Rules
- Push down — write at the lowest level that gives confidence
- Don't write E2E tests for things unit tests can cover
- Mock external deps in unit tests; use real ones in integration tests
- Contract tests over E2E for service boundaries — cheaper, faster, less flaky
- Coverage is a signal, not a goal — 100% with no assertions is worthless
1---2name: test-strategy-selection3description: Skill for the tester agent. Choose the right type of tests — unit, integration, contract, e2e, static — based on risk, context, and ROI. Load BEFORE planning any test approach.4---56# Test Strategy Selection78## Test Types910| Type | What It Tests | Speed | Confidence | Cost |11|------|--------------|-------|-----------|------|12| **Static analysis** | Types, lint, dead code | ⚡ Instant | Low | $0 |13| **Unit** | Single function/class in isolation | ⚡ ms | Low–Medium | $ |14| **Integration** | Multiple components working together | 🐢 seconds | High | $$ |15| **Contract** | Service boundary compatibility | 🐢 seconds | Medium–High | $$ |16| **End-to-end** | Full user flow through the system | 🐌 minutes | Highest | $$$$ |1718---1920## The Push-Down Principle2122> Write tests at the **lowest level** that gives you the confidence you need.2324```25Is a unit test enough?26 YES → Write unit test27 NO → Is an integration test enough?28 YES → Write integration test29 NO → Write E2E test30```3132Unnecessary elevation adds cost and fragility without adding confidence.3334---3536## Decision Framework: Which Test Type When?3738| Question | Test Type |39|----------|-----------|40| "Does this **function** do what I expect?" | Unit |41| "Do these **components work together**?" | Integration |42| "Is my **API contract** still compatible?" | Contract |43| "Can a **user actually do this thing**?" | E2E |44| "Is my code **well-typed** and lint-free?" | Static |45| "Is this **performance-sensitive** path fast enough?" | Benchmark |46| "Is the **migration reversible**?" | Integration |4748---4950## Risk-Based Framework5152### Step 1: Rate the Risk5354| Dimension | 1 (Low) | 2 (Medium) | 3 (High) | 4 (Critical) |55|-----------|---------|------------|----------|--------------| 56| **Business Impact** | Cosmetic, rarely used | Minor feature | Core feature, revenue-impacting | Safety-critical, financial, PII |57| **Failure Probability** | Stable, tested | Occasional changes | High churn, complex logic | New code, external deps, concurrency |5859### Step 2: Score = Business Impact × Failure Probability6061| Score | Testing Requirement |62|-------|---------------------|63| 1-4 | Minimal — smoke tests, unit only |64| 5-6 | Standard — unit + integration |65| 7-9 | Thorough — unit + integration + contract |66| 10-16 | Extensive — unit + integration + contract + E2E |6768### Step 3: Allocate Effort6970| Category | Budget | Examples |71|----------|--------|---------|72| 🔴 Critical (10-16) | 40% | Payment, auth, data integrity |73| 🟠 High (7-9) | 30% | Search, user management |74| 🟡 Medium (5-6) | 20% | Profiles, notifications |75| 🟢 Low (1-4) | 10% | Admin panels, logging |7677---7879## Cost/Benefit Reference8081| Dimension | Unit | Integration | Contract | E2E |82|-----------|------|-------------|----------|-----|83| Execution speed | ⚡ ms | 🐢 seconds | 🐢 seconds | 🐌 minutes |84| Write cost | $ | $$ | $$ | $$$$ |85| Maintenance cost | $ | $$ | $ | $$$$ |86| Debugging signal | ✅ Precise | ✅ Good | ✅ Good | ❌ Noisy |87| Flakiness | 🟢 Very low | 🟢 Low | 🟢 Very low | 🔴 High |8889---9091## Test Shapes9293| Shape | Ratio | Best For |94|-------|-------|----------|95| **Pyramid** | 70% Unit / 20% Integration / 10% E2E | Monoliths, logic-heavy apps |96| **Trophy** | Static + Unit + fat Integration + thin E2E | Component-driven frontends |97| **Honeycomb** | Many Integration + Contract, few Unit + E2E | Microservices |9899The shape debate is mostly semantic. What matters: tests are fast, reliable, and catch meaningful failures.100101---102103## Strategy by Codebase Context104105**Greenfield:** Start with pyramid (70/20/10). Invest in test infrastructure early — Testcontainers, CI pipeline, sharding.106107**Legacy (untested):** Write a test before every bug fix; write a test before every refactor; start with integration tests — they give more value when boundaries are unclear.108109**Monolith:** Classic pyramid. Resist the temptation to write E2E tests because they're "easy."110111**Microservices:** Contract testing is the linchpin. Unit + Contract dominate; minimize E2E.112113---114115## CI/CD Integration116117| Trigger | Tests to Run |118|---------|-------------|119| Every commit (branch) | Lint, unit, type check |120| Pull request open/update | + Integration, impact-analyzed regression |121| Merge to main | + Contract, component tests |122| Deploy to staging | + E2E (critical paths) |123| Deploy to production | + Smoke tests |124125**Hard gates** (pipeline fails): test failures, critical security vulns, build errors.126**Soft gates** (warning only): coverage drops, medium-severity findings.127128---129130## Coverage Targets131132Use as signals, not goals:133134| Code Type | Target | Test Level |135|-----------|--------|------------|136| Business logic | 90%+ branch | Unit |137| API handlers | 80%+ line | Unit + Integration |138| Utility/pure functions | 95%+ | Unit |139| Critical UI components | 60%+ | Integration |140141**Speed budgets:**142- Unit: < 30s total, < 10ms per test143- Integration: < 3min total, 50-500ms per test144- E2E: < 10min total, 2-30s per test145146---147148## Core Rules1491501. Push down — write at the lowest level that gives confidence1512. Don't write E2E tests for things unit tests can cover1523. Mock external deps in unit tests; use real ones in integration tests1534. Contract tests over E2E for service boundaries — cheaper, faster, less flaky1545. Coverage is a signal, not a goal — 100% with no assertions is worthless