永远不会失败的测试
Tests that can't fail
智能体加的测试调用了代码,却什么都不断言(或断言一个必然为真的东西),覆盖率涨了,保护力没涨。
适用于: Claude Code · Cursor · Codex · Copilot agent
症状
新增的测试块里没有 `expect`/`assert`,或者只有 `expect(result).toBeDefined()` 这种对总是返回对象的函数毫无意义的断言。
为什么会这样
写个测试框架看起来很周全,算出准确的期望值却更难。agent-review 把它列为 AR010“没有断言的测试”(高严重度)。
示例
摘自 agent-review 分类(AR010)。
jstest("login works", () => {
const r = login();
}); // no expect / assert
复制即用的修复
按你用的智能体挑选文件。规则片段用英文写,放进任何仓库都能用。
规则
Claude Code:加入 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.
规则
Codex、Copilot 编码智能体等:加入 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 规则
Cursor:项目规则
.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 / 脚本
变异测试式的自检(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"