A high-level test checks whether important behavior works across a broader slice of a system. It uses more real dependencies than lower-level tests, so a passing result provides stronger confidence in overall correctness—but usually runs more slowly and can be flakier. section 10.1
Test level is not simply the abstraction level of the code under test. A form test that includes a button can still be a unit or component test when everything stays in memory and under test control; dependencies, rather than the size of the object graph, determine that category. section 10.1.2
Use high-level tests deliberately rather than as the whole suite:
- Cover the few scenarios that need broad-system confidence; prefer lower-level tests when they can provide sufficient confidence faster. section 10.3.3
- Avoid repeating the same successful scenario across levels. For example, an end-to-end successful-login check can leave provider variations and failed logins to lower-level tests. section 10.3.3
- Keep high-level tests connected to lower-level tests and shared ownership. Separate groups and pipelines can create duplicate coverage, long runs, flakiness, and ignored failures. section 10.2.3
- Do not rely only on either extreme: low-level-only suites lack whole-system confidence, while end-to-end-only suites accumulate maintenance cost for limited additional value. section 10.2.2 section 10.5
Choosing a login scenario
Put “a user can successfully log in” at a high level when that broad path is needed for confidence. Check unsuccessful results and different providers lower down, unless those cases also require end-to-end confidence. The goal is a set of scenarios whose passing results make the feature feel trustworthy without unnecessary speed or maintenance costs. section 10.3.3
Compare common software test levels and the confidence-versus-dependency trade-off. section 10.1
