Keeping quality with tests and review
Practices that keep agent-assisted changes shippable: tests as the contract, review as the gate, types as the first filter.
Tests as the contract
A prompt is ambiguous; a test is not. Write the failing test first and let the model satisfy it, or ask for test and implementation together and reject the pair when the test proves nothing.
// the test is the specification the agent works against
test('rejects disposable domains', () => {
expect(validateEmail('[email protected]').ok).toBe(false);
});
test('accepts ordinary domains and normalises case', () => {
expect(validateEmail('[email protected]').value).toBe('[email protected]');
});
// vacuous - passes whatever the implementation does
test('returns something', () => {
expect(validateEmail('[email protected]')).toBeTruthy();
});- Ask for a test that fails for the right reason before the fix.
- Reject tests that assert nothing, mirror the implementation, or mock the thing under test.
- Keep the suite fast, or the loop stops being a loop and nobody runs it.
Review is the gate
| Check | Question to ask |
|---|---|
| Diff size | Can I explain every changed file? |
| Behaviour | Which test would fail if this logic were wrong? |
| Dependencies | Did it add a package I did not ask for? |
| Secrets | Any key, token or internal URL in the change? |
| Rollback | Can I revert this in one command? |
💡
Two habits cover most of the risk: never accept a diff you cannot explain, and make every change revertible. Both are free, and both are the ones most often skipped.
FAQ
How much review is enough?
Enough that you could reimplement the change from memory. If you cannot, you are trusting code you do not understand.
Do generated tests count towards coverage?
Only when they assert real behaviour. Coverage produced by tests that always pass is a number, not evidence.
Related
When it works and when it fails Workflow tips and limits
Last refreshed 2026-09-18.