Test-Driven Development (TDD)

SkillDev tools

Lets your agent write code test-first, running the RED-GREEN-REFACTOR cycle to build reliable, well-tested software.

Then ask your AI: use the Test-Driven Development (TDD) skill

Details

Instructions available. Your AI can read the instructions. Execution depends on the setup they require.

Add it as a step in a pipeline you build on Ahel, or connect Ahel to Claude, ChatGPT, Cursor, Claude Code or Codex and ask your AI to use it.

About this skill

Write software using the RED-GREEN-REFACTOR cycle for reliable, well-tested code

What this skill tells your AI

The instructions your AI receives, as published by taracodlabs/aiden in skills/test-driven-development/SKILL.md and read by Ahel’s review.

Use the RED-GREEN-REFACTOR cycle to write reliable, well-tested software. Write tests first, then write the minimal code to pass them, then clean up.

When to Use

  • User wants to implement a new function or module correctly
  • User wants to ensure edge cases are handled before they become bugs
  • User is refactoring and wants a safety net
  • User wants tests for business-critical logic
  • User wants to document behavior through executable tests

How to Use

The TDD cycle

RED    → Write a failing test for the behavior you want
GREEN  → Write the minimum code to make the test pass
REFACTOR → Clean up the code without breaking tests
Repeat for each small behavior increment

Phase 1: RED — Write a failing test first

Write the test before the implementation. It must fail to prove the test works.

# test_calculator.py — write this BEFORE calculator.py
import pytest
from calculator import add

def test_add_two_positive_numbers():
  assert add(2, 3) == 5

def test_add_negative_number():
  assert add(-1, 5) == 4

def test_add_floats():
  assert abs(add(0.1, 0.2) - 0.3) < 1e-9

Run the tests — they should fail with ModuleNotFoundError or ImportError:

pytest test_calculator.py -v
# Expected: FAILED (module not found)

Phase 2: GREEN — Minimal implementation to pass

Write only enough code to make the tests pass — nothing more.

# calculator.py
def add(a, b):
  return a + b
pytest test_calculator.py -v
# Expected: 3 PASSED

Phase 3: REFACTOR — Improve code quality

Clean up implementation and tests while keeping all tests green.

# calculator.py — add type hints and docstring
def add(a: float, b: float) -> float:
  """Return the sum of a and b."""
  return a + b
pytest test_calculator.py -v  # must still pass after refactor

Write tests with pytest (Python)

# Parametrize for multiple cases
@pytest.mark.parametrize("a,b,expected", [
  (2, 3, 5),
  (-1, 5, 4),
  (0, 0, 0),
  (1.5, 2.5, 4.0),
])
def test_add(a, b, expected):
  assert add(a, b) == expected

# Test exceptions
def test_add_rejects_string():
  with pytest.raises(TypeError):
    add("hello", 2)

Write tests with Vitest / Jest (TypeScript / JavaScript)

// calculator.test.ts
import { describe, it, expect } from 'vitest'
import { add } from './calculator'

describe('add()', () => {
  it('adds two positive numbers', () => {
    expect(add(2, 3)).toBe(5)
  })

  it('handles negative numbers', () => {
    expect(add(-1, 5)).toBe(4)
  })

  it('throws on non-number input', () => {
    expect(() => add('a' as any, 2)).toThrow()
  })
})

TDD for API endpoints

# test_api.py — RED first
def test_create_user_returns_201(client):
  resp = client.post("/users", json={"name": "Alice", "email": "alice@example.com"})
  assert resp.status_code == 201
  assert resp.json()["id"] is not None

def test_create_user_rejects_missing_email(client):
  resp = client.post("/users", json={"name": "Alice"})
  assert resp.status_code == 422

# Then implement the /users endpoint to make these pass

Examples

"Implement a function that validates Indian phone numbers" → RED: write tests for +91 10-digit numbers, reject 9-digit, reject letters. GREEN: implement regex. REFACTOR: add named groups, docstring.

"Add a discount calculator to the checkout module" → RED: test 10% off, 0% off, 100% off, reject negative discount. GREEN: minimal implementation. REFACTOR: extract constants, add type hints.

"I want to refactor this function but keep it working" → Write characterization tests first (tests that document current behavior), then refactor with test safety net.

Cautions

  • Never skip the RED phase — a test that was never failing might not actually test anything
  • Tests should be independent — each test must set up its own state and not depend on test order
  • Aim for one assertion per test — tests with multiple assertions are harder to diagnose when they fail
  • TDD is slower upfront but faster overall — set this expectation with the user
  • Mock external services (APIs, databases) in unit tests — test real integrations separately

Signals

GitHub stars
851
Forks
149
Last commit
Sep 2026
Advanced
Item type
skill
Key
test-driven-development-taracodlabs
Source
github.com/taracodlabs/aiden