TDD
Test-Driven Development
Write the test first. Watch it fail. Write the code that makes it pass. Refactor. Repeat.
Test-Driven Development is a discipline, not a methodology. The loop is: red (write a failing test), green (write the simplest code that passes), refactor (clean up without breaking the test). Done literally, it produces code with high test coverage and a forcing function against over-engineering. The discipline only pays off when those tests run on every change, which is why TDD and CI/CD are siblings, not separate concerns.
The reason most teams say they do TDD but actually do not: writing the test first feels slower in the moment. The compounding payoff (refactor safety, regression coverage, design pressure toward smaller units) only shows up months later. By then the team has stopped writing the tests first and convinced itself it never made a difference.
Worked example of where TDD earns its cost versus where it is theatre: a payments reconciliation module has gnarly edge cases (partial refunds, currency rounding, retries). Writing the failing test first forces you to state the expected behaviour before the code exists, and the suite catches the regression six months later when someone “simplifies” the rounding. That is TDD paying for itself. Now contrast a throwaway data-import script you will delete in two weeks: writing tests first there is pure overhead. The honest rule is to TDD the logic-heavy, expensive-to-get-wrong code and not the rest.
The most common mistake is treating coverage as a target. Chase 90% and the team writes tests for getters and setters to hit the number while skipping the integration tests where the real bugs live. Coverage is a useful diagnostic and a terrible goal; it is a metric to game. Wavect uses TDD where it pays: integration tests for anything money-shaped, contract tests for anything customer-facing, BDD-style acceptance tests where product needs to read them, unit tests for non-trivial logic. We test the hard parts well, not all parts equally, and we treat it as one practice inside a healthy agile loop rather than a box to tick.