concept

Testability as a Design Property

How cheaply a system's behaviour can be observed and controlled, which is decided by architecture and largely fixed before any test is written.

A test strategy is bounded by what the architecture permits. Two properties decide it, and both are design decisions rather than testing decisions.

Controllability is the ability to put the system into a chosen state. A service that reads the wall clock directly cannot be tested at a month boundary without moving the machine's clock; one that takes a clock as a dependency can. A component that constructs its own collaborators cannot be given substitutes; one that receives them can. A workflow with no way to seed an in-progress state can only be tested from the beginning, which makes testing step nine expensive.

Observability is the ability to see what happened. Behaviour whose only effect is a row in a database three services away requires an end-to-end test to verify; the same behaviour that also emits a domain event can be verified where it occurs.

The reason to treat this as architecture is timing. Retrofitting testability into a system that has neither means changing dependency structure across a codebase, which is expensive and rarely funded — so the system stays hard to test, and the suite compensates by pushing everything to slow end-to-end tests. The cheap moment to decide is when the boundaries are drawn.