Preface¶
When asking AI to help write Python code, a common problem is not “being unable to write it”, but “writing too much at once”. Agents tend to pile up implementation code first and then add tests, or write a series of passing use cases all at once. As a result, the interface is fixed ahead of time, and tests only cover implementation details, making subsequent changes painful.
TDD (Test-Driven Development) was originally designed to rein in this impulse: write a failing test first, then write just enough code to make it pass, then refactor. uv from Astral combines dependency installation, virtual environments, and command execution into a fast toolchain. Combining these two practices into a reusable SKILL.md is what python-tdd-with-uv aims to do: let tools that support Agent Skills, such as Cursor, Claude Code, and Codex CLI, follow the “small steps, test first, run with uv” workflow by default when writing Python code.
What is this¶
python-tdd-with-uv is an Agent Skill included in the awesome-cursor-skills repository maintained by spencerpauly, located at resources/python-tdd-with-uv/. Its official one-sentence description is: Use uv for package management, perform test-driven development in Python, covering the red-green-refactor cycle, vertical slicing, and project initialization with uv.
The Skill itself is a standard SKILL.md file (YAML frontmatter + body instructions). In the frontmatter, name is set to python-tdd-with-uv, and description explains the applicable scenarios, with user-invocable: true declared. This means in addition to being automatically selected by the Agent based on the scenario, it can also be explicitly called with /python-tdd-with-uv in the conversation (specifically subject to the Skill support of the tool you are using).
The problem it solves is very specific: formalize “how to start a project, how to add pytest, how to advance only one behavior at a time, and how to run tests with uv run” into rules that the Agent must follow, instead of reminding verbally every time.
Core Capabilities¶
Based on the original SKILL.md in the repository, this Skill mainly constrains the following points:
-
Set up projects and test dependencies with uv
Check ifuvis available; useuv initwhen there is nopyproject.toml; useuv add --dev pytest pytest-covto add development dependencies; useuv run pytest --coto confirm that test discovery works properly. -
Vertical slicing red-green-refactor
Only allow one failing test at a time: RED writes one failing test case → GREEN writes the minimal implementation to make it pass → REFACTOR tidy up the code without changing behavior → repeat. Prohibits “implement first then add tests”, and also prohibits writing multiple failing tests at once. -
Make a brief plan before writing code
First answer: Which interfaces (functions, classes, APIs) need to be modified? Which behaviors are most critical? Can it be made into a testable design (dependency injection, less use of global state)? -
Test writing style and boundaries
Test assertions should check observable behavior, not implementation details; Mock should only be used at system boundaries (I/O, network, clock, etc.). It is recommended to group related behaviors into classes in the formattests/test_<module>.py. -
Unified execution with
uv run
All commands should useuv run, do not manuallyactivatethe virtual environment; also commit bothpyproject.tomlanduv.lock.
At the end of the Skill, there are links to relevant materials for extended reading: mattpocock’s vertical slicing TDD Skill, nizos/tdd-guard (enforce TDD with hooks), and s2005/uv-skill (uv workflow pattern). These are reference links and not built-in scripts of this Skill.
About uv itself: it is a Rust-written Python package and project management tool from Astral (the same team behind Ruff). Its official documentation states that it can replace parts of common toolchains such as pip, pip-tools, poetry, and virtualenv, and provides cross-platform uv.lock. This Skill does not reinvent uv; it only binds “TDD rhythm + uv command conventions” to facilitate Agent execution.
Installation and Activation¶
Manual placement in project (universal for all tools)¶
The essence of a Skill is a directory containing SKILL.md. After retrieving it from the official repository, place it in the corresponding directory according to the tool’s conventions. The README of awesome-cursor-skills explains: In Cursor, you can copy it to the project’s .cursor/skills/ (or personal directory) for the Agent to automatically discover.
# Example: Pull only this Skill into the current project (Cursor project-level)
mkdir -p .cursor/skills/python-tdd-with-uv
curl -fsSL \
https://raw.githubusercontent.com/spencerpauly/awesome-cursor-skills/main/resources/python-tdd-with-uv/SKILL.md \
-o .cursor/skills/python-tdd-with-uv/SKILL.md
You can also clone the entire repository and copy the resources/python-tdd-with-uv/ directory to your local skills directory.
According to the Cursor documentation, Skills will be loaded from the following locations (project-level / user-level):
| Location | Scope |
|---|---|
.cursor/skills/, .agents/skills/ |
Current project |
~/.cursor/skills/, ~/.agents/skills/ |
User global |
.claude/skills/, .codex/skills/ and their home directory paths |
Compatible with Claude Code / Codex |
Each Skill should be a “directory + SKILL.md”, and the directory name must match the name in the frontmatter (here it is python-tdd-with-uv).
Install with skills CLI (for Claude Code etc.)¶
The installation example given by the third-party directory Claude Skills Hub is:
npx skills add spencerpauly/awesome-cursor-skills --skill python-tdd-with-uv --agent claude-code
This command will install the Skill into the current project’s .claude/skills/ directory. If you are using other agent identifiers such as Codex, refer to the parameters supported by npx skills at that time.
System-level dependency: Install uv first¶
This Skill assumes that uv is already installed on the local machine. You can install it according to the official uv installation instructions, for example on macOS / Linux:
curl -LsSf https://astral.sh/uv/install.sh | sh
uv --version
After installing the Skill, just say “implement a certain function using TDD with uv” in the Agent conversation, or enter /python-tdd-with-uv, and the Agent should read this Skill and execute according to the steps inside.
Typical Usage¶
The following processes are all from the official SKILL.md and can be reproduced directly.
1. Initialize project and pytest¶
uv --version
# If there is no pyproject.toml yet
uv init
uv add --dev pytest pytest-cov
uv run pytest --co
--co (collect-only) only collects test cases without executing them, used to confirm whether the test discovery configuration is normal.
2. Advance one behavior via vertical slicing¶
During the planning phase, clarify the interface and critical paths first, then strictly only work on one failing test at a time. The cycle given by the Skill is:
RED → Write **one** failing test for the next behavior
GREEN → Write the minimal code to make it pass
REFACTOR → Clean up the structure without changing behavior
REPEAT
Hard rules include: do not write implementation code without failing tests; run uv run pytest after each change; assert behavior rather than internal details; only use Mock for I/O, network, clock and other boundaries.
3. Recommended test file structure¶
# tests/test_<module>.py
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)
4. Common test commands¶
uv run pytest # Run all tests
uv run pytest tests/test_foo.py # Run single test file
uv run pytest -k "test_name" # Filter tests by name
uv run pytest --cov=src # Run tests with coverage report
uv run pytest -x # Stop on first test failure
5. Quick reference for daily uv commands¶
uv add <package> # Add production dependency
uv add --dev <package> # Add development dependency
uv remove <package> # Remove dependency
uv sync # Sync environment according to lock file
uv run <command> # Execute command in the managed environment
uv lock # Regenerate lock file
The Skill clearly requires: always use uv run to execute commands, do not manually activate the venv; commit both pyproject.toml and uv.lock to ensure reproducible environments.
Applicable Scenarios and Notes¶
More suitable situations:
- Building small Python projects from scratch with AI Agents, hoping to follow pytest + TDD by default.
- Adding behaviors to existing repositories, hoping that the Agent “only grasps one slice at a time” to avoid large speculative implementations.
- The team has already or is preparing to unify the use of uv to manage dependencies and lock files.
Notes on limitations:
- This is a “process instruction” Skill, not a framework that writes business code for you; the effect depends on whether the Agent follows the SKILL.md carefully.
- uv must be installed locally first; the Skill will not replace the system package manager to install uv.
- The rule of “only one failing test at a time” will intentionally slow down the process — this is to prevent over-engineering; if you just want a quick draft without TDD, you do not need to enable this Skill.
- The Mock rules are relatively strict: internal collaboration objects should not be easily mocked; if the project heavily relies on complex external services, you need to plan how to split the boundaries first.
- The Skill body references extended solutions such as mattpocock/skills, tdd-guard, and uv-skill, but these are independent projects and will not be installed automatically when installing this Skill by default.
Summary¶
python-tdd-with-uv combines two very practical conventions in recent Python and AI programming: one is the red-green-refactor cycle and vertical slicing, and the other is using uv to manage dependencies and closing the loop with uv run pytest for verification. It comes from the Testing category of awesome-cursor-skills, and the source file is located at:
https://github.com/spencerpauly/awesome-cursor-skills/tree/main/resources/python-tdd-with-uv
By placing SKILL.md in the project’s skills directory (or installing it to .claude/skills/ via the CLI), when you ask the Agent to develop Python functions, you can reduce the need for verbal reminders like “please write tests first”, and have a more reproducible small-step development rhythm.