256 lines
7.8 KiB
Markdown
256 lines
7.8 KiB
Markdown
---
|
|
name: test-automation-architecture
|
|
description: Use when organizing test suites, setting up CI/CD testing pipelines, choosing test levels (unit vs integration vs E2E), fixing slow CI feedback, or migrating from inverted test pyramid - provides test pyramid guidance and anti-patterns
|
|
---
|
|
|
|
# Test Automation Architecture
|
|
|
|
## Overview
|
|
|
|
**Core principle:** Test pyramid - many fast unit tests, fewer integration tests, fewest E2E tests.
|
|
|
|
**Target distribution:** 70% unit, 20% integration, 10% E2E
|
|
|
|
**Flexibility:** Ratios can vary based on constraints (e.g., 80/15/5 if E2E infrastructure is expensive, 60/30/10 for microservices). Key is maintaining pyramid shape - more unit than integration than E2E.
|
|
|
|
**Starting from zero tests:** Don't try to reach target distribution immediately. Start with unit tests only (Phase 1), add integration (Phase 2), add E2E last (Phase 3). Distribute organically over 6-12 months.
|
|
|
|
## Test Pyramid Quick Reference
|
|
|
|
| Test Level | Purpose | Speed | When to Use |
|
|
|------------|---------|-------|-------------|
|
|
| **Unit** | Test individual functions/methods in isolation | Milliseconds | Business logic, utilities, calculations, error handling |
|
|
| **Integration** | Test components working together | Seconds | API contracts, database operations, service interactions |
|
|
| **E2E** | Test full user workflows through UI | Minutes | Critical user journeys, revenue flows, compliance paths |
|
|
|
|
**Rule:** If you can test it at a lower level, do that instead.
|
|
|
|
## Test Level Selection Guide
|
|
|
|
| What You're Testing | Test Level | Why |
|
|
|---------------------|-----------|-----|
|
|
| Function returns correct value | Unit | No external dependencies |
|
|
| API endpoint response format | Integration | Tests API contract, not full workflow |
|
|
| Database query performance | Integration | Tests DB interaction, not UI |
|
|
| User signup → payment flow | E2E | Crosses multiple systems, critical revenue |
|
|
| Form validation logic | Unit | Pure function, no UI needed |
|
|
| Service A calls Service B correctly | Integration | Tests contract, not user workflow |
|
|
| Button click updates state | Unit | Component behavior, no backend |
|
|
| Multi-step checkout process | E2E | Critical user journey, revenue impact |
|
|
|
|
**Guideline:** Unit tests verify "did I build it right?", E2E tests verify "did I build the right thing?"
|
|
|
|
## Anti-Patterns Catalog
|
|
|
|
### ❌ Inverted Pyramid
|
|
**Symptom:** 500 E2E tests, 100 unit tests
|
|
|
|
**Why bad:** Slow CI (30min+), brittle tests, hard to debug, expensive maintenance
|
|
|
|
**Fix:** Migrate 70% of E2E tests down to unit/integration. Use Migration Strategy below.
|
|
|
|
---
|
|
|
|
### ❌ All Tests on Every Commit
|
|
**Symptom:** Running full 30-minute test suite on every PR
|
|
|
|
**Why bad:** Slow feedback kills productivity, wastes CI resources
|
|
|
|
**Fix:** Progressive testing - unit tests on PR, integration on merge, E2E nightly/weekly
|
|
|
|
---
|
|
|
|
### ❌ No Test Categorization
|
|
**Symptom:** All tests in one folder, one command, one 30-minute run
|
|
|
|
**Why bad:** Can't run subsets, no fail-fast, poor organization
|
|
|
|
**Fix:** Separate by level (unit/, integration/, e2e/) with independent configs
|
|
|
|
---
|
|
|
|
### ❌ Slow CI Feedback Loop
|
|
**Symptom:** Waiting 20+ minutes for test results on every commit
|
|
|
|
**Why bad:** Context switching, delayed bug detection, reduced productivity
|
|
|
|
**Fix:** Fail fast - run fastest tests first, parallelize, cache dependencies
|
|
|
|
---
|
|
|
|
### ❌ No Fail Fast
|
|
**Symptom:** Running all 500 tests even after first test fails
|
|
|
|
**Why bad:** Wastes CI time, delays feedback
|
|
|
|
**Fix:** Configure test runner to stop on first failure in CI (not locally)
|
|
|
|
## CI/CD Pipeline Patterns
|
|
|
|
| Event | Run These Tests | Duration Target | Why |
|
|
|-------|----------------|-----------------|-----|
|
|
| **Every Commit (Pre-Push)** | Lint + unit tests | < 5 min | Fast local feedback |
|
|
| **Pull Request** | Lint + unit + integration | < 15 min | Gate before merge, balance speed/coverage |
|
|
| **Merge to Main** | All tests (unit + integration + E2E) | < 30 min | Full validation before deployment |
|
|
| **Nightly/Scheduled** | Full suite + performance tests | < 60 min | Catch regressions, performance drift |
|
|
| **Pre-Deployment** | Smoke tests only (5-10 critical E2E) | < 5 min | Fast production validation |
|
|
|
|
**Progressive complexity:** Start with just unit tests on PR, add integration after mastering that, add E2E last.
|
|
|
|
## Folder Structure Patterns
|
|
|
|
### Basic (Small Projects)
|
|
```
|
|
tests/
|
|
├── unit/
|
|
├── integration/
|
|
└── e2e/
|
|
```
|
|
|
|
### Mirrored (Medium Projects)
|
|
```
|
|
src/
|
|
├── components/
|
|
├── services/
|
|
└── utils/
|
|
tests/
|
|
├── unit/
|
|
│ ├── components/
|
|
│ ├── services/
|
|
│ └── utils/
|
|
├── integration/
|
|
└── e2e/
|
|
```
|
|
|
|
### Feature-Based (Large Projects)
|
|
```
|
|
features/
|
|
├── auth/
|
|
│ ├── src/
|
|
│ └── tests/
|
|
│ ├── unit/
|
|
│ ├── integration/
|
|
│ └── e2e/
|
|
└── payment/
|
|
├── src/
|
|
└── tests/
|
|
```
|
|
|
|
**Choose based on:** Team size (<5: Basic, 5-20: Mirrored, 20+: Feature-Based)
|
|
|
|
## Migration Strategy (Fixing Inverted Pyramid)
|
|
|
|
If you have 500 E2E tests and 100 unit tests:
|
|
|
|
**Week 1-2: Audit**
|
|
- [ ] Categorize each E2E test: Critical (keep) vs Redundant (migrate)
|
|
- [ ] Identify 10-20 critical user journeys
|
|
- [ ] Target: Keep 50-100 E2E tests maximum
|
|
|
|
**Week 3-4: Move High-Value Tests Down**
|
|
- [ ] Convert 200 E2E tests → integration tests (test API/services without UI)
|
|
- [ ] Convert 100 E2E tests → unit tests (pure logic tests)
|
|
- [ ] Delete 100 truly redundant E2E tests
|
|
|
|
**Week 5-6: Build Unit Test Coverage**
|
|
- [ ] Add 200-300 unit tests for untested business logic
|
|
- [ ] Target: 400+ unit tests total
|
|
|
|
**Week 7-8: Reorganize**
|
|
- [ ] Split tests into folders (unit/, integration/, e2e/)
|
|
- [ ] Create separate test configs
|
|
- [ ] Update CI to run progressively
|
|
|
|
**Expected result:** 400 unit, 200 integration, 100 E2E (~70/20/10 distribution)
|
|
|
|
## Your First CI Pipeline
|
|
|
|
**Start simple, add complexity progressively:**
|
|
|
|
**Phase 1 (Week 1):** Unit tests only
|
|
```yaml
|
|
on: [pull_request]
|
|
jobs:
|
|
test:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- run: npm run test:unit
|
|
```
|
|
|
|
**Phase 2 (Week 2-3):** Add lint + integration
|
|
```yaml
|
|
jobs:
|
|
lint:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- run: npm run lint
|
|
|
|
test:
|
|
needs: lint
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- run: npm run test:unit
|
|
- run: npm run test:integration
|
|
```
|
|
|
|
**Phase 3 (Week 4+):** Add E2E on main branch
|
|
```yaml
|
|
jobs:
|
|
e2e:
|
|
if: github.ref == 'refs/heads/main'
|
|
needs: [lint, test]
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- run: npm run test:e2e
|
|
```
|
|
|
|
**Don't start with full complexity** - master each phase before adding next.
|
|
|
|
## Common Mistakes
|
|
|
|
### ❌ Testing Everything at E2E Level
|
|
**Fix:** Use Test Level Selection Guide above. Most tests belong at unit level.
|
|
|
|
---
|
|
|
|
### ❌ No Parallel Execution
|
|
**Symptom:** Tests run sequentially, taking 30min when they could run in 10min
|
|
|
|
**Fix:** Run independent test suites in parallel (unit + lint simultaneously)
|
|
|
|
---
|
|
|
|
### ❌ No Caching
|
|
**Symptom:** Re-downloading dependencies on every CI run (5min wasted)
|
|
|
|
**Fix:** Cache node_modules, .m2, .gradle based on lock file hash
|
|
|
|
## Quick Reference
|
|
|
|
**Test Distribution Target:**
|
|
- 70% unit tests (fast, isolated)
|
|
- 20% integration tests (component interaction)
|
|
- 10% E2E tests (critical user journeys)
|
|
|
|
**CI Pipeline Events:**
|
|
- PR: unit + integration (< 15min)
|
|
- Main: all tests (< 30min)
|
|
- Deploy: smoke tests only (< 5min)
|
|
|
|
**Folder Organization:**
|
|
- Small team: tests/unit, tests/integration, tests/e2e
|
|
- Large team: feature-based with embedded test folders
|
|
|
|
**Migration Path:**
|
|
1. Audit E2E tests
|
|
2. Move 70% down to unit/integration
|
|
3. Add missing unit tests
|
|
4. Reorganize folders
|
|
5. Update CI pipeline
|
|
|
|
## Bottom Line
|
|
|
|
**Many fast tests beat few slow tests.**
|
|
|
|
Test pyramid exists because it balances confidence (E2E) with speed (unit). Organize tests by level, run progressively in CI, fail fast.
|