| name | python-tdd-with-uv |
| description | Test-driven development in Python using uv as the package manager. Covers the red-green-refactor cycle, vertical slicing, and uv project setup. |
| user-invocable | true |
Python TDD with uv
Write Python code test-first using uv for fast dependency and environment management.
Setting Up the Project
- Check if
uv is installed: uv --version
- If the project doesn't have a
pyproject.toml, initialize:
uv init
- Add pytest as a dev dependency:
uv add --dev pytest pytest-cov
- Confirm the test runner works:
uv run pytest --co
TDD Workflow — Vertical Slicing
Work in small cycles. Never write more than one failing test at a time.
Planning Phase
Before writing code, answer:
- What interface changes are needed? (functions, classes, APIs)
- Which behaviors matter most? (prioritize critical paths)
- Can we design for testability? (inject dependencies, avoid global state)
The Cycle
RED → Write ONE failing test for the next behavior
GREEN → Write the MINIMUM code to make it pass
REFACTOR → Clean up without changing behavior
REPEAT
Rules:
- Never write implementation before a failing test exists
- Never write more than one failing test at a time
- Run
uv run pytest after every change
- Tests must assert observable behavior, not implementation details
- Mocks should only be used at system boundaries (I/O, network, clock)
Test File Structure
class TestFeatureName:
"""Group related behaviors."""
def test_does_expected_thing_when_given_input(self):
result = function_under_test(input_value)
assert result == expected
def test_raises_when_given_invalid_input(self):
with pytest.raises(ValueError):
function_under_test(bad_input)
Running Tests
uv run pytest
uv run pytest tests/test_foo.py
uv run pytest -k "test_name"
uv run pytest --cov=src
uv run pytest -x
uv Essentials
uv add <package>
uv add --dev <package>
uv remove <package>
uv sync
uv run <command>
uv lock
- Always use
uv run to execute commands — never activate venvs manually
- Commit both
pyproject.toml and uv.lock
References