Superpowers Test Driven Development
christopherarter/superpowers-reasonix
Writing or fixing any code?. An agent skill from christopherarter/superpowers-reasonix.
A skill your agent uses when writing production code. An agent skill from MadAppGang/claude-code.
$ npx skills add MadAppGang/claude-code --skill test-driven-development -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install MadAppGang/claude-code test-driven-development --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/MadAppGang/claude-code.git skills-src && mkdir -p .claude/skills && cp -r skills-src/plugins/dev/skills/discipline/test-driven-development .claude/skills/test-driven-development && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "test-driven-development" agent skill from https://github.com/MadAppGang/claude-code/tree/main/plugins/dev/skills/discipline/test-driven-development into .claude/skills/test-driven-development/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "test-driven-development", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/MadAppGang/claude-code/tree/main/plugins/dev/skills/discipline/test-driven-developmentType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add MadAppGang/claude-code --skill test-driven-development -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install MadAppGang/claude-code test-driven-development --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/MadAppGang/claude-code.git skills-src && mkdir -p .agents/skills && cp -r skills-src/plugins/dev/skills/discipline/test-driven-development .agents/skills/test-driven-development && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "test-driven-development" agent skill from https://github.com/MadAppGang/claude-code/tree/main/plugins/dev/skills/discipline/test-driven-development into .agents/skills/test-driven-development/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "test-driven-development", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add MadAppGang/claude-code --skill test-driven-development -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install MadAppGang/claude-code test-driven-development --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/MadAppGang/claude-code.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/plugins/dev/skills/discipline/test-driven-development .cursor/skills/test-driven-development && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "test-driven-development" agent skill from https://github.com/MadAppGang/claude-code/tree/main/plugins/dev/skills/discipline/test-driven-development into .cursor/skills/test-driven-development/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "test-driven-development", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/MadAppGang/claude-code.git --path plugins/dev/skills/discipline/test-driven-development--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add MadAppGang/claude-code --skill test-driven-development -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install MadAppGang/claude-code test-driven-development --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/MadAppGang/claude-code.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/plugins/dev/skills/discipline/test-driven-development .gemini/skills/test-driven-development && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "test-driven-development" agent skill from https://github.com/MadAppGang/claude-code/tree/main/plugins/dev/skills/discipline/test-driven-development into .gemini/skills/test-driven-development/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "test-driven-development", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install MadAppGang/claude-code test-driven-developmentInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add MadAppGang/claude-code --skill test-driven-development -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/MadAppGang/claude-code.git skills-src && mkdir -p .github/skills && cp -r skills-src/plugins/dev/skills/discipline/test-driven-development .github/skills/test-driven-development && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "test-driven-development" agent skill from https://github.com/MadAppGang/claude-code/tree/main/plugins/dev/skills/discipline/test-driven-development into .github/skills/test-driven-development/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "test-driven-development", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add MadAppGang/claude-code --skill test-driven-development -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install MadAppGang/claude-code test-driven-development --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/MadAppGang/claude-code.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/plugins/dev/skills/discipline/test-driven-development .opencode/skills/test-driven-development && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "test-driven-development" agent skill from https://github.com/MadAppGang/claude-code/tree/main/plugins/dev/skills/discipline/test-driven-development into .opencode/skills/test-driven-development/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "test-driven-development", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
test-driven-developmentA skill your agent uses when writing production code. An agent skill from MadAppGang/claude-code.
Test Driven Development is an agent skill from MadAppGang/claude-code. Use when writing production code. Enforces RED-GREEN-REFACTOR cycle: write failing test, make it pass, improve design. Prevents test-after development and ensures verified behavior.
Its SKILL.md is about 4.1k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Testing & QA, covering Test-driven development and Failing and flaky tests. The repository describes itself as: claude code plugins marketplace. The licence is MIT.
3 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit 6097ad4. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are typescript, python and go).
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Test Driven Development loads about 4.1k tokens when it runs. Until then it costs about 51 tokens; SKILL.md has 919 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from MadAppGang/claude-code at commit 6097ad4, republished under its MIT licence (© MadAppGang). 919 words, ~4,081 tokens.
.claude/skills/test-driven-development/SKILL.md (or your agent's skills folder).Iron Law: "NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST"
Use this skill when:
Watch for these patterns that indicate TDD violations:
Violation Detection: If you find yourself saying "I'll test this after I get it working," you're violating TDD.
TDD follows a strict 3-phase workflow:
Objective: Specify desired behavior through a test that fails
Steps:
Example (TypeScript/Jest):
// tests/user-validator.test.ts
describe('UserValidator', () => {
it('rejects email without @ symbol', () => {
const validator = new UserValidator();
const result = validator.validateEmail('invalid-email');
expect(result.isValid).toBe(false);
expect(result.error).toBe('Email must contain @ symbol');
});
});
// Run: npm test
// Result: FAIL - UserValidator is not defined ✓ (correct failure)Red Phase Complete When: Test fails with expected error message
Objective: Write minimal code to make test pass
Steps:
Example (TypeScript):
// src/user-validator.ts
interface ValidationResult {
isValid: boolean;
error?: string;
}
export class UserValidator {
validateEmail(email: string): ValidationResult {
if (!email.includes('@')) {
return { isValid: false, error: 'Email must contain @ symbol' };
}
return { isValid: true };
}
}
// Run: npm test
// Result: PASS ✓Green Phase Complete When: Test passes consistently
Objective: Improve code quality while keeping tests green
Steps:
Example (TypeScript - Refactored):
// src/user-validator.ts
interface ValidationResult {
isValid: boolean;
error?: string;
}
export class UserValidator {
private static readonly EMAIL_REQUIRED_CHARS = '@';
private static readonly EMAIL_ERROR = 'Email must contain @ symbol';
validateEmail(email: string): ValidationResult {
if (!this.containsRequiredChars(email)) {
return this.createError(UserValidator.EMAIL_ERROR);
}
return this.createSuccess();
}
private containsRequiredChars(email: string): boolean {
return email.includes(UserValidator.EMAIL_REQUIRED_CHARS);
}
private createError(message: string): ValidationResult {
return { isValid: false, error: message };
}
private createSuccess(): ValidationResult {
return { isValid: true };
}
}
// Run: npm test
// Result: PASS ✓ (behavior unchanged)Refactor Phase Complete When: Code is clean AND tests still pass
| Anti-pattern | ✗ Wrong Approach | ✓ Correct TDD Approach |
|---|---|---|
| Test-After | Write calculateTotal() function, then write tests | Write test for calculateTotal(), see it fail, implement function |
| Empty Tests | Write test that always passes: expect(true).toBe(true) | Write test that fails until production code is correct |
| Happy-Path-Only | Test only valid inputs: validateEmail('user@example.com') | Test invalid inputs too: validateEmail('no-at-sign'), validateEmail('') |
| Skip-Simple | Skip test for "obvious" add(a, b) { return a + b } | Write test: expect(add(2, 3)).toBe(5) - bugs hide in "simple" code |
| Change-Then-Test | Modify calculateDiscount(), run app manually, then add test | Write failing test showing bug, modify code until test passes |
Pattern: 1 happy path + 3 edge cases minimum
Example (TypeScript):
describe('calculateDiscount', () => {
it('applies 10% discount to $100 purchase', () => {
expect(calculateDiscount(100, 0.1)).toBe(90);
});
it('returns 0 for negative amounts', () => {
expect(calculateDiscount(-50, 0.1)).toBe(0);
});
it('returns original amount for 0 discount', () => {
expect(calculateDiscount(100, 0)).toBe(100);
});
it('throws error for discount > 1', () => {
expect(() => calculateDiscount(100, 1.5)).toThrow('Discount must be <= 1');
});
});Pattern: 1 test per error type + 1 success case
Example (Python/pytest):
def test_divide_by_zero_raises_error():
with pytest.raises(ZeroDivisionError, match="Cannot divide by zero"):
divide(10, 0)
def test_divide_non_numeric_raises_error():
with pytest.raises(TypeError, match="Arguments must be numbers"):
divide("10", 5)
def test_divide_returns_float():
result = divide(10, 3)
assert result == pytest.approx(3.333, rel=1e-3)Pattern: 1 render test + 3 interaction tests
Example (TypeScript/React Testing Library):
describe('LoginForm', () => {
it('renders email and password inputs', () => {
render(<LoginForm />);
expect(screen.getByLabelText('Email')).toBeInTheDocument();
expect(screen.getByLabelText('Password')).toBeInTheDocument();
});
it('shows error for invalid email', async () => {
render(<LoginForm />);
await userEvent.type(screen.getByLabelText('Email'), 'invalid');
await userEvent.click(screen.getByRole('button', { name: 'Login' }));
expect(screen.getByText('Invalid email address')).toBeInTheDocument();
});
it('disables submit button while loading', async () => {
render(<LoginForm onSubmit={async () => await delay(1000)} />);
const submitButton = screen.getByRole('button', { name: 'Login' });
await userEvent.click(submitButton);
expect(submitButton).toBeDisabled();
});
it('calls onSubmit with form data', async () => {
const onSubmit = jest.fn();
render(<LoginForm onSubmit={onSubmit} />);
await userEvent.type(screen.getByLabelText('Email'), 'user@example.com');
await userEvent.type(screen.getByLabelText('Password'), 'password123');
await userEvent.click(screen.getByRole('button', { name: 'Login' }));
expect(onSubmit).toHaveBeenCalledWith({
email: 'user@example.com',
password: 'password123'
});
});
});Pattern: 1 success test + 2 error tests
Example (Go/testing):
func TestGetUser(t *testing.T) {
t.Run("returns user for valid ID", func(t *testing.T) {
req := httptest.NewRequest("GET", "/users/123", nil)
w := httptest.NewRecorder()
handler := NewUserHandler(mockUserRepo)
handler.GetUser(w, req)
assert.Equal(t, http.StatusOK, w.Code)
assert.Contains(t, w.Body.String(), `"id":"123"`)
})
t.Run("returns 404 for non-existent user", func(t *testing.T) {
req := httptest.NewRequest("GET", "/users/999", nil)
w := httptest.NewRecorder()
handler := NewUserHandler(mockUserRepo)
handler.GetUser(w, req)
assert.Equal(t, http.StatusNotFound, w.Code)
})
t.Run("returns 400 for invalid ID format", func(t *testing.T) {
req := httptest.NewRequest("GET", "/users/invalid", nil)
w := httptest.NewRecorder()
handler := NewUserHandler(mockUserRepo)
handler.GetUser(w, req)
assert.Equal(t, http.StatusBadRequest, w.Code)
})
}Scenario: User reports: "App crashes when searching with empty query"
Step 1 (RED): Write test that reproduces bug
// tests/search.test.ts
describe('searchProducts', () => {
it('returns empty array for empty query', () => {
const result = searchProducts('');
expect(result).toEqual([]);
});
});
// Run: npm test
// Result: FAIL - TypeError: Cannot read property 'toLowerCase' of undefinedStep 2 (GREEN): Fix the bug
// src/search.ts
export function searchProducts(query: string): Product[] {
if (!query || query.trim() === '') {
return [];
}
return products.filter(p => p.name.toLowerCase().includes(query.toLowerCase()));
}
// Run: npm test
// Result: PASS ✓Step 3 (REFACTOR): Add more edge cases
describe('searchProducts', () => {
it('returns empty array for empty query', () => {
expect(searchProducts('')).toEqual([]);
});
it('returns empty array for whitespace-only query', () => {
expect(searchProducts(' ')).toEqual([]);
});
it('is case-insensitive', () => {
expect(searchProducts('LAPTOP')).toHaveLength(3);
});
});Scenario: Add email validation to user registration
Step 1 (RED): Write test for feature that doesn't exist
# tests/test_user.py
def test_user_creation_validates_email():
with pytest.raises(ValidationError, match="Invalid email format"):
User.create(email="not-an-email", password="secret123")
# Run: pytest
# Result: FAIL - ValidationError not raisedStep 2 (GREEN): Implement validation
# src/user.py
import re
class ValidationError(Exception):
pass
class User:
@classmethod
def create(cls, email: str, password: str):
if not re.match(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$', email):
raise ValidationError("Invalid email format")
return cls(email, password)
# Run: pytest
# Result: PASS ✓Step 3 (REFACTOR): Extract validation logic
# src/validators.py
class EmailValidator:
PATTERN = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
@classmethod
def validate(cls, email: str) -> bool:
return bool(re.match(cls.PATTERN, email))
# src/user.py
class User:
@classmethod
def create(cls, email: str, password: str):
if not EmailValidator.validate(email):
raise ValidationError("Invalid email format")
return cls(email, password)
# Run: pytest
# Result: PASS ✓ (behavior unchanged)Scenario: Implement POST /api/orders endpoint
Step 1 (RED): Write test for non-existent endpoint
// handlers/orders_test.go
func TestCreateOrder(t *testing.T) {
t.Run("creates order with valid data", func(t *testing.T) {
payload := `{"user_id": "123", "items": [{"product_id": "456", "quantity": 2}]}`
req := httptest.NewRequest("POST", "/api/orders", strings.NewReader(payload))
w := httptest.NewRecorder()
handler := NewOrderHandler(mockOrderRepo)
handler.CreateOrder(w, req)
assert.Equal(t, http.StatusCreated, w.Code)
assert.Contains(t, w.Body.String(), `"order_id"`)
})
}
// Run: go test
// Result: FAIL - handler.CreateOrder undefinedStep 2 (GREEN): Implement handler
// handlers/orders.go
func (h *OrderHandler) CreateOrder(w http.ResponseWriter, r *http.Request) {
var req CreateOrderRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "Invalid request", http.StatusBadRequest)
return
}
order, err := h.orderRepo.Create(req.UserID, req.Items)
if err != nil {
http.Error(w, "Failed to create order", http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(map[string]string{"order_id": order.ID})
}
// Run: go test
// Result: PASS ✓Step 3 (REFACTOR): Add error handling tests
func TestCreateOrder(t *testing.T) {
t.Run("creates order with valid data", func(t *testing.T) {
// ... existing test
})
t.Run("returns 400 for invalid JSON", func(t *testing.T) {
req := httptest.NewRequest("POST", "/api/orders", strings.NewReader("invalid"))
w := httptest.NewRecorder()
handler.CreateOrder(w, req)
assert.Equal(t, http.StatusBadRequest, w.Code)
})
t.Run("returns 400 for missing user_id", func(t *testing.T) {
payload := `{"items": [{"product_id": "456", "quantity": 2}]}`
req := httptest.NewRequest("POST", "/api/orders", strings.NewReader(payload))
w := httptest.NewRecorder()
handler.CreateOrder(w, req)
assert.Equal(t, http.StatusBadRequest, w.Code)
})
}This skill integrates with:
Objection: "TDD is too slow, I can code faster without tests" Response: Writing tests first actually saves time by catching bugs early. Debugging later is far more expensive than preventing bugs upfront.
Objection: "This code is too simple to test" Response: Simple code is fastest to test. If it's truly simple, the test takes 30 seconds. If you can't write a fast test, the code isn't simple.
Objection: "I'll write tests after I figure out the design" Response: Tests ARE the design. Writing tests first forces you to think about API usability before implementation locks you in.
Objection: "I need to see if my approach works before committing to tests" Response: That's what the RED phase is for - write a test describing your desired approach, then implement it. If approach changes, update test first.
Core Principle: Tests first, code second, refactor third.
Workflow:
Benefits:
Remember: If you wrote production code without a failing test first, you violated TDD. Delete the code and start over with a test.
© MadAppGang, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in plugins/dev/skills/discipline/test-driven-development of MadAppGang/claude-code.
Open the folder on GitHubat commit 6097ad4
Test Driven Development next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Test Driven Development this skillMadAppGang/claude-code | 284 | — | ~4.1k | Automated safety check: Pass | MIT | |
| Superpowers Test Driven Developmentchristopherarter/superpowers-reasonix | 102 | — | ~1.9k | Automated safety check: Pass | MIT | |
| Openspec Plus TDDelastic/terraform-provider-elasticstack | 210 | 1 repos | ~4.7k | Automated safety check: Pass | Apache-2.0 | |
| Fix BugMelbourneDeveloper/dart_node | 113 | 1 repos | ~709 | Automated safety check: Notes | None | |
| Evanflow Debugevanklem/evanflow | 418 | — | ~760 | Automated safety check: Pass | Custom licence | |
| TDDcodeaholicguy/ai-devkit | 1.6k | — | ~838 | Automated safety check: Pass | Apache-2.0 |
christopherarter/superpowers-reasonix
Writing or fixing any code?. An agent skill from christopherarter/superpowers-reasonix.
elastic/terraform-provider-elasticstack
MANDATORY skill that activates whenever code is written to implement an OpenSpec change task.
MelbourneDeveloper/dart_node
Fix a bug using test-driven development. An agent skill from MelbourneDeveloper/dart_node.
evanklem/evanflow
Root-cause discipline for bugs, test failures, and unexpected behavior.
codeaholicguy/ai-devkit
AI DevKit · Test-driven development — write a failing test before writing production code.
aiskillstore/marketplace
Implement the minimal code needed to make failing tests pass in the TDD green phase.
MadAppGang/claude-code
Analyzes API documentation from OpenAPI specs to provide TypeScript interfaces, request/response formats, and implementation guidance.
MadAppGang/claude-code
Content brief template and creation methodology for SEO-optimized content.
MadAppGang/claude-code
A skill your agent uses when detecting project technology stack from files/configs/directory structure, auto-loading framework-specific skills, or analyzing multi-stack fullstack projects (e.g…
MadAppGang/claude-code
On-page SEO optimization techniques including keyword density, meta tags, heading structure, and readability.
MadAppGang/claude-code
Techniques for expanding seed keywords and clustering by topic and intent.
MadAppGang/claude-code
SERP analysis techniques for intent classification, feature identification, and competitive intelligence.
Categories
A skill your agent uses when writing production code. An agent skill from MadAppGang/claude-code. Test Driven Development is an agent skill from MadAppGang/claude-code. Use when writing production code.
Test Driven Development fits situations like: writing production code; tasks that involve Test-driven development; tasks that involve Failing and flaky tests.
Run `npx skills add MadAppGang/claude-code --skill test-driven-development -a claude-code`. Or copy the skill folder (plugins/dev/skills/discipline/test-driven-development in MadAppGang/claude-code) into .claude/skills/test-driven-development in your project. Claude Code loads it when a task matches its description.
Run `npx skills add MadAppGang/claude-code --skill test-driven-development -a codex`. Or copy the skill folder (plugins/dev/skills/discipline/test-driven-development in MadAppGang/claude-code) into .agents/skills/test-driven-development in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add MadAppGang/claude-code --skill test-driven-development -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/test-driven-development, .gemini/skills/test-driven-development, .github/skills/test-driven-development and .opencode/skills/test-driven-development in your project.
SKILL.md names no scripts, command-line tools or credentials: Test Driven Development is instructions for the agent only. Our summary lists: Python 3.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Test Driven Development is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 4.1k tokens (SKILL.md is roughly 16k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Test Driven Development: Superpowers Test Driven Development (christopherarter/superpowers-reasonix, 102 stars), Openspec Plus TDD (elastic/terraform-provider-elasticstack, 210 stars), Fix Bug (MelbourneDeveloper/dart_node, 113 stars) and Evanflow Debug (evanklem/evanflow, 418 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
MadAppGang (a GitHub organization) maintains it in MadAppGang/claude-code, which has 284 GitHub stars. The repository holds 69 skills in this directory. The repository was last updated on March 15, 2026.
Source: MadAppGang/claude-code on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.