Every few years someone redraws the testing pyramid and gives it a new name. Test Pyramid, Testing Honeycomb, Testing Trophy: each one showed up because the economics of building software had shifted just enough that the old shape stopped making sense.
I think AI-assisted development just did that again, and this time the shape looks less like a pyramid and more like a rocket. So that's what I'm calling it, the Test Rocket.
How we got from Pyramid to Trophy
The classic Test Pyramid says: write a lot of fast, cheap unit tests, fewer integration tests, and only a handful of end-to-end tests. The logic held up for a long time. Unit tests are quick to write and quick to run, while anything higher up the stack tends to be slower, pricier, and more fragile.
That worked fine until applications got more distributed. Once your system is a bunch of services talking to each other, most of the interesting bugs stop living inside a single function and start living in the gaps between components: a serialization mismatch here, a timeout assumption there.
Spotify ran into this with microservices and wrote up the Testing Honeycomb. Their point was simple: a service's real complexity is in how it talks to databases and other services, and unit tests that mock all of that away end up testing implementation details instead of behavior. So they leaned harder into integration tests and kept the unit layer intentionally small.
Kent C. Dodds made a similar call for frontend work with the Testing Trophy: static analysis as the base, then a fairly small unit layer, then integration tests doing most of the heavy lifting in the middle, then a thin sliver of E2E on top.
The interesting move here had nothing to do with unit tests being bad. It was a challenge to the assumption that integration tests have to be slow and expensive. Modern tooling made them fast enough to use liberally, and they tend to catch more real bugs per test because they're exercising multiple pieces at once.
Honeycomb and Trophy were both making the same underlying argument. A pile of isolated unit tests is a bad investment when the behavior you actually care about only shows up when components interact.
AI changes the economics again
Neither the Pyramid, the Honeycomb, nor the Trophy accounted for something that simply didn't exist when they were written: unit tests can be an extremely fast feedback loop for an AI coding agent, not just a safety net for humans.
Watch an agent work for a while and the pattern becomes clear. It edits some code, runs a large pile of unit tests, reads the failures, and revises. Then does it again. And again.
That loop changes what a unit-test suite is for. It's no longer just something a developer maintains to catch regressions later. It's part of the agent's own working loop, telling it second by second whether the change it just made actually did what it was supposed to do.
And that changes the cost equation. Writing and maintaining a hundred extra unit tests used to mean a hundred extra units of human effort: someone had to write them, review them, keep them passing. An agent can generate a useful test in seconds. So the old question, "can we afford this many unit tests," mostly stops being the right question. What matters now is: do these tests actually tell the agent (or the reviewer) something true about behavior?
Introducing the Test Rocket
The Test Rocket keeps the same four layers as the Trophy (static analysis, unit, integration, E2E) but shifts where the weight sits.
The name isn't just decoration. Static analysis is the thrust base: broad, unglamorous, doing the unsexy work of keeping the thing from tipping over. Unit and integration tests make up the body, two full stages instead of one thin and one thick, because both are doing real propulsion now. Neither one is sized to be an afterthought. And E2E sits up top as the nose cone: small, essential, and not where the mass or the power lives.
The point of the Rocket isn't a specific ratio you're supposed to hit. It's this:
Build out real unit and integration feedback loops, and keep the higher layers focused on the kind of confidence only they can give you.
Static analysis doesn't stay flat either. It's the cheapest, fastest checkpoint there is, faster than even the first unit test run, so it's the natural place to catch an agent's mistakes before they cost a full test cycle. Teams working with agents lean on it harder: stricter type checking, custom lint rules for house conventions the agent keeps missing, dependency and security scans, complexity gates on generated code. Same reason the unit layer grows: it's fast enough to run on every single change.
Unit tests are where the shift really shows up. In an AI-driven workflow they're the fastest way for an agent to check "did I just break something," which makes a much bigger unit layer worth having, even when the tests are fully isolated.
But "bigger" only means something if you know what's going in it. Think of it less as Honeycomb or Trophy's unit layer with the volume knob turned up, and more as new categories that were always worth writing but rarely survived the cost-benefit call a human had to make:
- Boundary and edge-case tests (nulls, empty collections, off-by-one ranges) that were correct in principle but never made the cut when someone had to write each one by hand.
- Property-based tests that check a rule holds across a generated range of inputs, instead of the two or three hand-picked examples a human had time for.
- A permanent regression test for every bug the agent fixes, so the same failure can't quietly come back later. Something teams always meant to do consistently and rarely did.
- Characterization tests that pin down existing behavior before a refactor, so both the agent and the reviewer have a safety net for changes that used to be too risky to attempt.
- Narrow, single-behavior tests around whatever the agent is actively touching, so a failure points at exactly what broke instead of a broad integration failure that still needs to be tracked down.
None of these are exotic. They're the tests a careful developer always knew were worth having and rarely had the hours to write. The idea of a good unit test hasn't changed. What changed is that these specific kinds finally got cheap enough to actually exist.
Integration tests still do what unit tests can't: prove that the real database, the real HTTP boundary, the real message queue actually work together. AI helps here too, generating fixtures and test containers faster, but standing up a real dependency and waiting on real I/O doesn't collapse the way authoring cost did for unit tests. That's why this layer doesn't need its own "what's new" list: it was already substantial under Honeycomb and Trophy. The Rocket doesn't trade it away to fund the unit layer, it keeps both substantial.
E2E tests stay at the top, validating the handful of journeys that matter most. Cheap generation doesn't change their calculus the way it does unit tests or static analysis, because their cost was never about who writes them. It's the run itself: a real browser, a real backend, minutes instead of milliseconds, and flakiness no amount of AI-assisted authoring fixes. An agent can write fifty E2E scripts as easily as five, but running all fifty on every change is still slow. They stay expensive enough that you don't want them carrying weight unit and integration already cover.
Okay, but weren't unit tests supposed to be the problem?
Fair question, and the old criticism still holds in one specific way: a bad unit test is still a bad unit test. If it's asserting implementation details, mocking every single collaborator, breaking every time you rename a variable, or existing purely to nudge a coverage number, none of that gets better just because an AI wrote it faster.
What actually changed is the economics, not the standard for what makes a test good. The old argument against a big unit layer was about human time: writing and babysitting a large pile of isolated tests wasn't worth it when integration tests gave you more confidence per test written. Once the marginal cost of producing a useful unit test drops, and its value as instant feedback to an agent goes up, that math just doesn't hold the way it used to.
So no, Test Rocket isn't secretly the Pyramid wearing a new hat. It's not arguing that unit tests should dominate again, and it's not arguing for a specific 50/50 split either, that would just be swapping one arbitrary ratio for another. What it's arguing is narrower: neither unit nor integration should be the thin layer anymore. Honeycomb and Trophy each picked one of the two to keep small, on the assumption that a large amount of the other layer was expensive to produce and maintain. Once that assumption stops holding for unit tests specifically, there's no longer a good reason to keep either layer deliberately thin. The exact ratio between them should come from where your bugs actually live, not from how much either layer used to cost to write.
Each layer is still answering a different question:
- Unit tests: did this specific piece of local behavior just break?
- Integration tests: do the real components actually work together?
- E2E tests: does the journey a user cares about still work end to end?
- Static analysis: is this code even structurally sound?
A caveat that matters more than it sounds like it should
This is where I'd push back on my own idea a little, because there's a real trap here, and it's not the one people usually reach for first.
The obvious worry is cost: teams churning out low-value tests because it's cheap now. The sharper worry is Honeycomb's original one: heavily mocked, isolated unit tests get coupled to implementation details, which makes them actively harmful during refactors, not just wasteful to write. Cheap AI-generated tests make that worse before they make it better. An agent looking at code it just wrote has every incentive to generate a test that mirrors that code's structure, since that's the fastest path to green. A bigger, cheaper unit layer can easily reintroduce exactly the failure mode Honeycomb warned about, just at higher volume, especially if the same pass that writes the implementation also writes the tests and grades itself against them. A test derived from the code it's checking will happily assert "the code does what the code does," which says nothing about whether it does what it's supposed to.
And routing every generated test through a human reviewer doesn't fix this. It just moves the bottleneck somewhere less visible and kills the speed that was the whole point. The fix needs to be automated:
- Derive tests from the spec, not the code. Generated from what the feature should do, in a pass that never sees the implementation. This is the direct answer to Honeycomb: a test that never saw the code can't get coupled to it.
- Derive tests from the plan the agent committed to before writing code. A weaker independence guarantee than spec-derived (same reasoning wrote both), but a useful second signal.
- Write the test before the code (TDD). If the test has to pass before the implementation is "done," it can't have been shaped to match code that doesn't exist yet. This bakes spec-first independence into the workflow itself, rather than relying on discipline to keep the two passes separate.
- Use a second, adversarial agent to hunt for disagreements between test and behavior, instead of trusting the implementation's own context to vouch for itself.
- Run mutation testing, sparingly. It confirms the suite actually fails against injected faults, but running the whole suite once per mutant gets expensive fast. Treat it as a targeted, occasional check on changed code or high-risk paths, not a blanket policy. The adversarial-agent approach above scales better as a default.
Human review still has a role spot-checking specs, but it can't be the main gate. That gate needs to move as fast as the agent it's checking.
The core idea
The Pyramid optimized for cost. Honeycomb and Trophy optimized for confidence and for catching failures at the boundaries. The Rocket adds a third thing to optimize for: how well the suite feeds an AI that's continuously generating and rewriting code.
That changes the value of the fast layers. Static analysis becomes a stronger first checkpoint, catching cheap structural mistakes before they consume a test cycle. Unit tests provide fast behavioral feedback, while integration and E2E tests add progressively higher-confidence validation.
Unit tests didn't get better as an idea. What they're used for, and what they cost to produce, changed underneath us.
More tests turn out to be part of the answer, but they were never the point on their own. The point is a fast, layered system that gives an AI enough signal to move quickly, and gives engineers enough confidence to actually hit deploy.
That's the Test Rocket 🚀.




Top comments (0)