testing-patterns
npx machina-cli add skill aiskillstore/marketplace/testing-patterns --openclawFiles (1)
SKILL.md
4.1 KB
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)
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
Source
git clone https://github.com/aiskillstore/marketplace/blob/main/skills/0xdarkmatter/testing-patterns/SKILL.mdView on GitHub Overview
Universal testing patterns that apply across languages, from unit to E2E. It emphasizes the Test Pyramid, clear naming conventions, AAA test structure, test doubles, and isolation to boost reliability and speed.
How This Skill Works
Teams categorize tests by scope (unit, integration, E2E), follow Arrange-Act-Assert, and pick appropriate test doubles. They apply language-agnostic rules for isolation of databases and external services, and use a test quality checklist to keep tests fast, deterministic, and meaningful.
When to Use It
- When building fast, reliable unit tests with mocked dependencies
- When validating service interactions and data flow with integration tests
- When validating complete user journeys in staging or production-like environments with E2E tests
- When adopting TDD or BDD practices to guide design and delivery
- When enforcing test isolation and coverage guarantees across teams
Quick Start
- Step 1: Map tests into unit, integration, and E2E categories per the Test Pyramid
- Step 2: Write tests using Arrange-Act-Assert and select appropriate test doubles
- Step 3: Apply database and external service isolation; iterate with fast feedback
Best Practices
- Define a clear test pyramid with a large base of unit tests, fewer integration tests, and even fewer E2E tests
- Use Arrange-Act-Assert to structure tests and keep them readable
- Choose test doubles intentionally (stub, mock, spy, fake, dummy) for each scenario
- Isolate external dependencies with mocks, fake servers, or contract testing
- Cover business logic, input validation, error handling, and edge cases; test should be fast, independent, and deterministic
Example Use Cases
- 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
- mock.send_email.assert_called_once() in a service interaction test
- Using transaction rollback for database isolation in unit/integration tests
Frequently Asked Questions
Add this skill to your agents