Principle Test Behavior Not Implementation

by cursorccb5507cec15No license10K starsListed Oct 8, 2026Updated Oct 8, 2026Repository updated today

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.

Instructions onlySoftware Development
AI-generated overview

A guideline for writing tests that assert observable behavior with literal expected values instead of implementation details.

What it does
This skill provides a review principle for tests: a test should call code the way its users do and assert the result they observe against a literal expected value. It offers a check — whether the test would still pass if every imported function returned undefined — and lists five shapes of tests that fail this check, such as weak assertions, mock-only assertions, self-referential expectations, constant pins, and fixtures asserting fixtures. It then describes fixes: call the subject with one concrete input and assert the literal output or observable effect, assert presence on another input for absences, test the mechanism that reads a constant, or delete the test. It also notes which tests…
When to use it
Use this when writing, changing, or keeping a test and you want to confirm it can actually fail for a defect. It is suited to reviewing existing tests for weak or implementation-coupled assertions, and to deciding whether a test should be rewritten or deleted.
Requirements
No tools, packages, or credentials are required; it is instructions only and ships no scripts.

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.

Source and attribution

Source:cursor/pluginsinpstack/skills/principle-test-behavior-not-implementationat commitccb5507

License: No license

Content belongs to its original authors. SourceWeft indexes it from a public repository.

Report or request removal