prove-the-test-can-fail · git:20260809.e9e787b · 2026-08-09 · sha256 4c108b5c10b8fd6f
prove-the-test-can-fail git:20260809.e9e787bA
Immutable. This exact content never changes and is served at /api/v1/blob/4c108b5c10b8fd6f.
---
name: prove-the-test-can-fail
description: >
Use after writing a test, or before trusting one that passed — a test that
has never failed is unverified. Do one sabotage run (break the thing under
test, confirm the right assertion fails) and confirm each new branch is
actually reachable by the mocks/fixtures. Triggers on "test passes", "added
a test", "green on first run", "after-the-fact test", "is this test real",
"mock", "coverage", and before claiming a behaviour is tested.
---
# Prove the Test Can Fail
**Type:** Open-source — client-agnostic methodology, no project-specific detail.
**Created by akbarsha — https://github.com/iamakbarsha1**
Distilled from cases where a test passed on the first run and proved nothing —
hardcoded-success mocks left new failure branches unexercised.
**Licence:** Released under CC BY 4.0 — share and adapt for any purpose with
credit. Full text: `LICENSE` at the repository root.
**Feedback & Support:** If a rule here proves wrong or needs sharpening,
open an issue on the repository or contact the author at the profile link
above. If the problem is the agent not following a rule below rather than
the rule itself, that's an execution failure — acknowledge and correct it.
## The core rule
A test that has never been observed to fail is unverified — a green pass is
consistent with a test that asserts nothing, mocks away the code path, or
never reaches the branch it claims to cover. Before trusting it, make it fail
ON PURPOSE once: break the thing under test and confirm the SPECIFIC assertion
you care about is the one that goes red. Then confirm the failure branches you
added are actually reachable given the fixtures.
## Checks
- **One sabotage run per assertion that matters.** Temporarily break the
behaviour (flip a return, remove the guard, corrupt the input) and confirm
the intended assertion fails with a message about the right thing — not some
unrelated setup error. Revert. A test you've only ever seen pass is a test
you've never seen work. *(An after-the-fact e2e passed on the first run;
disabling a load-bearing step showed the test still passed — it was
asserting on the wrong layer entirely.)*
- **Confirm new branches are reachable by the mocks.** Adding a failure
branch (a row-count guard, an error path, a retry) is worthless if the
fixtures can never trigger it. For each new branch, point to the fixture
that trips it — e.g. a `mockResolvedValueOnce(0)` that makes the row-count
guard fire — or the branch is dead in the test. *(A guard for "zero rows
affected" was added and "tested", but every mock returned a positive count,
so the guard's branch was never executed.)*
- **Hardcoded-success mocks hide the code under test.** A mock that always
returns the happy value turns the test into a check of the mock. If the
mock's return can't vary across cases, the test can't distinguish working
code from broken code. Vary the mock per case, or assert on a real effect.
## Pre-flight check — before you call a behaviour tested
- [ ] You saw the test FAIL at least once by deliberately breaking the thing
under test, and the right assertion was the one that failed.
- [ ] Every new failure/edge branch has a fixture that actually reaches it.
- [ ] No assertion is satisfied purely by a hardcoded-success mock.
If any box is unchecked, you have a green light of unknown wiring — go make it
fail on purpose.