test-driven
Skill7 starsChanged 5 months agoMITView on GitHub
实现功能或修 bug 前使用。先写会失败的测试,再写实现。
1 other project uses a version of this.
Adopted by
Most recently taken up by
- adeonir/agent-skillstheir own version, first seen Nov 1, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 1
- adeonir/agent-skills★ 8same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository47 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- api-designSkill
- chinese-commitSkill
- ci-cd-pipelineSkill
- cocos2dx-luaSkill
- cocos-creator-adaptationSkill
- cocos-creator-bundleSkill
- cocos-creator-drawcallSkill
- cocos-creator-hotupdateSkill
- cocos-creatorSkill
- cocos-creator-tween-animSkill
- cocos-creator-ui-listSkill
- code-review-selfSkill
- concurrency-safetySkill
- core-disciplineSkill
- database-safetySkill
- docker-best-practicesSkill
- domestic-stackSkill
- error-handlingSkill
- frontend-best-practicesSkill
- game-assets-memorySkill
- game-mathSkill
- game-netcodeSkill
- game-performanceSkill
- gameplay-architectureSkill
- godot-gdscriptSkill
- go-idiomsSkill
- input-validationSkill
- integration-testingSkill
- large-repo-refactorSkill
- legacy-safe-editSkill
- naming-thingsSkill
- node-best-practicesSkill
- performance-profilingSkill
- pr-descriptionSkill
- python-idiomsSkill
- requirement-deliverySkill
- rust-safetySkill
- secrets-handlingSkill
- security-reviewSkill
- shell-scripting-safeSkill
- systematic-debuggingSkill
- test-data-managementSkill
- unity-csharpSkill
- unreal-cppSkill
- writing-docsSkill
The file
Files
测试驱动
何时用
- 实现一个新功能或新接口,还没有一行实现代码时。
- 修复 bug,想用测试把"错误行为"钉死,防止日后回归。
- 重构已有代码,需要一张安全网确认行为没有改变。
- 不确定某个边界条件下系统应该做什么,想用测试把期望行为写清楚再动手。
核心规则
1. 先写测试
规则: 在写任何实现代码之前,先写一个表达期望行为的测试。
为什么: AI 最常见的路线是"先把功能写出来,最后补测试"——但补出来的测试天然向实现靠拢,只覆盖 happy path,不会质疑假设。等实现已经存在,测试变成了橡皮图章:它测的是"代码现在怎么跑",而不是"代码应该怎么跑"。先写测试才能强迫自己想清楚"调用方视角的合约"。
怎么做:
- 从调用方视角出发:给什么输入,期望得到什么输出或副作用?
- 测试文件比实现文件先存在,
import指向尚不存在的模块也没关系,先写好断言。 - 一次只写一个测试用例,专注于当前最重要的行为。
2. 看它失败
规则: 写完测试后立即运行,确认测试因"功能未实现"而失败,而非因测试本身写错而失败。
为什么: AI 写完测试后经常直接跳到实现,跳过"看红"这一步。但如果测试从一开始就是绿的(比如断言条件写反了、assert True 之类),那整个 TDD 循环就是假的——你永远不知道这个测试有没有能力抓住真正的错误。一个从未失败过的测试,保护价值接近零。
怎么做:
- 运行测试,读错误信息,确认失败原因是
ModuleNotFoundError、AttributeError或断言不等式,而非语法错误或导入错误(后者说明测试本身有 bug)。 - 如果测试意外通过了,停下来审查:是断言写错了,还是功能早已存在?搞清楚再继续。
- 把失败信息记下来,待会儿用于确认"绿"时对应的正是这个失败点。
3. 最小实现
规则: 只写刚好让当前测试通过的代码,不多写。
为什么: AI 一旦开始实现就容易"发散":顺手加错误处理、抽接口、加日志、考虑将来的扩展——测试还没绿,代码已经膨胀了一倍。最小实现原则把"让这一个测试通过"和"完善代码"拆成两个独立步骤,避免在不确定行为是否正确的时候就堆代码。
怎么做:
- 允许暂时写"硬编码返回值"——目的是让测试绿,再靠下一个测试逼迫你写真正的逻辑。
- 克制"顺手做"的冲动:看到相关代码有坏味道,记到 TODO,当前步骤只做让测试通过的最小改动。
- 实现完成后立即运行测试,不要先重构再运行。
4. 看它通过
规则: 运行测试,确认当前测试由红变绿,且原有测试仍然全绿。
为什么: AI 改完代码后会说"应该好了"而不真的跑。或者只运行新测试,没跑全量套件——导致刚写的实现破坏了其他已有功能,而这个问题要等 CI 才暴露。本地绿才算绿,口头绿不算绿。
怎么做:
- 运行全量测试套件,不只跑新写的测试文件。
- 若出现意外的新失败,先查清楚是新代码引入的回归还是测试本身的问题,再继续。
- 全绿之后才可以进入重构阶段("整理代码")。
5. 测行为,不测实现
规则: 测试只断言对外可观察的行为(返回值、副作用、抛出的异常),不断言内部实现细节(私有方法是否被调用、内部变量的值、调用次数等)。
为什么: AI 写测试时有一个典型错误:用 mock.assert_called_once_with(...) 检查内部函数调用顺序,或者 spy 私有方法——这样的测试与实现高度耦合。一旦重构内部逻辑(即便行为没有任何改变),测试就会莫名其妙地挂掉,让人觉得"测试在妨碍重构"而最终把它删掉。测试应该是安全网,不应该是紧身衣。
怎么做:
- 断言函数的返回值,而不是函数内部调用了哪个子函数。
- 断言系统的状态变化(数据库里有没有记录、文件是否存在),而不是某个私有方法被调用了几次。
- Mock 只用于隔离真正的外部依赖(网络、数据库、时钟),不用于验证内部调用链。
正例 / 反例
完整红→绿循环示例(Python + pytest)
场景: 实现一个 parse_amount 函数,接受形如 "¥1,234.56" 的字符串,返回浮点数 1234.56;若格式非法则抛出 ValueError。
第一步:先写测试(此时 parse_amount 函数根本不存在)
# tests/test_parse_amount.py
import pytest
from myapp.currency import parse_amount # 模块尚不存在,先写断言
def test_parse_valid_amount():
assert parse_amount("¥1,234.56") == 1234.56
def test_parse_without_symbol():
assert parse_amount("1,234.56") == 1234.56
def test_parse_invalid_raises():
with pytest.raises(ValueError):
parse_amount("not_a_number")第二步:运行——确认因"模块不存在"而失败(红)
$ pytest tests/test_parse_amount.py -v
FAILED tests/test_parse_amount.py::test_parse_valid_amount
ModuleNotFoundError: No module named 'myapp.currency'失败原因是"模块不存在",而非测试写错。符合预期,继续。
第三步:最小实现——只写让测试通过的代码
# myapp/currency.py
def parse_amount(value: str) -> float:
cleaned = value.lstrip("¥").replace(",", "")
try:
return float(cleaned)
except ValueError:
raise ValueError(f"无法解析金额:{value!r}")第四步:运行——确认全部变绿(绿)
$ pytest tests/test_parse_amount.py -v
PASSED tests/test_parse_amount.py::test_parse_valid_amount
PASSED tests/test_parse_amount.py::test_parse_without_symbol
PASSED tests/test_parse_amount.py::test_parse_invalid_raises
3 passed in 0.04s三个测试全绿,可以进入重构阶段(如有必要)。
测行为 vs 测实现细节:正反例
# 反例 — 测内部实现细节:断言私有方法被调用
from unittest.mock import patch
def test_parse_calls_strip_internally():
with patch("myapp.currency._strip_symbol") as mock_strip:
parse_amount("¥100.00")
mock_strip.assert_called_once_with("¥100.00") # ❌ 与内部实现强耦合
# 重命名 _strip_symbol 就挂# 正例 — 只测对外可观察的返回值
def test_parse_valid_amount():
assert parse_amount("¥100.00") == 100.0 # ✅ 只关心输入→输出
# 内部怎么实现随便改自查清单
- 写实现代码之前,测试文件已经存在,断言已经写好。
- 测试已运行过一次并确认是红的,且失败原因是"功能缺失"而非"测试写错"。
- 实现代码只写了让当前测试通过的最小量,没有顺手加无关逻辑。
- 实现完成后运行了全量测试套件,新测试绿且没有引入新的失败。
- 测试断言的是返回值或可观察状态,没有 mock 或 spy 内部私有方法。
- 每个测试用例只验证一个行为,测试名能清楚说明"什么条件下期望什么结果"。
- 边界条件(空值、非法输入、极值)有对应的测试用例,不只测 happy path。
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

