All articles & videos

What could I delete and stay green?

Ask an agent for tests and it writes mocks, sleeps and button checks. One question per test turns that list into a suite worth keeping.

Adil Ben Moussa
07 November 2026· 5 min
What could I delete and stay green?

The previous part closed the last hole in the migration plan. One step is left in every part of it: the tests the agent writes. Take the new transfer component from part 4 and ask the agent for its tests. What usually comes back:

  • a mocked AccountsStore ({ accounts: () => [...] } as any) and a mocked Router
  • await new Promise((r) => setTimeout(r, 0)) between steps
  • expectations on component.error() and component.verdict()
  • a test that querySelector('button') is not null

Solitary tests, mocks everywhere, implementation details asserted. The agent defaults to the opposite of a good test suite. So apply one question to each test.

The question

What could I delete from the production code and still see green?

Green tests, clean code, shipped fast, and nobody can say what it does when production breaks.

The button-exists test. I could delete the whole submit flow and it stays green. Delete the test.

"A blocked account shows a message", with a mocked store. The mocked store hands back the message, so I could bypass canTransfer() and it stays green. But a blocked account is a requirement a customer sees. Rewrite it with the real store, and assert the message on the screen.

"Navigates after transfer", with a mocked store and a mocked router. I could delete the store.transfer() call and the mocked router still records the navigation. Rewrite it with the real store over the fake backend, then assert two things: the balance went down and the route changed.

The setTimeout waits. Rewrite with await fixture.whenStable().

In the workshop runs on this component, roughly half the generated tests were deleted, a quarter rewritten through the DOM, and a quarter kept. The agent's first draft of a test suite is a list of candidates, and reviewing it is where the time goes.

The red-flag list

These lines go into the demo repo's AGENTS.md, so the next generation of tests is better before anyone reviews it:

  • a test double for anything inside the unit; only the boundary, the fake backend, gets a fake
  • sleeps or setTimeout in a test
  • assertions on component fields instead of the DOM or store state
  • an expected value recomputed by the code under test instead of hardcoded
  • an element asserted present that exists from first render regardless of data
  • a green run whose console output contains an error

The last one is the cheapest to check and the most often skipped. A stray backend error in a green run usually means a test passed without checking what went wrong.

Prompt · review your own tests before I do

Read the test rules in AGENTS.md. Then review libs/feature/transfers/src/lib/new-transfer.spec.ts, which you wrote. For each it(), answer one question: which line of production code could be deleted with this test still green? If the answer is "any important one", mark the test DELETE or REWRITE and say which rule it breaks. Do not edit the file. Reply as a table: test name, verdict, rule.

The agent is a fair judge of its own tests when the question is this specific. It often marks many of them itself, which turns your review into a check of its verdicts.

What a kept test looks like

From new-transfer.spec.ts on track1/m2-ngmodule-solution:

it('moves the money and returns to the account', async () => {
  const { harness, type, click, store, router } = await open();
  type('Amount (MAD)', '500');
  type('Label', 'Loyer');
  await click('Confirm transfer');
  await harness.fixture.whenStable();
  harness.detectChanges();
  expect(store.accounts()[0].balanceMad).toBe(1500);
  expect(router.url).toBe('/accounts/a-1');
});

open() opens the URL with the real store over an instant fake backend, where the account starts at 2,000 MAD. type() finds a field by its label and click() a button by its name, like a user. So 1500 is the requirement written down: 2,000 minus the 500 typed. Delete the store.transfer() call from the component and this test goes red. That is the whole definition of a test worth keeping.

Back to the meeting

Part 1 started with a diff of well over a thousand lines and a meeting where only the demo counted. Here is the same kind of migration in the demo repo, measured with git diff --stat on track1/m2-ngmodule-solution and counted per path:

  • Pin (task 000): 141 lines, all tests. No production line changed.
  • Build beside and flip (task 002): 233 lines of production code, most of it one 223-line component, plus 271 lines of tests and the generator's scaffolding. The switch itself is one changed line.
  • Delete (task 003): 545 lines removed, 1 added, no logic.

Three task files, each one a pull request a person can read in one sitting, and no step that needs anyone to remember how the old screen worked. The screen from part 6 was built beside and flipped the same way on track1/m2b-angularjs-solution, ending in a four-line route change. These are demo repo numbers, not a client's. Your own come from the same command.

A pull request you can read in one sitting is one you can explain at two in the morning.

On Monday

  • For every generated test, ask what you could delete and stay green. Delete or rewrite accordingly.
  • Put the red flags in your rules file.
  • Run git diff --stat on your next three agent pull requests and write the review hours next to each. Take those two columns to the meeting, not the demo. They answer the question from part 1: why are we not faster?

Exercise: scene 3 of module 2 in the demo repo. Start from your scene 2 branch, or git switch -c m2/tests origin/track1/m2-ngmodule-solution. Reference: the five tests in new-transfer.spec.ts on that branch. Then delete the test rules from AGENTS.md, run it again, and watch the difference.


Track 1, part 7, the last of this track, in the free series behind the Fast and safe: AI in your Angular codebase workshop. The closing part is the policy your team writes down.

Share this article
Workshop

Fast and safe: AI in your Angular codebase

Let agents write Angular under rules, modernise legacy code without breaking production, and keep it secure, in three days, on an enterprise-shaped codebase.

See the agenda
Read next