A test suite can make a small change expensive. Update one business rule, and tests across several services fail. Those tests repeat checks of the same implementation, so one rule change creates several rounds of repairs. Engineers must repair test data and unrelated expectations before they can assess whether the business rule still works.
That is a legitimate reason to simplify the suite.
In a recent AI-assisted review, I looked at a cleanup that removed duplicated assertions and moved detailed checks closer to the code responsible for them. Much of it made sense. The tests had clearer responsibilities, and changes would require fewer unrelated updates.
Formatting, linting, type checks, and the full remaining test suite passed.
Then we deliberately broke two behaviors. The suite still passed.
The original tests caught both regressions. That changed the recommendation: keep the cleanup, but preserve a few small assertions at the boundaries where the coverage had disappeared.
The examples below are anonymized and simplified. They preserve what the experiments established without identifying the company or vendors.
The missing coverage was between the pieces
The cleanup relied on a reasonable idea: if tests already cover a helper’s rule thoroughly, the code that calls it needs fewer detailed checks.
The problem was deciding which details belonged to the helper and which belonged to the caller.
In the first case, a service selected a customer identifier from an incoming order and passed it to another operation. The remaining tests confirmed that records were written. They no longer checked which identifier the caller supplied.
We changed the caller to forward the order identifier instead of the customer identifier.
The remaining suite passed. The helper’s tests supplied the correct customer identifier themselves, so they had no reason to fail. The original caller tests detected the change.
In the second case, the application connected several services to a shared fulfillment operation. Each service had its own tests and test dependencies. We replaced that operation with one that reported success but did nothing.
Again, the remaining suite passed. The service tests showed that fulfillment worked when correctly connected. They could not establish that the application connected it correctly. The original tests for those connections caught the defect.
Both experiments exposed a gap in how the pieces were assembled. A component can behave correctly in isolation while its caller selects the wrong input or omits an essential effect.
That distinction also explains the smallest useful repair. The caller did not need to repeat the helper’s calculations or check every field sent to a provider. It needed to check the customer identifier it forwarded. The code connecting the services needed a check that fulfillment received the expected inputs on the relevant paths.
Make the removal claim testable
“This test is redundant” needs a narrower explanation before it becomes a safe edit.
Start with the test proposed for removal: the candidate. Name the behavior it protects and identify the tests expected to keep protecting it. Then introduce a plausible defect that breaks that behavior.
This is a focused use of mutation testing: deliberately changing application code to see whether tests detect the defect. Run the experiment in an isolated copy, never in a live system.
For the identity example, the experiment can be expressed with this illustrative code:
// Required behavior
await updateCustomer(order.customerId)
// Temporary mutation: the caller selects the wrong identity
await updateCustomer(order.id)
Use different customer and order identifiers in the test data. If both have the same value, the experiment cannot distinguish the correct selection from the incorrect one.
The change must reach the behavior under review. A syntax error or missing import can fail a check without exercising the customer identifier. Inspect the failure and confirm that the test detected the intended defect.
First, confirm that the candidate passes with the correct behavior and fails with the intended defect. Then exclude it temporarily. Run the remaining tests against the same defect to see whether they still detect it.
If the candidate does not detect the defect, inspect the experiment before judging the test. The test may protect something else. The change may also leave the relevant behavior unchanged. If no tests fail, investigate a possible coverage gap.
Candidate passes with correct behavior and fails on the intended defect
Exclude the candidate. Do the remaining tests detect the same defect?
Check distinct inputs, failure paths, and how easily each test identifies the cause before deciding.
Illustrative removal decision: overlapping detection is evidence to review, not automatic permission to delete.
One shared failure does not prove two tests interchangeable. Both may cover a successful request, while only one catches a wrong identifier, an omitted operation, or an ignored failure. A broad test may detect a defect while a smaller test makes its cause much easier to locate.
The evidence supports a particular removal decision within the cases examined. It is not proof that every possible regression remains detectable.
Keep the experiment bounded and reversible
These experiments ran in an isolated copy of the code. That kept temporary defects away from unrelated work and production systems.
For a removal review, I would use the following sequence:
- Establish a passing baseline for the relevant tests and preserve existing changes.
- Introduce one plausible behavior defect in the production path the candidate exercises.
- Run the candidate and surrounding tests, inspecting why each failure occurred.
- Exclude the candidate and check whether the remaining tests detect the regression. Repeat for materially different contracts or paths where needed.
- Restore the experimental changes. After the intended cleanup, rerun the appropriate checks and inspect the final diff.
Restoration belongs in the procedure even when a command fails or the review is interrupted. A temporary mutation should never become part of the cleanup commit.
Match the investigation to the consequence. Selecting the right customer and triggering fulfillment deserved explicit experiments. Rearranging test descriptions does not justify the same effort.
Automated mutation tools can examine more code. A focused review can start with a few deliberate defects chosen to test the removal claim.
If the evidence remains ambiguous, keeping a compact test is often cheaper than spending more time trying to justify deleting it.
Use AI to challenge the cleanup
This review is a concrete example of how I use AI to make software easier to own. The assistant helped inspect the diff, trace callers, and run controlled experiments. The useful question was whether the remaining tests would reject a specific business failure.
A review request can make that obligation explicit:
For each test proposed for removal, identify the required behavior it protects and the coverage that remains. Use an isolated experiment to introduce a plausible regression. Report which tests detect it with and without the candidate. Restore all experimental changes and explain what the evidence does not establish.
The model’s explanation still needs inspection. It may call tests equivalent because they use similar data or call the same helper. Neither proves that they protect the same required behavior.
It can also overcorrect by recommending that every deleted assertion return. That would discard the maintenance benefit of the cleanup. In this case, the recommendation was to keep focused checks at the callers while preserving clearer responsibilities and less duplication elsewhere.
I did not measure a meaningful execution-speed improvement. The supported benefit was a suite with fewer unrelated expectations and clearer responsibilities. The experiments identified where the proposed reduction went too far.
Preserve the contract with less machinery
The final judgment was that the cleanup was worthwhile and needed two targeted coverage repairs. A successful baseline alone had not exposed that distinction.
This is where practical simplicity and designing for the next engineer meet. A smaller suite is useful when it lets someone change the implementation while retaining clear evidence that the required behavior survives. Sometimes that means deleting a large test. Sometimes it means replacing it with one precise boundary assertion. Sometimes it means leaving the existing test alone.
For the next cleanup, choose one proposed deletion and write down a defect you expect the remaining suite to catch. Introduce that defect in an isolated environment and inspect the result. The answer will tell you more about the removal than another green run against unchanged production code.


