principle-test-behavior-not-implementation

Rewrites or deletes tests that assert implementation details instead of observable behavior.

1|Updated Aug 27, 2025
One-click install
npx skills add https://github.com/IgorGanapolsky/Random-Timer --skill principle-test-behavior-not-implementation-igorganapolsky
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: principle-test-behavior-not-implementation
Source: https://github.com/IgorGanapolsky/Random-Timer/tree/main/.cursor/skills/principle-test-behavior-not-implementation
Command: npx skills add https://github.com/IgorGanapolsky/Random-Timer --skill principle-test-behavior-not-implementation-igorganapolsky

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? Test suites accumulate tests that cannot fail for a real defect: weak assertions, mock-only checks, constant pins, and self-referential comparisons. These tests cost CI time and review attention while catching nothing, and constant pins actively block legitimate edits. ## Core Features & Use Cases - Dead-test detection heuristic: Apply the core check — would this test still pass if every imported function returned undefined? If yes, it observes no behavior. - Five anti-pattern catalog: Identifies weak assertions (toBeDefined, toBeTruthy), mock/absence-only checks (toHaveBeenCalled), self-referential expectations, constant pins, and fixture-asserts-fixture patterns. - Concrete rewrite guidance: Replace each anti-pattern with a call to the subject using one concrete input and an assertion against a literal expected output, such as expect(slugify("Hello, World!")).toBe("hello-world"). - Use Case: While reviewing a pull request, apply this Skill to flag a test that only asserts toHaveBeenCalled on a mock and rewrite it to assert the payload the mock received. ## Quick Start Review the tests in this change and rewrite or delete any that would still pass if every imported function returned undefined.

Frequently Asked Questions about principle-test-behavior-not-implementation

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I tell if a test is testing behavior or implementation?

Ask whether the test would still pass if every function it imports returned undefined. If yes, it observes no behavior and cannot fail for a real defect, so rewrite the assertion or delete the test.

How to fix a test that only checks toHaveBeenCalled on a mock?

Assert the payload the mock received or the state after the call instead of the call itself. A call-count assertion verifies wiring, not the result a user would observe.

Should I delete tests that assert constant values like config defaults?

Do not restate the constant; test the mechanism that reads it with one concrete input instead. Constant pins fail when someone edits the value, blocking legitimate changes without catching defects.

When is a weak assertion like toBeDefined acceptable in a test?

Rarely on its own, since it passes even when the subject returns undefined-adjacent values. Pair it with a literal expected output, or keep it only for relation checks across table rows and compile-time checks in *.test-d.ts files.

Why do self-referential assertions like expect(f(a)).toBe(f(a)) fail as tests?

The expected value comes from the code under test itself, so the assertion compares the code to itself and can never detect a defect. Replace it with a hardcoded literal expected result.