What It Costs, What It Returns
Part 3, the one for whoever signs the invoice.
The honest QA pitch was never “we caught bugs”. It is “here is what this decision costs, and here is what it returns”. I learned that the slow way, moving from the person who blocks releases to the person who puts the trade on the table and lets the one who pays decide. So let me put the architecture decision in those terms.
Maintenance: one change, one place
The one-way dependency graph turns most changes into single-file edits.
A selector moved. You edit components.ts. One file. Every test that used it is already fixed.
A flow gained a step, say an extra confirmation screen. You edit actions.ts. One file. All thirty tests that call that flow inherit the change.
A new scenario. You add to test.ts. The other three layers do not move.
Compare that to the all-in-one method, where a selector and a business rule sit in the same place. You touch the file, you risk the other concern, and you re-review the whole thing to be sure. The cost is not the edit. The cost is the blast radius of the edit.
Scaling: the flat-cost asset
A new tester points at one folder. Four files, each obvious, a template they can copy and edit on day one. Onboarding drops from weeks to days.
The tenth test in a feature costs roughly what the second one did, because the shape never changes. That flatness is the actual asset. Most suites get more expensive per test as they grow, which is why they quietly stop growing. This one does not bend that way.
The track record, anonymised but real
Two years. Roughly 25 months and counting.
Nine production systems.
3000+ tests still running across the portfolio, 180 to 520 per system.
Two of the nine projects died for unrelated business reasons. The other seven still run CDAT-shaped tests today. I am not selling a miracle. I am reporting a survival rate.
Why this is not a 2019 conversation
Here is the part that makes the architecture decision urgent now.
The cost of writing a test is collapsing. Agents will write more of them, faster, this year and next. The bottleneck moves from “writing tests” to “maintaining the tests a machine wrote at machine speed”. And a machine writing into a god object produces debt at machine speed too.
So the architecture decision is now an AI decision. A deterministic structure is the thing that lets you safely turn the generation speed up. Without it, faster generation is just faster mess. The tooling, the agents, the whole next stretch of this series, only pays off on top of structure that already holds. Context first, then AI. The order is not negotiable, and you set it once, at the architecture.
ROI, in the currency that matters
Every hour a senior spends grepping a monolith for where a change lives is an hour not spent on the coverage that would have stopped a production incident.
The regression you ship because a split method let you fix one half and miss the other is not a QA line item. It is a revenue line item. Some share of users hit it, do not buy, and your support queue floods. The person who signs the invoice decides what that is worth, so hand them the number in their currency: maintenance hours saved, incident risk lowered, onboarding measured in days instead of weeks.
Where it loses
Skip this when the project is five tests on a static page. POM is fine, anything is fine.
Skip it on a JavaScript-only codebase staying that way, because you lose the type-safety third of the value.
Skip it when the team already ships Screenplay well. Do not break what works.
The pattern earns its keep on systems that have to survive both rapid feature work and the month the original author changes teams. If your system does not have to survive that, you do not need this.
If your suite has started to rot
That is the conversation I take for a living, especially right before a team lets agents loose on a suite that cannot hold them yet.
Implementation and consulting: sdet.it/services
The pattern itself is MIT and public: github.com/darco81/cdat-pattern
There is an MCP endpoint at cdat.sdet.it/mcp if you want your own assistant to read the docs first, which is a fitting way to end an episode about giving the machine a structure it can reason about.
Related
The long-form reasoning, every layer with full code: the CDAT deep dive.
The bigger picture this episode fits into: Context-First QA, Series #03.
The pattern has its own product site and proves itself on itself, 124 CDAT-on-CDAT tests against it: cdat.sdet.it.
From the Field is what I actually build, what breaks, and what I learn. Real projects, real numbers, real bugs. No tutorials.