A characterization test is a snapshot of actual behavior
Lightweight characterization is a small test that records what code does now in a specific scenario before refactoring. It protects a narrow area from accidental change, but does not claim that the current behavior is business-correct.
This test complements unit, integration, and regression tests; it does not replace them.
| When it fits | Why |
|---|---|
| One method or local flow | The area is easy to bound |
| A full integration test is too broad | A cheap safety net is needed |
| There are one or two key scenarios | It is enough to capture the main results |
| Existing coverage is limited | A baseline is needed before a structural change |
Test observable behavior
- response status;
- error code or reason;
- message;
- external side effect;
- another part of the public result.
Example for finalizeOrder
The test calls public finalizeOrder and checks the result. If a helper is renamed, combined, or removed during refactoring, the assertions should remain valid.
| Scenario | Expected current result |
|---|---|
| Payment succeeds, item is in stock | Status FINALIZED and the corresponding message |
| Payment succeeds, stock is zero | Status REJECTED and reason OUT_OF_STOCK |
Target: finalizeOrder
Scenarios: one successful and one boundary case
Add only 1-2 behavior tests.
Do not change production code.
Capture current behavior; do not call it business-correct.A lightweight characterization cycle
- Describe in words the behavior to protect.
- Add one or two narrow tests.
- Run them against the current implementation.
- Make one small structural change.
- Run characterization and the main harness.
- Check the diff and only then create a commit.
When characterization is insufficient
- a large module with many integrations;
- queues, a database, and numerous side effects;
- a change spanning several packages;
- an updated external contract;
- business rules changing at the same time.
Canonical lesson source · JavaRush
Open JavaRush material