🔥 Launch tonight — Claude Code Power Prompts PDF 50p (just 50p tonight)30 battle-tested prompts · 8-page PDF · paste into CLAUDE.md · flat 50p tonight

Claude Code Testing Workflow

Updated May 2026 · TDD, Test Generation & Debugging · Python, TypeScript, Go

Claude Code reads your entire codebase, understands your existing test patterns, and can write, fix, and debug tests fluently. This page covers the core testing workflows: generating tests for existing code, TDD (writing tests first), and debugging failing tests.

Quick Commands Reference

# Generate tests for a file
claude "write tests for src/auth.ts"

# TDD: make failing tests pass
claude "make the failing tests in auth.test.ts pass without changing the test file"

# Debug a failing test
claude "these tests are failing: $(npm test 2>&1 | tail -40). Fix the root cause."

# Generate tests for all untested files in a directory
claude "scan src/utils/ and generate test files for any functions that don't have tests yet"

# Add edge cases to existing tests
claude "look at src/auth.test.ts and add edge cases for null inputs, empty strings, and concurrent calls"

# Check test coverage and suggest what's missing
claude "review the test coverage for src/payments/ and list the most important missing test cases"

TDD Workflow with Claude Code

The red-green-refactor loop works well with Claude Code because it holds your full codebase in context and won't over-engineer implementations just to pass tests.

1

Write (or describe) the failing test

You write the test that describes the behavior you want, or ask Claude to write the test spec from a description:

claude "write a failing Jest test for a validateEmail function that:
- returns true for valid emails
- returns false for missing @ symbol
- returns false for domains without a TLD
- returns false for null/undefined input
Don't implement the function yet."
2

Confirm the test fails

Run the test suite and verify the new test fails (expected — the function doesn't exist yet):

npm test -- --testPathPattern=auth.test.ts
# → FAIL: validateEmail is not defined
3

Ask Claude to make the tests pass

claude "implement validateEmail in src/auth.ts to make the failing tests in src/auth.test.ts pass. Don't change the test file."

Claude reads the test file, understands the expected behavior, and writes the minimal implementation. It will also run the tests to verify they pass before reporting back.

4

Refactor

claude "refactor validateEmail to use a compiled regex for performance. Tests must still pass."

Generating Tests for Existing Code

TypeScript / Jest

# Basic: generate tests for one file
claude "write Jest tests for src/stripe-webhook.ts. Match the test style in src/__tests__/ (using describe/it/expect). Cover happy path, invalid signatures, and Stripe retry events."

# Claude will:
# 1. Read src/stripe-webhook.ts
# 2. Read existing tests in src/__tests__/ for style patterns
# 3. Generate src/__tests__/stripe-webhook.test.ts
# 4. Run the tests and fix any that fail

Python / Pytest

# Generate pytest tests for a module
claude "generate pytest tests for src/auth/validators.py. Use fixtures for database setup. Cover validation errors with pytest.raises. Mock external HTTP calls with responses library."

# For a Django view:
claude "write tests for the UserProfileView in accounts/views.py using Django's TestCase. Cover: GET returns 200 for authenticated users, GET returns 403 for anonymous, POST updates profile, POST with invalid data returns 400 with errors."

Go

# Generate Go table-driven tests
claude "write Go tests for the ParseConfig function in config/parser.go. Use table-driven test style (var tests = []struct{...}). Cover: valid YAML, invalid YAML, missing required fields, default values."

# Claude generates standard Go test file:
# func TestParseConfig(t *testing.T) {
#   tests := []struct { name string; input string; want Config; wantErr bool }{...}
#   for _, tt := range tests { ... }
# }

Debugging Failing Tests

Paste the error output

# Pipe test output directly to Claude
npm test 2>&1 | claude --no-interactive "these tests are failing. Identify the root cause and fix it without changing test assertions."

# Or paste interactively
claude
> these tests failed:
> FAIL src/auth.test.ts
>   ● validateEmail › should return false for missing @ symbol
>     Expected: false
>     Received: true
>
> Fix the root cause in the source file, not the test.

Flaky test diagnosis

claude "src/payments.test.ts fails intermittently — about 1 in 10 runs — with a timeout error on the Stripe webhook handler. It's consistent in CI but not locally. What are the likely causes and how do I fix them?"

Claude typically identifies race conditions, uncleared mock state, clock drift in time-dependent assertions, or missing await on async teardown.

Coverage gap analysis

# After running coverage
npm test -- --coverage 2>&1 | claude --no-interactive "which functions have the lowest coverage? What are the most important missing test cases for the payment processing logic?"

Setting Up CLAUDE.md for Consistent Test Generation

Add a testing section to your CLAUDE.md so Claude always generates tests in your preferred style without being told:

# CLAUDE.md (in project root)

## Testing Conventions
- Framework: Jest + React Testing Library
- Test files: colocate with source as `*.test.ts`
- Use `describe()` blocks per exported function
- Use `it()` for each case (not `test()`)
- Mock external APIs with `jest.mock()` at module level
- Database: use in-memory SQLite for tests (see `src/test-utils/db.ts`)
- Never use `any` in test assertions — use proper types
- Always test error paths and null inputs

With this in CLAUDE.md, claude "write tests for src/auth.ts" will automatically follow all these rules without you repeating them.

Common Patterns and Pitfalls

Claude writes tests that always pass

If Claude generates tests and they pass immediately, it may have tested the wrong thing or written trivially passing assertions. Check that tests fail if you intentionally break the implementation — this is the real validation. Prompt: "Verify these tests would catch a bug in the [function name] implementation."

Generated tests don't reflect business logic

Claude knows the code structure but not your domain invariants. For payment processing, auth, or compliance logic — add the business rules to CLAUDE.md or explicitly state them in the prompt: "In our system, a refund can only be issued within 30 days of purchase. The test must cover this constraint."

Tests are too verbose / too terse

Claude calibrates test verbosity to what it finds in your existing test files. If you don't have existing tests, it defaults to a medium level. Specify explicitly: "Write minimal tests — one assertion per it() block, no comments, no helper functions unless shared across 3+ tests."

Frequently Asked Questions

Can Claude Code write tests for existing code?

Yes. Point it at a source file: claude "write tests for src/auth.ts". It reads your file, checks nearby test files for style patterns, and generates a test file. Review before committing — Claude occasionally misses domain invariants you haven't documented.

How do I use Claude Code for TDD?

Write (or have Claude write) a failing test first. Run it to confirm failure. Then: claude "make the failing tests in auth.test.ts pass without changing the test file." Claude implements the minimal code to pass the test, runs it, and confirms green. Then refactor with claude "refactor X, tests must still pass."

Can Claude Code debug failing tests?

Yes. Pipe the test output: npm test 2>&1 | claude "fix the failing tests." Claude reads the error, traces to the source, and applies a fix. For flaky tests, describe the failure pattern — Claude is good at identifying race conditions and uncleared mock state.

Does Claude Code understand pytest / Jest / Go test?

Yes. It detects the framework from your project files and generates tests in the correct syntax. It also reads your existing tests to match your style — describe/it vs class-based vs function-based, which assertion library, how you set up mocks, etc.

How do I generate tests for an entire directory?

Ask: claude "generate test files for all untested functions in src/utils/". For large directories, do it file-by-file for quality control. Adding testing conventions to CLAUDE.md ensures consistent output across all generated files.

→ Claude Code debugging workflow

→ Automate testing in CI/CD with Claude Code

→ Code review workflow

← Back to Home