前言¶
让 AI 帮忙写 Python 时,常见问题不是「写不出来」,而是「一次写太多」。Agent 容易先堆实现、再补测试,或者一口气写一串尚未失败的用例,结果接口提前定死、测试只贴实现细节,后面改起来很痛。
TDD(测试驱动开发)本来就是用来约束这种冲动的:先写一个失败的测试,再写刚好够通过的代码,再重构。Astral 出品的 uv 又把依赖安装、虚拟环境和命令执行收成一套很快的工具链。把这两件事写进一份可复用的 SKILL.md,就是 python-tdd-with-uv 要做的事——让 Cursor、Claude Code、Codex CLI 等支持 Agent Skills 的工具,在写 Python 时默认走「小步、先测、用 uv 跑」的流程。
这是什么¶
python-tdd-with-uv 是一份 Agent Skill,收录在 spencerpauly 维护的 awesome-cursor-skills 仓库中,路径为 resources/python-tdd-with-uv/。官方一句话定位是:用 uv 做包管理,在 Python 里做测试驱动开发,覆盖红-绿-重构循环、垂直切片,以及用 uv 初始化项目。
Skill 本体是标准的 SKILL.md(YAML frontmatter + 正文指令)。frontmatter 里 name 为 python-tdd-with-uv,description 说明适用场景,并声明 user-invocable: true,因此除了 Agent 按描述自动选用外,也可以在对话里用 /python-tdd-with-uv 显式调用(具体以所用工具对 Skills 的支持为准)。
它解决的问题很具体:把「怎么立项、怎么加 pytest、怎么一轮只推进一个行为、怎么用 uv run 跑测试」写成 Agent 必须遵守的规则,而不是每次口头提醒。
核心能力¶
根据仓库中的 SKILL.md 原文,该 Skill 主要约束以下几件事。
-
用 uv 搭项目与测试依赖
检查uv是否可用;没有pyproject.toml时用uv init;用uv add --dev pytest pytest-cov加入开发依赖;用uv run pytest --co确认测试发现正常。 -
垂直切片式的红-绿-重构
同一时间只允许一个失败测试:RED 写一个失败用例 → GREEN 写最少实现让它通过 → REFACTOR 在行为不变的前提下整理代码 → 再重复。禁止「先实现再补测」,也禁止一次写多个失败测试。 -
写代码前先做简短规划
先回答:要改哪些接口(函数、类、API)?哪些行为最关键?能否做成可测设计(依赖注入、少用全局状态)? -
测试写法与边界
测试断言可观察行为,而不是实现细节;Mock 只用在系统边界(I/O、网络、时钟等)。推荐按tests/test_<module>.py用类分组相关行为。 -
统一用
uv run执行
所有命令走uv run,不要手动activate虚拟环境;同时提交pyproject.toml与uv.lock。
Skill 文末还指向了几份相关资料作延伸阅读:mattpocock 的垂直切片 TDD Skill、nizos/tdd-guard(用 hooks 强制 TDD)、以及 s2005/uv-skill(uv 工作流模式)。这些是参考链接,不是本 Skill 的内置脚本。
关于 uv 本身:它是 Astral(Ruff 同门)用 Rust 写的 Python 包与项目管理工具,官方文档称可替代 pip、pip-tools、poetry、virtualenv 等常见工具链的一部分,并提供跨平台的 uv.lock。本 Skill 并不重新发明 uv,只是把「TDD 节奏 + uv 命令约定」绑在一起,方便 Agent 执行。
安装与启用¶
手动放入项目(各工具通用)¶
Skill 的实质就是一个目录里的 SKILL.md。从官方仓库取出后,按工具约定放到对应目录即可。awesome-cursor-skills 的 README 说明:在 Cursor 中可复制到项目的 .cursor/skills/(或个人目录)下,由 Agent 自动发现。
# 示例:只拉取该 Skill 到当前项目(Cursor 项目级)
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
也可整仓克隆后,把 resources/python-tdd-with-uv/ 拷到本地 skills 目录。
按 Cursor 文档,Skills 会从下列位置加载(项目级 / 用户级):
| 位置 | 范围 |
|---|---|
.cursor/skills/、.agents/skills/ |
当前项目 |
~/.cursor/skills/、~/.agents/skills/ |
用户全局 |
.claude/skills/、.codex/skills/ 及对应家目录路径 |
兼容 Claude Code / Codex |
每个 Skill 应是「文件夹 + SKILL.md」,文件夹名与 frontmatter 里的 name 一致(此处为 python-tdd-with-uv)。
用 skills CLI 安装(Claude Code 等)¶
第三方目录 Claude Skills Hub 给出的安装示例为:
npx skills add spencerpauly/awesome-cursor-skills --skill python-tdd-with-uv --agent claude-code
该命令会把 Skill 装进当前项目的 .claude/skills/。若你使用 Codex 等其它 agent 标识,以 npx skills 当时支持的参数为准。
系统侧依赖:先装好 uv¶
本 Skill 假设本机已有 uv。可按 uv 官方安装说明 安装,例如 macOS / Linux:
curl -LsSf https://astral.sh/uv/install.sh | sh
uv --version
装好 Skill 之后,在 Agent 对话里直接说「按 TDD 用 uv 实现某某功能」,或输入 /python-tdd-with-uv,Agent 应读取该 Skill 并按其中步骤执行。
典型用法¶
下面流程均来自官方 SKILL.md,可直接复现。
1. 初始化项目与 pytest¶
uv --version
# 若还没有 pyproject.toml
uv init
uv add --dev pytest pytest-cov
uv run pytest --co
--co(collect-only)只收集用例、不执行,用来确认测试发现配置是否正常。
2. 按垂直切片推进一个行为¶
规划阶段先想清楚接口与关键路径,然后严格一轮只做一个失败测试。Skill 给出的循环是:
RED → 为下一个行为写「一个」失败测试
GREEN → 写最少代码让它通过
REFACTOR → 清理结构,不改变行为
REPEAT
硬性规则包括:没有失败测试就不要写实现;每次改完都跑 uv run pytest;断言行为而非内部细节;Mock 仅用于 I/O、网络、时钟等边界。
3. 推荐的测试文件结构¶
# 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. 常用测试命令¶
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 # 遇失败即停
5. uv 日常命令速查¶
uv add <package> # 添加依赖
uv add --dev <package> # 添加开发依赖
uv remove <package> # 移除依赖
uv sync # 按锁文件同步环境
uv run <command> # 在托管环境中执行
uv lock # 重新生成锁文件
Skill 明确要求:始终用 uv run 执行命令,不要手动激活 venv;pyproject.toml 与 uv.lock 一并提交,保证环境可复现。
适用场景与注意事项¶
比较合适的情况:
- 用 AI Agent 从零搭 Python 小项目,希望默认走 pytest + TDD。
- 给已有仓库补行为时,希望 Agent「一次只吃透一个切片」,避免大段投机实现。
- 团队已经或准备统一用
uv管理依赖与锁文件。
需要注意的限制:
- 这是「流程指令」Skill,不是替你写好业务代码的框架;效果取决于 Agent 是否认真遵循 SKILL.md。
- 本机必须先安装
uv;Skill 不会代替系统包管理器去装 uv。 - 「一次只允许一个失败测试」会故意变慢一点——这是为了防止过度设计;若你明确只要快速草稿、不要 TDD,就不必启用该 Skill。
- Mock 规则偏严:内部协作对象不该轻易 mock;若项目大量依赖复杂外部服务,需要先想好边界怎么切。
- Skill 正文引用了 mattpocock/skills、tdd-guard、uv-skill 等延伸方案,但它们是独立项目,默认安装本 Skill 时并不会一并装上。
小结¶
python-tdd-with-uv 把两件近年 Python / AI 编程里很实用的约定绑在一起:一是红-绿-重构与垂直切片,二是用 uv 管依赖并用 uv run pytest 闭环验证。它来自 awesome-cursor-skills 的 Testing 分类,源文件在:
https://github.com/spencerpauly/awesome-cursor-skills/tree/main/resources/python-tdd-with-uv
把 SKILL.md 放进项目的 skills 目录(或按 CLI 装到 .claude/skills/),再让 Agent 做 Python 功能开发时,就能少写一点「请先写测试」的口头约束,多一点可复现的小步节奏。