You Have Written This Test Case Before
New campaign bundles arrive every few sprints. The four test archetypes never change — only the promotion table does. That is a generator, not an authoring task.
You have written this test case before. Not one like it. It.
Same steps, same assertions, same order. A different product name and a different price, typed by hand, again.
The Requirement That Keeps Coming Back
New marketing campaign bundles, configured in Salesforce and in the billing system. It arrived as a requirement, it was tested, it closed. A few sprints later it arrived again with a different set of bundles. Then again.
Each time it looked like new work, because the bundles were new. Each time the test authoring was near-identical to the previous round, because the bundles were the only thing that was new.
At some point I stopped treating that as a coincidence and looked at what was actually varying.
Four test archetypes. The same four, every iteration. What changed between one iteration and the next was a table of promotions — names, prices, the data. Not a step. Not an assertion. Not an order of operations.
That is not a recurring authoring task. That is a function with an argument, being executed manually by a human.
What "Fixed Steps, Variable Data" Really Costs
A test case is two things wearing one name: a procedure and a set of parameters.
When the procedure is stable and only the parameters move, re-authoring means re-typing the part that did not change in order to update the part that did. The effort lands almost entirely on the wrong half.
And that half-hour of typing is not the real cost. The real cost is drift.
The version you wrote in the first iteration had an assertion that the fourth version quietly lost, because the fourth was written from memory on a Thursday afternoon. Nobody notices. There is no diff between two hand-written test suites, and no reviewer compares this sprint's cases against last quarter's. Two suites that were supposed to be identical except for data are now different in ways nobody can enumerate.
Manual re-authoring does not just cost time. It costs the guarantee that your coverage is the same coverage as last time.
The Move
When a requirement type recurs with identical steps and only the data varies, stop authoring it and build the generator.
Concretely, in this case: a flat CSV in — one row per promotion, columns for exactly the things that differ. The generator emits the test cases as JSON and the collective import CSV for the test-management tool in one command.
The next iteration of that requirement stops being an authoring sprint. It becomes: receive the promotion table, save it as a CSV, run one command, review the output.
The reviewing is still real work and still yours. What disappears is the typing, and with it the drift.
Finding Yours
Every programme has at least one of these. They hide because each occurrence has a different title.
- Wait for the second occurrence, then diff it against the first. One instance proves nothing. Two lets you see exactly which lines changed — and if the changed lines are all values, you have found a generator candidate. Do this deliberately rather than waiting to notice, because noticing is what has not happened for the last four iterations.
- Write the procedure once, in one file, and give it a name. The invariant steps are the asset. Keep them somewhere that is edited on purpose, not somewhere that gets copied and mutated. Every change to the procedure should be a change to that one file, so the improvement propagates to every future run.
- Take the input in the shape the business already sends you. The promotion table exists before you do anything — it arrives as a table, in a spreadsheet, from the people who own the campaign. Re-keying it into your own format is the same manual step you are trying to delete. Read their shape.
- Emit the tool's import format, not just your own. A generator that produces beautiful JSON nobody can upload has moved the manual step rather than removed it. The output that matters is the one your test management tool ingests directly.
- Version the template, not the output. The generated cases are disposable — regenerate them any time. What goes under review, and what gets improved when someone spots a missing assertion, is the template.
Why Most Testers Never Get There
Three reasons, and none of them is laziness.
The first is that re-authoring looks like work. It fills a day, it produces artefacts, it is visible on a board. Building a generator produces nothing on the board for half a day and then produces the same artefacts faster forever. Only one of those is easy to explain in a stand-up.
The second is disguise. The requirement never arrives labelled "the recurring one." It arrives with this quarter's campaign name on it, from a different stakeholder, in a sprint where it is the only thing that looks new. Recognising it as the fourth instance of a pattern requires remembering the first three.
The third is that the marginal cost never crosses a threshold. Retyping twelve cases is annoying, not painful. It is never bad enough on any single occasion to justify stopping, which is precisely how something gets done twelve times.
The Part That Outlives the Sprint
A generator is not only a time saving. It is a deliverable in its own right.
The invariant steps in it are a documented, reviewable statement of how this requirement type gets tested — which is the thing every programme claims to have and few can produce on request. It transfers to a new joiner in one paragraph. It transfers to a different client with the columns changed.
Test cases expire with the sprint. The pattern behind them does not, and the pattern is the part worth owning.
Which requirement on your programme has arrived three times already — and are you about to type it out for the fourth?