Engineering Practices
Testing Strategy
Testing strategy defines where confidence comes from before a change reaches production. Keep the test suite fast enough to run often and realistic enough to catch integration risk.
Test pyramid
Unit and component tests
Use unit tests for deterministic business logic, validation, rendering branches, and edge cases.
- Keep tests close to the code they protect.
- Prefer public behavior over private implementation details.
- Avoid snapshots unless they protect a stable contract.
- Make failures explain the broken behavior clearly.
Integration and contract tests
Use integration tests for boundaries between services, databases, queues, APIs, and third-party systems.
- Test database migrations against realistic schemas.
- Test API contracts between producers and consumers.
- Use contract tests for shared APIs and event schemas.
- Use containers or managed test environments when mocks hide risk.
E2E and smoke tests
Use a small number of end-to-end tests for critical user journeys and production smoke checks.
- Keep E2E tests focused on revenue, safety, or compliance-critical paths.
- Run smoke tests after deployment and during incident mitigation.
- Prefer stable selectors, roles, labels, and test IDs.
- Avoid brittle waits and framework internals.
Release gates
Every service should define minimum gates for merge and deployment. Common gates include:
- Linting, type checks, and formatting.
- Unit and integration tests.
- Security and dependency scans.
- Migration validation.
- Smoke tests or health checks after deployment.
Do not block every change on slow, flaky suites. Fix flakiness or move checks to the right stage.