1
TestDrivenDevelopment
Bernd Worsch edited this page 2025-09-21 21:00:33 +00:00

ExplorationChat

Prompt

I want to do test driven development for a python based project with a rigorous test first approach. Please provide a best practice guide how to do this with claude code.

Answer

I'll help you set up a rigorous test-first development workflow with Claude Code for Python projects. Here's a best practice guide:

Test-First Development with Claude Code

1. Project Structure Setup

First, establish a clean project structure that separates concerns:

my_project/
├── src/
│   └── my_package/
│       ├── __init__.py
│       └── core/
│           └── __init__.py
├── tests/
│   ├── __init__.py
│   └── unit/
│       └── __init__.py
├── pyproject.toml
└── pytest.ini

2. Initial Configuration

Create a pytest.ini for consistent test behavior:

[pytest]
testpaths = tests
python_files = test_*.py
python_classes = Test*
python_functions = test_*
addopts = -v --tb=short --strict-markers

3. Test-First Workflow with Claude Code

Step 1: Start with the Test When beginning a new feature, always ask Claude Code to write the test first:

# In your terminal
claude-code "Write a test for a function that validates email addresses. 
The test should be in tests/unit/test_validators.py and cover valid emails, 
invalid formats, and edge cases. Use pytest."

Step 2: Review and Refine Tests Claude Code will create the test file. Review it and iterate if needed:

claude-code "Add test cases for international domain names and plus addressing 
to tests/unit/test_validators.py"

Step 3: Implement to Pass Tests Only after tests are written, ask for the implementation:

claude-code "Implement the email_validator function in src/my_package/core/validators.py 
to make the tests in tests/unit/test_validators.py pass. Keep it focused and reusable."

4. Best Practices for Test-First with Claude Code

Be Explicit About Test-First Order:

claude-code "Following TDD: 
1. First create tests in tests/unit/test_parser.py for a JSON parser 
2. Only after showing me the tests, implement the parser in src/my_package/core/parser.py"

Request Idempotent Operations:

claude-code "Write tests and implementation for a file processor that is idempotent - 
running it multiple times on the same input produces the same result"

Ensure Separation of Concerns:

claude-code "Create tests for a repository pattern that separates data access from business logic. 
Tests should mock the database layer."

Specify Test Coverage:

claude-code "Write comprehensive tests covering:
- Happy path
- Edge cases (empty input, null values)
- Error conditions
- Boundary values
Then implement to pass these tests"

5. Running Tests in the Loop

After Claude Code makes changes, immediately run tests:

# Run specific test file
pytest tests/unit/test_validators.py -v

# Run all tests
pytest

# With coverage
pytest --cov=src/my_package --cov-report=term-missing

6. Iterative Refinement Pattern

# 1. Write failing test
claude-code "Add test for handling concurrent requests in tests/unit/test_handler.py"

# 2. Verify it fails
pytest tests/unit/test_handler.py

# 3. Implement
claude-code "Make the concurrent request test pass"

# 4. Verify it passes
pytest tests/unit/test_handler.py

# 5. Refactor if needed
claude-code "Refactor the request handler for better separation of concerns"

7. Advanced TDD Patterns

Test Fixtures for Reusability:

claude-code "Create pytest fixtures in tests/conftest.py for common test data 
and mock objects that can be reused across test modules"

Parameterized Tests:

claude-code "Write parameterized tests using pytest.mark.parametrize 
for testing multiple input scenarios efficiently"

Test Isolation:

claude-code "Ensure all tests are isolated - each test should set up its own 
state and clean up afterward. Use fixtures with appropriate scope."

8. Integration with CI/CD

Include test commands in your workflow:

claude-code "Create a GitHub Actions workflow that runs pytest on every push, 
fails if coverage drops below 90%, and checks for test failures"

9. Documentation Through Tests

claude-code "Write tests that also serve as documentation examples, 
showing how to use the API. Include docstrings in test functions 
explaining what behavior is being verified"

10. Key Commands to Use Regularly

# Start new feature test-first
claude-code "TDD: Write tests first for [feature description], then implement"

# Refactor with test safety net
claude-code "Refactor [module] while ensuring all tests still pass"

# Add missing test coverage
claude-code "Analyze [module] and add tests for uncovered code paths"

# Review and improve tests
claude-code "Review tests/unit/test_*.py and suggest improvements for clarity and coverage"

Tips for Success

  1. Always start sessions with: "Following TDD, write tests first for..."
  2. Be specific about test location: Always specify the exact test file path
  3. Request test verification: Ask Claude Code to explain how tests verify the requirements
  4. Iterative approach: Make small, testable changes rather than large implementations
  5. Use descriptive test names: Request tests with clear, descriptive names that explain what's being tested
  6. Mock external dependencies: Always ask for proper mocking of databases, APIs, file systems
  7. Keep tests fast: Request unit tests that run quickly without I/O when possible

This approach ensures your code is thoroughly tested, maintainable, and follows clean architecture principles with proper separation of concerns.