agentleFS
mahsumaktasmahsumaktas/agent-evolution-kit/skills/tdd-workflow/SKILL.md

tdd-workflow

Skill2 starsChanged 9 months agoMITView on GitHub

Test-Driven Development workflow. Write tests BEFORE implementation code.

128 other projects use a version of this, 1 of them edited.

Adopted by

Most recently taken up by

Used with

Projects with it also use brand-discovery, configure-ecc and 10 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.
  • ysyecustSkill

    brand-discovery

    Use when a brand needs to discover or articulate its identity through structured multi-session interviews. Covers purpose, positioning, audience, personality, voice, narrative, and founder-brand tension across 8 modules using laddering, 5 Whys, and projective techniques. Produces a resumable session with disk-persisted state and a master brandbook (90_SYNTHESIS.md).

    Also in 6 projects that use this

  • royaluniondesign-sysSkill

    configure-ecc

    Interactive installer for Everything Claude Code — guides users through selecting and installing skills and rules to user-level or project-level directories, verifies paths, and optionally optimizes installed files.

    Also in 12 projects that use this

  • junimnjwSkill

    ralphinho-rfc-pipeline

    RFC-driven multi-agent DAG execution pattern with quality gates, merge queues, and work unit orchestration.

    Also in 12 projects that use this

  • loulanyueSkill

    nuxt4-patterns

    Nuxt 4 app patterns for hydration safety, performance, route rules, lazy loading, and SSR-safe data fetching with useFetch and useAsyncData.

    Also in 10 projects that use this

  • royaluniondesign-sysSkill

    content-hash-cache-pattern

    Cache expensive file processing results using SHA-256 content hashes — path-independent, auto-invalidating, with service layer separation.

    Also in 16 projects that use this

  • RojiosSkill

    dart-flutter-patterns

    Production-ready Dart and Flutter patterns covering null safety, immutable state, async composition, widget architecture, popular state management frameworks (BLoC, Riverpod, Provider), GoRouter navigation, Dio networking, Freezed code generation, and clean architecture.

    Also in 7 projects that use this

The file

Show its rules and text

We split this skill into the rules it gives an agent

14 rules. 0 are common, 14 are distinctive, and 0 are very specific to this project.

  • 0

    Common

    Most of the 117 edited versions we read keep these.

  • 14

    Distinctive

    This author's own choices. Worth a look.

  • 0

    Very specific

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

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Write the test first. Watch it fail.

    line 10
  2. Distinctive:

    Core principle: If you did not watch the test fail, you do not know whether you are testing the right thing.

    line 12
  3. Distinctive:

    If you are thinking "I will skip TDD just this once" — stop.

    line 29
  4. Distinctive:

    Do not keep it "for reference"

    line 40
  5. Distinctive:

    Do not "adapt" it while writing tests

    line 41
  6. Distinctive:

    Do not even look at it

    line 42
  7. Distinctive:

    Write one minimal test that shows what should happen.

    line 79
  8. Distinctive:

    Test fails (not errors)

    line 125
  9. Distinctive:

    Write the simplest code that makes the test pass.

    line 135
  10. Distinctive:

    Do not add features beyond the test.

    line 167
  11. Distinctive:

    Keep tests green. Do not add behavior.

    line 192
  12. Distinctive:

    Test-first forces you to see the test fail, proving it actually tests something.

    line 216
  13. Distinctive:

    Before marking work as complete:

    line 252
  14. Distinctive:

    Never fix a bug without a test.

    line 269

“Common” is measured: kept by at least 6 in 10 of the 117 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)

Overview

Write the test first. Watch it fail. Write the minimum code to make it pass.

Core principle: If you did not watch the test fail, you do not know whether you are testing the right thing.

Violating the letter of these rules violates their spirit.

When to Use

Always:

  • New features
  • Bug fixes
  • Refactoring
  • Behavioral changes

Exceptions (ask the user):

  • Throwaway prototypes
  • Generated code
  • Configuration files

If you are thinking "I will skip TDD just this once" — stop. That is rationalization.

Iron Rule

NO PRODUCTION CODE WITHOUT A FAILING TEST

Wrote code before the test? DELETE IT. Start over.

No exceptions:

  • Do not keep it "for reference"
  • Do not "adapt" it while writing tests
  • Do not even look at it
  • Delete means delete

Implement from scratch, starting from tests. Period.

Red-Green-Refactor Cycle

RED (Write a failing test)
  |
  v
Fails correctly? --NO--> Fix the test
  |
  YES
  |
  v
GREEN (Write minimum code)
  |
  v
All tests pass? --NO--> Fix the code
  |
  YES
  |
  v
REFACTOR (Clean up)
  |
  v
Still green? --NO--> Revert the refactor
  |
  YES
  |
  v
Next test --> Return to RED

RED -- Write a Failing Test

Write one minimal test that shows what should happen.

Good:

test('retries failed operations 3 times', async () => {
  let attemptCount = 0;
  const operation = () => {
    attemptCount++;
    if (attemptCount < 3) throw new Error('failed');
    return 'success';
  };

  const result = await retry(operation);

  expect(result).toBe('success');
  expect(attemptCount).toBe(3);
});

Clear name, tests real behavior, tests one thing.

Bad:

test('retry works', async () => {
  const mock = jest.fn()
    .mockRejectedValueOnce(new Error())
    .mockResolvedValueOnce('success');
  await retry(mock);
  expect(mock).toHaveBeenCalledTimes(2);
});

Vague name, tests the mock instead of the code.

Requirements:

  • One behavior per test
  • Clear, descriptive name
  • Real code (avoid mocks unless unavoidable)

RED Verify -- Watch It Fail

MANDATORY. Never skip.

npm test path/to/test.test.ts

Check:

  • Test fails (not errors)
  • Failure message is what you expected
  • It fails because the feature is missing (not because of a typo)

Test passes? You are testing existing behavior. Fix the test.

Test errors? Fix the error, re-run until it fails correctly.

GREEN -- Minimum Code

Write the simplest code that makes the test pass.

Good:

async function retry<T>(fn: () => Promise<T>): Promise<T> {
  for (let i = 0; i < 3; i++) {
    try {
      return await fn();
    } catch (e) {
      if (i === 2) throw e;
    }
  }
  throw new Error('unreachable');
}

Just enough to pass.

Bad:

async function retry<T>(
  fn: () => Promise<T>,
  options?: {
    maxRetries?: number;
    backoff?: 'linear' | 'exponential';
    onRetry?: (attempt: number) => void;
  }
): Promise<T> {
  // YAGNI -- do not add things that were not asked for
}

Over-engineering.

Do not add features beyond the test. Do not refactor other code. Do not "improve" anything.

GREEN Verify -- Watch It Pass

MANDATORY.

npm test path/to/test.test.ts

Check:

  • Test passes
  • Other tests still pass
  • Output is clean (no errors, no warnings)

Test fails? Fix the code, not the test. Other tests fail? Fix them now.

REFACTOR -- Clean Up

Only after green:

  • Remove duplication
  • Improve names
  • Extract helpers

Keep tests green. Do not add behavior.

Repeat

Next failing test for the next feature.

Good Tests

QualityGoodBad
MinimalTests one thing. If the name contains "and", split it.test('validates email and domain and whitespace')
ClearName describes the behaviortest('test1')
Shows intentReveals the desired APIHides what the code should do

Why Order Matters

"I will write tests afterward to verify my work"

Tests written after pass immediately. Passing immediately proves nothing:

  • You might be testing the wrong thing
  • You might be testing the implementation, not the behavior
  • You will miss edge cases you did not think of
  • You never saw the test catch an error

Test-first forces you to see the test fail, proving it actually tests something.

Common Rationalizations

ExcuseReality
"No need to test, it is too simple"Simple code breaks too. The test takes 30 seconds.
"I will test later"Tests that pass immediately prove nothing.
"Tests written after serve the same purpose"After = "what does this do?" Before = "what should it do?"
"I already tested manually"Ad-hoc is not systematic. No record, not repeatable.
"Deleting X hours of work is wasteful"Sunk cost fallacy. Keeping unverified code is technical debt.
"Keep it as reference, write test-first"You will adapt it. That is test-after in disguise. Delete means delete.
"I need to explore first"Fine. Throw away the exploration, then start with TDD.
"Test is hard = design is unclear"Listen to the test. Hard to test = hard to use.
"TDD slows me down"TDD is faster than debugging. Pragmatic = test-first.
"Manual testing is faster"Manual testing does not prove edge cases. You re-test on every change.
"Existing code has no tests"You are improving. Add tests for the code you are changing.

Red Flags -- STOP and Start Over

  • Code before test
  • Test after implementation
  • Test passes immediately
  • Cannot explain why the test fails
  • Tests added "later"
  • "Just this once" rationalization
  • "I already tested manually"
  • "Keep it as reference" or "adapt the existing code"
  • "I spent X hours, deleting is wasteful"
  • "TDD is dogmatic, I am pragmatic"
  • "This is different because..."

All of these mean: Delete the code. Restart with TDD.

Verification Checklist

Before marking work as complete:

  • Every new function/method has a test
  • I watched every test fail BEFORE implementing
  • Every test failed for the expected reason (missing feature, not typo)
  • I wrote the minimum code to make each test pass
  • All tests pass
  • Output is clean (no errors, no warnings)
  • Tests use real code (mocks only when unavoidable)
  • Edge cases and error paths are covered

Cannot check all boxes? You skipped TDD. Start over.

Debug Integration

Bug found? Write a failing test that reproduces the bug. Follow the TDD cycle. The test proves the fix and prevents regression.

Never fix a bug without a test.

REQUIRED SKILL: systematic-debugging (when the test fails unexpectedly)

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.