Principle Test Behavior Not Implementation

作者 cursorccb5507cec15无许可证10K 个星标收录于 2026年10月8日更新于 2026年10月8日仓库今天更新

Apply when you write, change, or keep a test. Call the code the way its users do and assert the result they observe against a literal expected value. If the test would still pass when every imported function returns undefined, rewrite the assertion or delete the test.

AI 生成的概览

一套编写测试的准则:断言可观察行为与字面期望值,而非实现细节。

功能
该技能提供一条测试审查原则:测试应像使用者那样调用代码,并针对字面期望值断言其观察到的结果。它给出一个检查方法——若所有被导入的函数都返回 undefined 时测试仍能通过,则说明问题——并列出五类无法通过该检查的测试形态,例如断言过弱、仅断言 mock、自引用期望、常量钉死,以及夹具断言夹具。随后说明修复方式:用具体输入调用被测对象并断言字面输出或可观察效果;对于“不存在”的情况,在同一测试中用另一输入断言其存在;对于常量,改为测试读取该常量的机制;对于 mock,断言其收到的载荷或调用后的状态;若不存在此类断言则删除该测试。它还指出应保留的测试,例如跨表行的关系测试以及 *.test-d.ts 文件中的编译期检查。
适用场景
适用于编写、修改或保留测试时,确认该测试确实能因缺陷而失败。也适合审查现有测试中过弱或与实现耦合的断言,并判断某个测试应当重写还是删除。
运行要求
无需任何工具、软件包或凭据;仅为说明性指令,不附带脚本。

Test Behavior, Not Implementation

A test calls the code the way its users do and asserts the result they observe against a literal expected value. A test that asserts which calls the code made, or restates a constant the code contains, does neither.

The check: before you keep a test, ask whether it would still pass if every function it imports returned undefined. If yes, it observes no behavior and cannot fail for a defect. Rewrite the assertion or delete the test.

Why: A test that cannot fail for a defect costs CI time and review attention and catches nothing. A constant pin also fails when someone edits the constant or the prompt it restates, so it prevents that edit.

Five shapes that still pass when every imported function returns undefined:

  • Weak or no assertion. No expect, or only toBeDefined, toBeTruthy, not.toThrow, toBeInstanceOf, toBeGreaterThan(0).
  • Mock or absence only. Only toHaveBeenCalled, not.toHaveBeenCalled, toBeUndefined, toEqual([]), toHaveLength(0), not.toBe(wrongValue).
  • Self-referential. The expected value comes from the code under test: expect(f(a)).toBe(f(a)), expect(parsed.url).toBe(buildUrl(...)).
  • Constant pin. The assertion restates a hand-maintained constant, config default, table row, or prompt string: expect(LIMITS.maxTools).toBe(8), expect(PROMPT).toContain("You are").
  • Fixture asserts fixture. The assertion reads data the test built or a value computed in beforeEach, and the subject never runs inside the body.

The fix: call the subject inside the test body with one concrete input and assert the literal output or the observable effect, expect(slugify("Hello, World!")).toBe("hello-world"). For an absence, assert the presence on the other input in the same test. For a constant, test the mechanism that reads it with one input instead of restating the value. For a mock, assert the payload it received or the state after the call, not that it was called. When no such assertion exists, delete the test.

Keep a test of a relation across a table's rows (a key present in two tables, a parent that exists), and a compile-time check in a *.test-d.ts file.

来源与署名

来源:cursor/plugins位于pstack/skills/principle-test-behavior-not-implementation提交ccb5507

许可证: 无许可证

内容归原作者所有。SourceWeft 从公开仓库中收录这些内容。

举报或申请下架