Tests that can't fail
永远不会失败的测试
The agent adds tests that call the code but assert nothing (or assert something trivially true), so coverage goes up and protection doesn't.
Applies to: Claude Code · Cursor · Codex · Copilot agent
Symptom
New test blocks with no `expect`/`assert`, or assertions like `expect(result).toBeDefined()` on a function that always returns an object.
Why it happens
Scaffolding a test looks thorough; working out the exact expected value is harder. agent-review lists this as AR010 "Test without assertion" (High severity).
Example
From the agent-review taxonomy (AR010).
jstest("login works", () => {
const r = login();
}); // no expect / assert
Copy-paste fixes
Pick the files for the agents you use. Snippets are in English so they work in any repo.
Rules
Claude Code: add to CLAUDE.md
CLAUDE.md## Every test must be able to fail
- Each new test asserts a specific expected value or error, not just that something is defined.
- For each new test, state the bug it would catch. Then prove it: temporarily break the code
(or invert the assertion), show the test fails, and restore.
- No `sleep`-based waits in tests; wait for the event or state instead.
Rules
Codex, Copilot coding agent and others: add to AGENTS.md
AGENTS.md## Every test must be able to fail
- Each new test asserts a specific expected value or error, not just that something is defined.
- For each new test, state the bug it would catch. Then prove it: temporarily break the code
(or invert the assertion), show the test fails, and restore.
- No `sleep`-based waits in tests; wait for the event or state instead.
Cursor rule
Cursor: project rule
.cursor/rules/assertion-free-test.mdc---
description: "AgentFails: Tests that can't fail"
globs: **/*.{test,spec}.*
alwaysApply: false
---
## Every test must be able to fail
- Each new test asserts a specific expected value or error, not just that something is defined.
- For each new test, state the bug it would catch. Then prove it: temporarily break the code
(or invert the assertion), show the test fails, and restore.
- No `sleep`-based waits in tests; wait for the event or state instead.
CI / script
Mutation-style sanity check (JS/TS, Stryker)
terminal# Mutation testing changes your code on purpose; tests that still pass are not asserting anything useful.
npm i -D @stryker-mutator/core @stryker-mutator/vitest-runner
npx stryker run --testRunner vitest --mutate "src/**/*.ts"