---
name: testing-ops
description: "Cross-language testing strategies and patterns. Triggers on: test pyramid, unit test, integration test, e2e test, TDD, BDD, test coverage, mocking strategy, test doubles, test isolation."
license: MIT
compatibility: "Language-agnostic patterns. Framework-specific details in references."
allowed-tools: "Read Write Bash"
metadata:
  author: claude-mods
---

# Testing Patterns

Universal testing strategies and patterns applicable across languages.

## The Test Pyramid

```
        /\
       /  \     E2E Tests (few, slow, expensive)
      /    \    - Full system tests
     /------\   - Real browser/API calls
    /        \
   /  Integ   \ Integration Tests (some)
  /   Tests    \ - Service boundaries
 /--------------\ - Database, APIs
/                \
/   Unit Tests    \ Unit Tests (many, fast, cheap)
------------------  - Single function/class
                    - Mocked dependencies
```

## Test Types

### Unit Tests
```
Scope:      Single function/method/class
Speed:      Milliseconds
Dependencies: All mocked
When:       Every code change
Coverage:   80%+ of codebase
```

### Integration Tests
```
Scope:      Multiple components together
Speed:      Seconds
Dependencies: Real databases, mocked external APIs
When:       PR/merge, critical paths
Coverage:   Key integration points
```

### End-to-End Tests
```
Scope:      Full user journey
Speed:      Minutes
Dependencies: Real system (or staging)
When:       Pre-deploy, nightly
Coverage:   Critical user flows only
```

## Test Naming Convention

```
test_<unit>_<scenario>_<expected>

Examples:
- test_calculate_total_with_discount_returns_reduced_price
- test_user_login_with_invalid_password_returns_401
- test_order_submit_when_out_of_stock_raises_error
```

## Arrange-Act-Assert (AAA)

```python
def test_calculate_discount():
    # Arrange - Set up test data and dependencies
    cart = Cart()
    cart.add_item(Item(price=100))
    discount = Discount(percent=10)

    # Act - Execute the code under test
    total = cart.calculate_total(discount)

    # Assert - Verify the results
    assert total == 90
```

## Test Doubles

| Type | Purpose | Example |
|------|---------|---------|
| **Stub** | Returns canned data | `stub.get_user.returns(fake_user)` |
| **Mock** | Verifies interactions | `mock.send_email.assert_called_once()` |
| **Spy** | Records calls, uses real impl | `spy.on(service, 'save')` |
| **Fake** | Working simplified impl | `FakeDatabase()` instead of real DB |
| **Dummy** | Placeholder, never used | `null` object for required param |

## Test Isolation Strategies

### Database Isolation
```
Option 1: Transaction rollback (fast)
- Start transaction before test
- Rollback after test

Option 2: Truncate tables (medium)
- Clear all data between tests

Option 3: Separate database (slow)
- Each test gets fresh database
```

### External Service Isolation
```
Option 1: Mock at boundary
- Replace HTTP client with mock

Option 2: Fake server
- WireMock, MSW, VCR cassettes

Option 3: Contract testing
- Pact, consumer-driven contracts
```

## What to Test

### MUST Test
- Business logic and calculations
- Input validation and error handling
- Security-sensitive code (auth, permissions)
- Edge cases and boundary conditions

### SHOULD Test
- Integration points (DB, APIs)
- State transitions
- Configuration handling

### AVOID Testing
- Framework internals
- Third-party library behavior
- Simple getters/setters
- Private implementation details

## Test Quality Checklist

- [ ] Tests are independent (no order dependency)
- [ ] Tests are deterministic (no flaky tests)
- [ ] Tests are fast (unit < 100ms, integration < 5s)
- [ ] Tests have clear names describing behavior
- [ ] Tests cover happy path AND error cases
- [ ] Tests don't repeat production logic
- [ ] Mocks are minimal (only external boundaries)

## Additional Resources

- `./references/tdd-workflow.md` - Test-Driven Development cycle
- `./references/mocking-strategies.md` - When and how to mock
- `./references/test-data-patterns.md` - Fixtures, factories, builders
- `./references/ci-testing.md` - Testing in CI/CD pipelines

## Scripts

- `./scripts/coverage-check.sh` - Run coverage and fail if below threshold
