Verdict
Yes
Yes, write tests when requirements keep changing: one API-level test for each rule the client states, changed in the same commit as the rule, and no tests of screen layout.
Why
- Blast radiususers
- Change frequencyconstantly
- Detectabilitysame-day
- Reversibilitywith-effort
- Test costmoderate
Yes, write tests while the requirements change; rule R11 gives Test for my typical case, a web application with live users whose product owner changes some rule in most weeks. Change frequency is constantly, and that raises the case for tests: each change can break a rule nobody meant to touch. Blast radius is users, and Detectability is same-day, because a user reports the broken rule within a day. Reversibility is with-effort, since records saved under a broken rule need a repair script. Test cost is moderate: a test of one rule takes about an hour, and a changed rule means editing that test.
| When | Decision | Why |
|---|---|---|
| The changing requirement is a screen's layout or copy, which the developer checks in the browser before merging | Do not test the layout; check it in the browser and in the client demo | Detectability moves to immediately and Reversibility to trivial: the developer sees the fault before merging |
| The changing rule sets a price, a discount or an invoice amount | Test mandatory: every amount and boundary of the current rule, reviewed by a second person | Blast radius rises to money and Reversibility to costly: a wrong charge ends in refunds |
| The changing rule decides which role may read which records | Test mandatory: allowed, denied and cross-account requests for each role | Blast radius rises to safety-or-legal and Detectability to never: a leaked record raises no error |
| Each change replaces the whole flow, and a useful test needs a browser and seeded accounts | Test minimally: one end-to-end test of the main path | Test cost rises to heavy: the test takes days to build and does not survive the next change |
| The requirements settle, and the feature changes a few times a year | Test minimally: keep the existing tests and add a regression test for each bug | Change frequency falls to rarely: a failure gets fewer chances to happen |
| A requirement change needs a one-time migration of existing records | Test the migration differently: rehearse it on a copy of production data, compare counts, and keep a backup | Change frequency falls to once: a test in the suite would never run again |
What breaks if you don't test
The client of a meeting-room booking app extends the booking window from 14 days to 30. The developer rewrites the date check and, in the same function, drops the limit of three future bookings per person. Nobody asked about the limit, so nobody tries it. One person books the large room for every Friday of the next month, colleagues complain the next morning, and someone cancels the extra bookings by hand.
What you lose if you over-test
A suite that mocks every class encodes which method calls which, so moving one check into another class fails every test that mocked the old class, while the behaviour stays right. Developers who see red tests after every requirement change learn to update them without reading them, and a real regression then passes too.
How to test
- Write one test for each rule the client states, such as "a room can be booked 30 days ahead", through the public API of the code, as Test Behavior, Not Implementation on the Google Testing Blog shows.
- When a rule changes, change its test in the same commit. An unexpected failure is the regression you wanted to catch.
- Delete the tests of a dropped rule together with its code.
- Check layout and copy in the browser and in the client demo.
The unit testing chapter of Software Engineering at Google sets the goal: a test changes only when its requirement changes.
When the answer changes
- The changing rule charges money or decides who may read which records.
- Every change rewrites the whole flow.
- The requirements settle, and the code changes a few times a year.
Counterexample + Code example
Waiting for the requirements to settle gets it backwards
The common advice is to write tests once the requirements stop moving. While the rules change in most weeks, Change frequency is constantly and the feature gets Test; after they settle, it falls to rarely and the same feature drops to Test minimally. The advice skips tests in the months when they catch the most regressions.
A test that states one rule also keeps its cost down: a changed rule costs one edited assertion. For the meeting-room app, in Vitest:
import { test, expect } from 'vitest';
import { canBook } from './booking-rules';
const now = new Date('2026-09-15T09:00:00Z');
const person = { id: 'p1', futureBookings: 0 };
// One test per rule the client stated.
test('a room can be booked 30 days ahead', () => {
expect(canBook(person, { start: '2026-10-15T09:00:00Z', hours: 1 }, now)).toBe(true);
expect(canBook(person, { start: '2026-10-16T09:00:00Z', hours: 1 }, now)).toBe(false);
});
test('a booking lasts at most 4 hours', () => {
expect(canBook(person, { start: '2026-09-16T09:00:00Z', hours: 4 }, now)).toBe(true);
expect(canBook(person, { start: '2026-09-16T09:00:00Z', hours: 5 }, now)).toBe(false);
});
test('a person holds at most 3 future bookings', () => {
const busy = { ...person, futureBookings: 3 };
expect(canBook(busy, { start: '2026-09-16T09:00:00Z', hours: 1 }, now)).toBe(false);
});
When the window moved to 30 days, one test changed, and the limit test still fails on any change that drops the limit.
Related questions
FAQ
- Should I use TDD if my project is changing fast?
Yes, TDD works on a fast-changing project when each test states one rule the client asked for, because a changed rule then means one changed test. TDD of internal classes costs more on such a project, since each redesign rewrites them.
- Should I wait until requirements are stable before writing tests?
No, do not wait for stable requirements, because code that changes in most weeks has the most chances to break. Write one test for each rule as it arrives, and edit it when the rule changes.
- How do I stop tests from breaking every time requirements change?
Tests fail only on real behaviour changes when each one checks a single rule through the public API of the code. A changed rule then fails one test, and a refactoring fails none.
- Should I delete tests when a requirement is dropped?
Yes, delete the tests of a dropped requirement in the commit that removes its code, because a test of a rule nobody wants fails at the next nearby change.