agentleFS
celestialdustcelestialdust/achilles-skills/skills/test-driven-development/SKILL.md

test-driven-development

Skill1 starsChanged 2 months agoMITView on GitHub

Write the failing test before the code that passes it — one behaviour per test, named for the scenario id it realizes, red, then green, then refactored. Reach for it inside a slice's build and ahead of every bug fix. Not increment sequencing (`incremental-implementation`) or grading a built slice (`quality-verification`).

190 other projects use a version of this.

Adopted by

Most recently taken up by

Used with

Projects with it also use chinese-code-review, chinese-commit-conventions and 7 more.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • Leodorareluctant259Skill

    chinese-code-review

    中文代码审查规范——在保持专业严谨的同时,用符合国内团队文化的方式给出有效反馈

    Also in 8 projects that use this

  • Leodorareluctant259Skill

    chinese-commit-conventions

    中文 Git 提交规范 — 适配国内团队的 commit message 规范和 changelog 自动化

    Also in 8 projects that use this

  • obraSkill

    diagnosing-superpowers

    Use when a superpowers session went wrong and your human partner wants to know why — repeated work, ignored plans, stumbles, poor results, a skill that didn't fire, "it took too long", "why is it so expensive", "what is it doing" — or wants to build a bug report for the superpowers maintainers, for the current session or a past one identified by id or path, on any harness.

    Also in 19 projects that use this

  • LLl0k0laDSkill

    git-workflow-and-versioning

    Use when making any code change. Use when committing, branching, resolving conflicts, or when you need to organize work across multiple parallel streams.

    Also in 47 projects that use this

  • MrCipherSmithSkill

    constraint-driven-development

    Use when a project needs a persistent, measurable quality bar — starting a project without documented standards, 'set up constraints', or when coverage/perf/a11y thresholds get re-debated per-PR. Produces CONSTRAINTS.md with enforceable numbers, ratchets, and a guard against silent weakening. NOT for throwaway prototypes or a one-off CI setup.

    Also in 15 projects that use this

  • LLl0k0laDSkill

    api-and-interface-design

    Use when designing APIs, module boundaries, or any public interface. Use when creating REST or GraphQL endpoints, defining type contracts between modules, or establishing boundaries between frontend and backend.

    Also in 49 projects that use this

  • +3 more from Leodorareluctant259

The file

We split this skill into the rules it gives an agent

1 rule. 0 are common, 0 are distinctive, and 1 is very specific to this project.

  • 0

    Common

    Most of the 178 edited versions we read keep these.

  • 0

    Distinctive

    This author's own choices. Worth a look.

  • 1

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Not sequencing the increments (incremental-implementation owns the loop this drives one turn of), nor re-cutting slices (plan-breakdown), …

    line 25

“Common” is measured: kept by at least 6 in 10 of the 178 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Test-Driven Development (TDD)

Purpose

Stage: Implement. Principles 1, 6, 7.

The test-first loop, one behaviour at a time inside a slice's build: red, green, refactor. It emits tests and the minimal code passing them into the caller's checkout — the loop incremental-implementation turns once per behaviour a slice owes.

When to use / when to skip

  • A slice's next behaviour, inside incremental-implementation's increment loop.
  • A bug fix — the reproducer first, so something proves the fix and catches its return (debugging-and-error-recovery root-causes; this writes the guard).
  • A behaviour change, a refactor of code with tests to hold it still, or a hand call — a scenario, a ticket, "make it do X" in a repository with no scaffolding.
  • Skip a throwaway prototype, generated code and configuration — none has behaviour to pin. "Too simple to test" is not on that list.
  • Not sequencing the increments (incremental-implementation owns the loop this drives one turn of), nor re-cutting slices (plan-breakdown), nor grading what was built — quality-verification exercises the scenarios cold against the running app.

Inputs

  • docs/features/<slug>/acceptance.md — helps: the Given/When/Then scenarios and the feature-namespaced ids your test names carry · without it: take the behaviours from prd.md, the prompt and the code, give each a local id, derived
  • docs/features/<slug>/plan/<slice-id>.md — helps: the behaviours this slice owes and the files holding them · without it: the slice row in plan.md, or infer it from the files the work reaches, derived
  • the test framework and runner command — helps: red and green are real runs · without it: read package.json, the tests already there or the CI config, and name the command you chose, derived
  • the caller's checkout or worktree — helps: tests and code land where the slice's commits are · without it: work in the repository and touch no board row

With a person present, ask at most three questions, and only where the gap changes which behaviours get tested rather than how one is worded.

Process

  1. One behaviour, one test, named for the scenario id it realizes — PWR-A3: retries a failed save three times. Realize the Given/When/Then by judgment in the project's own framework; there is no step-definition engine here. A name carrying "and" is two tests. The id is what lets quality-verification key its ledger by behaviour.
  2. Write it before the code it judges, and delete the production code you wrote for this behaviour ahead of its own test — code kept as reference, or adapted while the test is written, shapes that test around its own blind spots. Explore freely, then throw the exploration away and start from the test.
  3. Run it and watch it fail for the reason you predicted. A test that errors is broken rather than red: re-run until the failure message is the missing behaviour itself. One passing first time is describing something that already worked.
  4. Write the simplest code that turns it green — no options, no configuration, no second caller's needs. Assert on what the code does, never on what a mock was called with; a test needing everything mocked says the interface is too coupled, so inject the dependency or move the seam. Load references/testing-anti-patterns.md when adding a mock, a fixture or a test utility.
  5. Run it again and read the whole output — this test green, every other still green, no warnings, no stray errors. Fix the code rather than the test: a relaxed assertion buys one green run and spends the only evidence downstream has.
  6. Refactor under green — duplication out, names better, helpers extracted, no behaviour added; re-run before moving on.
  7. Repeat until the slice's list is spent, covering error and edge paths as well as the happy one and giving every new function or method a test. Record a scenario whose Given this slice cannot construct as not-reachable with its reason and carry past it — nothing stopped being checked, so it ends no slice.
  8. Change a test the plan moved past rather than test a stale thing — nothing here is frozen. Its before, its after and the reason go to the pull request and one docs/session-log.md entry, where the code-cold review meets the change inside the diff (pull-request shapes it). Only the stop list (safety-rails.md) ends a slice; the rest is a default with a reason, a log line and a Decided-for-you row.

Rationalizations

RationalizationReality
"I'll write the tests straight after"A test written after its code passes first run, having shown nothing about what it catches.
"It's already written — keep it as reference"A test shaped around existing code inherits that code's blind spots. Adapting is testing after, renamed.
"The feature works, the assertion is a bit off"Then the code is wrong — or the plan moved and the test is stale, which travels in the PR body, not into the assertion.
"Mocking everything keeps it fast and isolated"A test asserting on mock calls stays green when the product breaks and red on a correct refactor.
"This scenario can't be built yet, so drop it"not-reachable by id leaves it in the contract, unproven and visible; removing it stops something being checked.

Red flags

  • Production code in the diff that no test was ever red against.
  • A new test that passed on its first run.
  • An assertion counting mock calls where the returned value or stored row was there to assert on.
  • A test loosened, skipped or deleted to reach green, with nothing in the PR body saying so.
  • A test name carrying "and", or naming no scenario id where a contract supplies them.
  • Green reported with no runner output behind it.

Verification

  • Every behaviour this slice owes has a test that failed first for the reason predicted, passes now, and carries its scenario id.
  • Every new function or method has a test; error and edge paths are covered too.
  • The suite is green and the output pristine — no warnings, no stray errors, nothing quietly skipped.
  • Scenarios this slice could not construct are handed back not-reachable by id, with their reasons.
  • Any changed test is handed back with its before, its after and why the plan moved.
  • Every derived input is marked derived where written or handed back.

Outputs & handoff

  • Tests and the code passing them, in the caller's checkout — each named for its scenario id, each watched red before its production code existed, scoped to the files the caller named. Both ride the caller's commits; this pass opens no artifact of its own.
  • docs/session-log.md — one appended entry, cap 60 words, where this pass changed a test or settled something itself; shape in state-schema.md. Where no such file exists, hand the entry back rather than create one — project-setup owns that.
  • No STATE.md row and no gate flip — the caller owns the slice's transition (state-schema.md).
  • Returned in conversation — the red and green commands with their real output, the scenario ids proved, the not-reachable ids with reasons, the before/after of any changed test, and the log entry's measured size against its cap — an over-cap entry reported at that size, never handed on as if it fit.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.