TDD guidance for writing tests, using test doubles, and ensuring high code coverage.

Install

mkdir -p .claude/skills/tdd-kennedym-ds && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/18735" && unzip -o skill.zip -d .claude/skills/tdd-kennedym-ds && rm skill.zip

Installs to .claude/skills/tdd-kennedym-ds

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

TDD patterns for Red-Green-Refactor cycles, unit/integration testing, test doubles, and coverage analysis. Use for writing tests before implementation and validating code changes.
179 chars✓ has a “when” trigger
Beginner

Key capabilities

  • Implement new features using TDD
  • Fix bugs with reproducible test cases
  • Refactor existing code with a safety net
  • Establish baseline test coverage
  • Validate edge cases and error handling
  • Apply Red-Green-Refactor cycle

How it works

The process involves writing a failing test (Red), implementing minimal code to make the test pass (Green), and then improving the code quality while ensuring tests still pass (Refactor).

Inputs & outputs

You give it
A new feature, bug, or code to refactor
You get back
Implemented code with passing tests and improved quality

When to use tdd

  • Write unit tests first
  • Create mocks and stubs
  • Improve test coverage
  • Refactor code with test validation

About this skill

Test-Driven Development (TDD)

Provides TDD patterns for writing tests before implementation, following Red-Green-Refactor cycle, and achieving comprehensive test coverage.

Description

This skill teaches implementer and test agents how to apply Test-Driven Development principles: write failing tests first (Red), implement minimal code to pass (Green), then refactor for quality (Refactor). It covers unit testing, integration testing, test doubles (mocks/stubs), and coverage analysis.

When to Use

  • Implementing new features or functions
  • Fixing bugs with reproducible test cases
  • Refactoring existing code with safety net
  • Establishing baseline test coverage
  • Validating edge cases and error handling

When NOT to Use

  • Do not use for documentation-only changes or configuration updates with no testable behavior.
  • Do not use for exploratory debugging where the problem is not yet understood — use the researcher or rubber-duck agent first.

Entry Points

Trigger Phrases: "write tests first", "TDD approach", "test coverage", "unit tests", "integration tests", "test this function"

Context Patterns: New feature implementation, bug fixes, refactoring tasks, code review with missing tests

Core Knowledge

Red-Green-Refactor Cycle

1. Red (Write Failing Test)

# test_calculator.py
def test_add_positive_numbers():
    calc = Calculator()
    result = calc.add(2, 3)
    assert result == 5  # FAILS: Calculator not implemented

def test_add_negative_numbers():
    calc = Calculator()
    result = calc.add(-2, -3)
    assert result == -5  # FAILS

2. Green (Minimal Implementation)

# calculator.py
class Calculator:
    def add(self, a, b):
        return a + b  # Simplest code that passes tests

3. Refactor (Improve Code Quality)

# calculator.py
class Calculator:
    """Performs basic arithmetic operations."""

    def add(self, a: float, b: float) -> float:
        """Add two numbers and return result."""
        return a + b  # No refactoring needed (already simple)

Test Pyramid

         /\
        /  \  E2E Tests (Few, Slow, High Value)
       /____\
      /      \
     / Integration Tests (Some, Medium Speed)
    /________\
   /          \
  / Unit Tests (Many, Fast, Focused)
 /______________\

Unit Tests (70%): Test individual functions/methods in isolation Integration Tests (20%): Test component interactions (DB, API, services) E2E Tests (10%): Test complete user workflows through UI

Test Doubles

TypePurposeExample
StubReturns fixed datagetUserStub() returns { id: 1, name: 'Test' }
MockVerifies interactionsAssert sendEmail() called once with correct args
SpyRecords invocationsTrack how many times logger.info() called
FakeSimplified implementationIn-memory database for tests

Coverage Metrics

Line Coverage: % of code lines executed during tests Branch Coverage: % of if/else branches exercised Function Coverage: % of functions called Target: ≥80% line coverage, ≥70% branch coverage for new code

TDD Patterns

Pattern 1: Arrange-Act-Assert (AAA)

test('user registration creates account', async () => {
  // Arrange: Set up test data and preconditions
  const userData = { email: '[email protected]', password: 'secret123' };

  // Act: Execute the code under test
  const user = await registerUser(userData);

  // Assert: Verify expected outcomes
  expect(user.id).toBeDefined();
  expect(user.email).toBe('[email protected]');
  expect(user.password).not.toBe('secret123'); // Should be hashed
});

Pattern 2: Test Edge Cases

def test_divide():
    # Happy path
    assert divide(10, 2) == 5

    # Edge cases
    assert divide(0, 5) == 0  # Zero numerator
    assert divide(7, 3) == 2.333  # Float result

    # Error cases
    with pytest.raises(ZeroDivisionError):
        divide(10, 0)  # Division by zero

Pattern 3: Parameterized Tests

@pytest.mark.parametrize("input,expected", [
    ("hello", "HELLO"),
    ("WORLD", "WORLD"),
    ("", ""),
    ("123", "123"),
])
def test_to_uppercase(input, expected):
    assert to_uppercase(input) == expected

Examples

Example: TDD for API Endpoint

Phase 1: Red (Failing Tests)

// tests/api/users.test.js
describe('POST /api/users', () => {
  it('creates new user with valid data', async () => {
    const res = await request(app)
      .post('/api/users')
      .send({ name: 'John', email: '[email protected]' });

    expect(res.status).toBe(201);
    expect(res.body.user.name).toBe('John');
    expect(res.body.user.id).toBeDefined();
  });

  it('returns 400 for missing email', async () => {
    const res = await request(app)
      .post('/api/users')
      .send({ name: 'John' });

    expect(res.status).toBe(400);
    expect(res.body.error).toContain('email');
  });
});

// ❌ Tests FAIL: /api/users endpoint doesn't exist

Phase 2: Green (Minimal Implementation)

// routes/users.js
app.post('/api/users', async (req, res) => {
  const { name, email } = req.body;

  if (!email) {
    return res.status(400).json({ error: 'email is required' });
  }

  const user = await db.users.create({ name, email });
  res.status(201).json({ user });
});

// ✅ Tests PASS

Phase 3: Refactor (Improve Quality)

// routes/users.js
const { body, validationResult } = require('express-validator');

app.post('/api/users',
  // Validation middleware
  body('email').isEmail().normalizeEmail(),
  body('name').trim().isLength({ min: 1, max: 100 }),

  async (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      return res.status(400).json({ errors: errors.array() });
    }

    const { name, email } = req.body;

    try {
      const user = await db.users.create({ name, email });
      res.status(201).json({ user: sanitizeUser(user) });
    } catch (err) {
      if (err.code === 'UNIQUE_VIOLATION') {
        return res.status(409).json({ error: 'Email already exists' });
      }
      throw err;
    }
  }
);

// ✅ Tests still PASS, code quality improved

Bundled References

References

  • Testing Frameworks: Jest, Pytest, Mocha, RSpec
  • Coverage Tools: nyc, coverage.py, SimpleCov
  • Test Agent: .github/agents/test.agent.md
  • .github/agents/implementer.agent.md — implementation workflow that applies strict TDD discipline
  • instructions/workflows/implementer.instructions.md — tests-first execution guardrails for implementer tasks

When not to use it

  • For documentation-only changes or configuration updates with no testable behavior
  • For exploratory debugging where the problem is not yet understood

Limitations

  • Does not apply to documentation-only changes
  • Not for exploratory debugging

How it compares

This skill provides a structured, iterative approach to development that prioritizes testing before implementation, ensuring code quality and preventing regressions.

Compared to similar skills

tdd side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
tdd (this skill)03moNo flagsBeginner
python-testing-patterns772moReviewIntermediate
pr-review61moReviewIntermediate
pytest86moReviewIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

Search skills

Search the agent skills registry