QA Engineer Skills 2026QA-2026Testability and Test Curation

Testability and Test Curation

Systems thinkers influence quality before tests are written. They shape the architecture to be testable (so tests are easy to write and reliable to run) and they curate the existing test suite (so it stays sharp rather than growing into an unmaintainable mass). Both activities have more leverage than writing new tests.


Testability as a Design Principle

Anti-Pattern: The system is built first, then QA tries to test it. Testing is hard because services are tightly coupled, behavior is non-deterministic, and there is no way to observe internal state.

Pattern: Testability is a design requirement, considered during architecture reviews alongside performance, security, and scalability.

Three Pillars of Testability

Dependency injection — Services accept their dependencies as parameters rather than creating them internally. This allows tests to substitute real databases, APIs, and services with controlled test doubles. Without dependency injection, integration tests require the entire production stack.

Observability — The system exposes enough information for tests to verify behavior without reaching into internal state. Structured logging, event streams, and test hooks provide visibility into what the system did and why. If you cannot observe it, you cannot test it.

Determinism — Given the same inputs, the system produces the same outputs. Non-deterministic behavior (random values, wall-clock time, unordered collections) creates flaky tests. Design for determinism: inject clocks and random seeds, sort outputs when order does not matter, use stable identifiers.


Killing Bad Tests

Anti-Pattern: The test suite only grows. Nobody deletes tests because "what if we miss a bug?" The suite becomes slower, flakier, and harder to maintain. New tests are added; dead tests accumulate.

Pattern: Regular test suite curation. Tests have a cost (maintenance, execution time, cognitive load) and a value (bugs caught, confidence provided). Delete tests where the cost exceeds the value.

Categories of Tests to Delete

Category Description Example
Tautological Tests that cannot fail, or test the framework/language itself expect(true).toBe(true), mocking a function and asserting the mock was called
Duplicate coverage Multiple tests covering the same path with no additional value Three tests that all verify successful login with valid credentials
Implementation-detail Tests that break when code is refactored without changing behavior Asserting on internal method calls, private state, or CSS class names
Permanently skipped Tests marked @skip or @ignore for months with no plan to fix Any test that has been skipped for more than two sprints

Cost-Value Analysis

For each test (or test category), ask:

  • How often does it catch real bugs? (value)
  • How often does it fail due to flakiness or environment issues? (noise cost)
  • How long does it take to run? (time cost)
  • How much effort does it require to maintain? (maintenance cost)

If a test has not caught a real bug in six months, runs for 30 seconds, and breaks every other sprint due to environmental issues — delete it.


Key Takeaways

  • Testability is a design requirement, not an afterthought — advocate for dependency injection, observability, and determinism during architecture reviews
  • Tests have costs (maintenance, speed, cognitive load) and value (bugs caught, confidence) — curate accordingly
  • Delete tautological tests, duplicate coverage, implementation-detail tests, and permanently skipped tests
  • Regular test curation is higher-leverage than writing new tests in a mature suite
  • If a test has not caught a real bug in months and costs time to maintain, it is not providing value