/testing-philosophy
Use when proposing, writing, or reviewing automated tests, defines what a good test is: behavior over implementation details, and the Testing Trophy with a hard floor on end-to-end coverage for user-facing features. Generalized to any language and any layer (frontend, backend,
$ npx -y skills add Flagrare/agent-skills --skill testing-philosophy --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.
- You can call itInvoke it directly when you want it.
- Slash command
/testing-philosophy
Context preview
The summary Claude sees to decide when to auto-load this skill.
Use when proposing, writing, or reviewing automated tests, defines what a good test is: behavior over implementation details, and the Testing Trophy with a hard floor on end-to-end coverage for user-facing features. Generalized to any language and any layer (frontend, backend,
SKILL.md
testing-philosophy.SKILL.mdname: testing-philosophy
description: "Use when proposing, writing, or reviewing automated tests, defines what a good test is: behavior over implementation details, and the Testing Trophy with a hard floor on end-to-end coverage for user-facing features. Generalized to any language and any layer (frontend, backend, CLI, library), not just JS/React. REQUIRED BACKGROUND for skills that plan or review tests, atdd-plan, implementation-review, tdd-writer, wrap-up. Use when the user asks whether tests are good, what to test, why a test is brittle, or whether e2e is needed."
Testing philosophy
This is the shared definition of "good test" that every flagrare skill which proposes or reviews tests leans on. It distils Kent Dodds' testing writing and generalizes it past his JS/React context to any language and any layer. (Grounded in [`docs/research/2026-06-11-kent-dodds-testing-philosophy.md`](../../../../docs/research/2026-06-11-kent-dodds-testing-philosophy.md).)
The one principle
> **The more your tests resemble the way your software is used, the more confidence they can give you.** (Kent C. Dodds)
Every rule below is a corollary. The principle is already language- and layer-agnostic; "the way your software is used" just resolves to a different surface in each context. When a testing decision is unclear, return to this sentence.
Pillar 1: Behavior over implementation details
An **implementation detail** is anything *"users of your code will not typically use, see, or even know about."* A test bound to one fails in both directions at once:
- **False negative on refactor**: you change internals without changing behavior, and the test breaks anyway. It cries wolf.
- **False positive on breakage**: you break the actual behavior, and the test stays green because it was watching the mechanism, not the result.
Dodds' framing: a test that drives your code differently from how real users drive it becomes *a third user you never wanted*, now you have to keep the end user, the calling developer, **and** the test happy.
**"User" generalizes by layer.** Assert only on what *that* user can observe; drive the code only through the surface *that* user touches:
| Layer | The user | Assert on (observable) | Do NOT touch (implementation) | |---|---|---|---| | Library / module | the calling developer | return values, thrown errors, public types, emitted events | private fields/methods, internal helpers, internal data-structure choices | | Backend / API | the HTTP/RPC client | status codes, response bodies, headers, state visible *through* the API, domain events | ORM internals, service method names, query shapes, internal DTOs | | Frontend / UI | the person clicking | rendered text, roles, what appears/disappears after an interaction | component state vars, hook internals, CSS class names, child-component names | | CLI | the person at the prompt | stdout/stderr, exit code, files written | internal flag parsing, function call order |
**Concrete tells of an implementation-detail test** (stack-independent, flag any of these):
- Asserts on private fields, unexported functions, internal state, or internal data-structure shape.
- Asserts a particular internal function/method *was called*, spy / mock-call-count assertions on a collaborator **you own**.
- Mocks a collaborator you own, rather than mocking only at a true external boundary (network, disk, clock, OS process, third-party service).
- Its name describes a mechanism (`calls setIndex with 0`) instead of a behavior (`shows the first slide on load`).
**The acid test:** *"If I refactor the internals but keep the public contract identical, does this test break?"* If yes, it tests the wrong thing. Pair it with: *"Does this assert what a real user observes?"* If no, same problem.
Pillar 2: The Testing Trophy, and the e2e floor
Four layers, bottom to top. Height is **confidence**; height is also **cost/time**. Testing is "return on investment where return is confidence and investment is time."
| Layer | What it is | Mock how much | |---|---|---| | **Static** | types + lint, correctness for free | n/a | | **Unit** | one piece in isolation | dependencies mocked | | **Integration** | several units working together, **the default tier** | mock only external boundaries | | **E2E** | the whole assembled system | "as little as possible" |
"Write tests. Not too many. **Mostly integration**" puts most effort in the middle, because that's the best confidence-per-effort and most regressions live *between* units, not inside them.
**The correction that matters: "mostly integration" is not "skip e2e."** There are two opposite violations, and most reviews only catch the first:
1. **Too much e2e**: every scenario duplicated as a slow, flaky full-stack test that could be an integration test. Flag it; push it down the trophy. 2. **No e2e at all for the critical path**: every layer tested in isolation, but nothing proves they connect. This is the quieter, more common gap. Flag it just as hard.
**The e2e necessity rule:** *every user-facing feature needs at least one end-to-end (or highest-practical) test that exercises its critical happy path through the real, assembled system*, one or two paths, not one per scenario. The e2e tier proves the wiring; integration proves the behavior; unit proves the tricky pure logic; static proves the shapes. A plan or a diff that has unit + integration coverage but no wiring proof for a user-facing feature **has a gap**.
**E2e does not require a browser**: it generalizes:
| Surface | What "e2e" means | |---|---| | Frontend app | browser-driven test of the critical journey: load → act → see the result | | Backend service | hit the running service over HTTP against a real (test) DB; assert response + persisted state | | CLI | invoke the built binary as a subprocess; assert stdout / exit code / files written | | Library | consume the published public API exactly as a downstream user would, nothing internal stubbed |
Read more
name: testing-philosophy description: "Use when proposing, writing, or reviewing automated tests, defines what a good test is: behavior over implementation details, and the Testing Trophy with a hard floor on end-to-end coverage for user-facing features. Generalized to any language and any layer (frontend, backend, CLI, library), not just JS/React. REQUIRED BACKGROUND for skills that plan or review tests, atdd-plan, implementation-review, tdd-writer, wrap-up. Use when the user asks whether tests are good, what to test, why a test is brittle, or whether e2e is needed."
Testing philosophy
This is the shared definition of "good test" that every flagrare skill which proposes or reviews tests leans on. It distils Kent Dodds' testing writing and generalizes it past his JS/React context to any language and any layer. (Grounded in [`docs/research/2026-06-11-kent-dodds-testing-philosophy.md`](../../../../docs/research/2026-06-11-kent-dodds-testing-philosophy.md).)
The one principle
> **The more your tests resemble the way your software is used, the more confidence they can give you.** (Kent C. Dodds)
Every rule below is a corollary. The principle is already language- and layer-agnostic; "the way your software is used" just resolves to a different surface in each context. When a testing decision is unclear, return to this sentence.
Pillar 1: Behavior over implementation details
An **implementation detail** is anything *"users of your code will not typically use, see, or even know about."* A test bound to one fails in both directions at once:
- **False negative on refactor**: you change internals without changing behavior, and the test breaks anyway. It cries wolf.
- **False positive on breakage**: you break the actual behavior, and the test stays green because it was watching the mechanism, not the result.
Dodds' framing: a test that drives your code differently from how real users drive it becomes *a third user you never wanted*, now you have to keep the end user, the calling developer, **and** the test happy.
**"User" generalizes by layer.** Assert only on what *that* user can observe; drive the code only through the surface *that* user touches:
| Layer | The user | Assert on (observable) | Do NOT touch (implementation) | |---|---|---|---| | Library / module | the calling developer | return values, thrown errors, public types, emitted events | private fields/methods, internal helpers, internal data-structure choices | | Backend / API | the HTTP/RPC client | status codes, response bodies, headers, state visible *through* the API, domain events | ORM internals, service method names, query shapes, internal DTOs | | Frontend / UI | the person clicking | rendered text, roles, what appears/disappears after an interaction | component state vars, hook internals, CSS class names, child-component names | | CLI | the person at the prompt | stdout/stderr, exit code, files written | internal flag parsing, function call order |
**Concrete tells of an implementation-detail test** (stack-independent, flag any of these):
- Asserts on private fields, unexported functions, internal state, or internal data-structure shape.
- Asserts a particular internal function/method *was called*, spy / mock-call-count assertions on a collaborator **you own**.
- Mocks a collaborator you own, rather than mocking only at a true external boundary (network, disk, clock, OS process, third-party service).
- Its name describes a mechanism (`calls setIndex with 0`) instead of a behavior (`shows the first slide on load`).
**The acid test:** *"If I refactor the internals but keep the public contract identical, does this test break?"* If yes, it tests the wrong thing. Pair it with: *"Does this assert what a real user observes?"* If no, same problem.
Pillar 2: The Testing Trophy, and the e2e floor
Four layers, bottom to top. Height is **confidence**; height is also **cost/time**. Testing is "return on investment where return is confidence and investment is time."
| Layer | What it is | Mock how much | |---|---|---| | **Static** | types + lint, correctness for free | n/a | | **Unit** | one piece in isolation | dependencies mocked | | **Integration** | several units working together, **the default tier** | mock only external boundaries | | **E2E** | the whole assembled system | "as little as possible" |
"Write tests. Not too many. **Mostly integration**" puts most effort in the middle, because that's the best confidence-per-effort and most regressions live *between* units, not inside them.
**The correction that matters: "mostly integration" is not "skip e2e."** There are two opposite violations, and most reviews only catch the first:
1. **Too much e2e**: every scenario duplicated as a slow, flaky full-stack test that could be an integration test. Flag it; push it down the trophy. 2. **No e2e at all for the critical path**: every layer tested in isolation, but nothing proves they connect. This is the quieter, more common gap. Flag it just as hard.
**The e2e necessity rule:** *every user-facing feature needs at least one end-to-end (or highest-practical) test that exercises its critical happy path through the real, assembled system*, one or two paths, not one per scenario. The e2e tier proves the wiring; integration proves the behavior; unit proves the tricky pure logic; static proves the shapes. A plan or a diff that has unit + integration coverage but no wiring proof for a user-facing feature **has a gap**.
**E2e does not require a browser**: it generalizes:
| Surface | What "e2e" means | |---|---| | Frontend app | browser-driven test of the critical journey: load → act → see the result | | Backend service | hit the running service over HTTP against a real (test) DB; assert response + persisted state | | CLI | invoke the built binary as a subprocess; assert stdout / exit code / files written | | Library | consume the published public API exactly as a downstream user would, nothing internal stubbed |
Showing the first part of this file.
Thirty-two skills that wrap around your development cycle in Claude Code. They turn tickets into ATDD plans, smoke-test features against a running app or service, hunt down bugs with runtime evidence, guard commits against doc drift, run seven-axis code
Repo: Flagrare/agent-skills
Other skills on flagrare-agent-skills.
- /atdd-plan
Produce an ATDD-first implementation plan in Claude Code's native plan mode, with named design patterns called out where they earn their keep. The skill enters plan mode automatically (via the EnterPlanMode tool), runs /flagrare:codebase-explore to ground the plan in the actual
Open skill - /brag-doc
Generate a comprehensive, impact-framed brag-doc entry for a chosen time window (day, week, biweek, month, or custom). Pulls authored PRs, reviews given, commits, deploys, and linked tickets across GitHub, local git, and configured MCPs, then synthesises a themed narrative,
Open skill - /bug-bash
Programmatic bug bashing, ingest a prescribed test plan (Notion, markdown, pasted spec), drive a real running system (browser via Chrome DevTools / Playwright MCP, backend via API tools when relevant), run every prescribed case with evidence, then do exploratory passes
Open skill - /codebase-explore
Explore the codebase to map conventions, reusable utilities, analogous features, and data flows relevant to a planned change. Returns raw findings (file paths, patterns, code snippets), does NOT produce a plan. Used by /flagrare:atdd-plan as its codebase understanding step.
Open skill - /daily-code-review
Generate a daily code review report showing stale PRs, items needing your attention, and active work for your team. Use whenever the user asks for a PR report, code review status, daily standup prep, team PR overview, "what needs review", "what's stale", "show me open PRs",
Open skill - /debug-hunt
Evidence-first debugging for bugs that are hard to reproduce, intermittent, performance-related, or where previous static-analysis fixes have failed. Declares an explicit goal via /goal (the bug no longer reproduces), then loops through Hypothesis → Instrument → Reproduce →
Open skill

