docs
This commit is contained in:
@@ -1,82 +1,142 @@
|
||||
# Testing layers between unit and integration
|
||||
# Test layers and where they belong
|
||||
|
||||
This section explains **where each test type belongs conceptually**,
|
||||
based on the rule:
|
||||
|
||||
> Tests should live as close as possible to the code they verify.
|
||||
> Only boundary- and system-level tests belong to a global test area.
|
||||
|
||||
---
|
||||
|
||||
## Unit tests
|
||||
Test a single function or class in isolation.
|
||||
|
||||
- No real dependencies
|
||||
- Everything external is mocked or stubbed
|
||||
- Very fast, very granular
|
||||
- Good for pure logic
|
||||
Unit tests belong **directly to the implementation they verify**.
|
||||
|
||||
**Goal:** Verify correctness of small, isolated units
|
||||
They protect:
|
||||
- pure logic
|
||||
- local decisions
|
||||
- small transformations
|
||||
|
||||
They are part of the code, not a separate concern.
|
||||
|
||||
---
|
||||
|
||||
## Sociable unit tests
|
||||
Units are tested together with their close collaborators.
|
||||
|
||||
- Multiple classes/functions work together
|
||||
- Only external side effects are mocked (DB, network, filesystem)
|
||||
- Internal collaborators are real
|
||||
- Still fast, but more meaningful than isolated units
|
||||
Sociable unit tests belong **to small clusters of collaborating units**.
|
||||
|
||||
**Goal:** Verify local collaboration without infrastructure
|
||||
They protect:
|
||||
- collaboration
|
||||
- shared assumptions
|
||||
- local workflows
|
||||
|
||||
They stay local but are not file-bound.
|
||||
|
||||
---
|
||||
|
||||
## Component / Module tests
|
||||
Test a coherent group of units as one component.
|
||||
|
||||
- Entire module is tested as a black box
|
||||
- Internal structure is irrelevant
|
||||
- Boundaries are mocked, internals are real
|
||||
- No real infrastructure
|
||||
Module tests belong **to a module as a whole**.
|
||||
|
||||
**Goal:** Verify that a module behaves correctly as a whole
|
||||
They verify:
|
||||
- composition
|
||||
- wiring
|
||||
- feature-level invariants
|
||||
- internal boundaries
|
||||
|
||||
They run without infrastructure and do not care about internal structure.
|
||||
|
||||
They protect **correctness of composition**.
|
||||
|
||||
---
|
||||
|
||||
## Service / Slice tests
|
||||
Test a full use case or service flow.
|
||||
|
||||
- Domain + application logic is real
|
||||
- Adapters are mocked or faked
|
||||
- Represents a real business action
|
||||
- Often maps to one command/query
|
||||
Service tests belong **to business use cases**.
|
||||
|
||||
**Goal:** Verify business behavior without infrastructure cost
|
||||
They verify:
|
||||
- orchestration
|
||||
- business decisions
|
||||
- multi-step workflows
|
||||
- cross-module logic (without infra)
|
||||
|
||||
They describe *what the system does*, not *how it is built*.
|
||||
|
||||
They protect **business correctness**.
|
||||
|
||||
---
|
||||
|
||||
## Feature flow tests (frontend integration)
|
||||
|
||||
Feature flow tests belong **to the frontend as a system**.
|
||||
|
||||
They verify:
|
||||
- routing
|
||||
- guards
|
||||
- navigation
|
||||
- cross-screen state
|
||||
- user flows (without real backend)
|
||||
|
||||
They run with:
|
||||
- real frontend
|
||||
- mocked contracts
|
||||
|
||||
They protect **frontend system correctness**.
|
||||
|
||||
---
|
||||
|
||||
## Contract tests
|
||||
Test the contract between two components or services.
|
||||
|
||||
- Focus on inputs/outputs and schemas
|
||||
- No real integration required
|
||||
- One side is mocked, contract is enforced
|
||||
- Prevents breaking changes
|
||||
Contract tests belong **at boundaries between systems**.
|
||||
|
||||
**Goal:** Verify that boundaries remain compatible
|
||||
They verify shared agreements:
|
||||
- schemas
|
||||
- semantics
|
||||
- error shapes
|
||||
- guarantees
|
||||
|
||||
Each side tests the same contract.
|
||||
|
||||
They protect **compatibility and independent deployability**.
|
||||
|
||||
---
|
||||
|
||||
## Integration tests
|
||||
Test real integration with infrastructure.
|
||||
|
||||
- Real database, filesystem, network, etc.
|
||||
- Slower and more expensive
|
||||
- Fewer tests, higher confidence
|
||||
Integration tests belong **to the system level**.
|
||||
|
||||
**Goal:** Verify that the system works with real dependencies
|
||||
They verify real infrastructure:
|
||||
- DB
|
||||
- queues
|
||||
- storage
|
||||
- auth
|
||||
- external APIs
|
||||
|
||||
They protect **environmental correctness**.
|
||||
|
||||
---
|
||||
|
||||
## End-to-end (E2E) tests
|
||||
Test the system exactly like a user would.
|
||||
|
||||
- Everything is real
|
||||
- UI → backend → infrastructure
|
||||
- Slow and fragile
|
||||
- Very few tests should exist
|
||||
E2E tests belong **at the highest level**.
|
||||
|
||||
**Goal:** Verify critical user flows
|
||||
They verify:
|
||||
- critical user journeys
|
||||
- real deployment
|
||||
- full wiring
|
||||
|
||||
They are few, slow, and intentional.
|
||||
|
||||
They protect **real-world safety**.
|
||||
|
||||
---
|
||||
|
||||
## Summary principle
|
||||
|
||||
- **Local tests**: unit, sociable, module
|
||||
- **Business tests**: service, feature flow
|
||||
- **Boundary tests**: contract
|
||||
- **System tests**: integration, E2E
|
||||
|
||||
The closer a test is to the code, the more of them you should have.
|
||||
The further away, the fewer — but more meaningful — they become.
|
||||
Reference in New Issue
Block a user