返回技能市场
开发运维 安全

tdd

@admin/tdd

Test-driven development. Use when the user wants to build features or fix bugs test-first, mentions "red-green-refactor", or wants integration tests.

admin 热度 406v0.0.1

测试驱动开发

TDD 是 red → green 循环。本技能是使该循环产出值得保留的测试的参考:什么是好测试、测试放在哪里、反模式,以及循环规则。每个部分适用于每个循环:在循环之前和期间查阅它们,而不是之后。

探索代码库时,阅读 CONTEXT.md(如果存在),以便测试名称和接口词汇与项目的领域语言匹配,并尊重你正在接触区域的 ADR。

什么是好测试

测试通过公共接口验证行为,而不是实现细节。代码可以完全改变;测试不应该改变。好的测试读起来像规格说明:“user can checkout with valid cart” 准确告诉你存在什么能力,并且它能在重构后存活,因为它不关心内部结构。

参见 [tests.md](tests.md) 获取示例,参见 [mocking.md](mocking.md) 获取模拟指南。

Seam:测试放在哪里

seam 是你进行测试的公共边界:在不触及内部的情况下观察行为的接口。测试存在于 seam 中,绝不针对内部实现。

只在预先商定的 seam 处进行测试。 在编写任何测试之前,写下受测的 seam,并与用户确认。不得在未确认的 seam 处编写测试。你无法测试所有内容,因此事先商定 seam 是测试工作落在关键路径和复杂逻辑上、而不是每个边缘用例的方法。

询问:“公共接口是什么,我们应该测试哪些 seam?”

当该接口的形状本身存疑时(模块有多深、seam 属于哪里、接口应该暴露什么),调用 Skill 工具并使用 “codebase-design” 获取词汇。它是 module、interface、depth、seam、adapter、leverage 和 locality 术语的共同来源,是供查阅的参考,而不是要运行的会话。

反模式

  • 实现耦合:模拟内部协作者、测试私有方法,或通过旁路渠道进行验证(查询数据库而不是使用接口)。迹象是:当你重构时测试会失败,但行为没有变化。
  • 同义反复:断言以代码的方式重新计算期望值(expect(add(a, b)).toBe(a + b)、以同样方式手工派生的快照、断言自身相等的常量),因此它按构造通过,并且永远不可能与代码不一致。期望值必须来自独立的事实来源:已知正确的字面量、已算好的示例、规格说明。
  • 水平切片:先编写所有测试,再编写所有实现。批量测试验证 _想象出的_ 行为:你测试事物的 _形状_ 而不是面向用户的行为,测试对真实变化变得不敏感,并且你在理解实现之前先确定测试结构。应改为使用 垂直切片:一个测试 → 一个实现 → 重复,每个测试都是 曳光弹,会对上一个循环教给你的内容作出响应。

循环规则

  • 先红灯后绿灯。 先编写失败的测试,然后只编写足够的代码使其通过。不要预先设想未来测试或添加投机性功能。
  • 一次一个切片。 每个循环一个 seam、一个测试、一个最小实现。
  • 重构不属于该循环。 它属于评审阶段(参见 code-review 技能),而不是 red → green 实现循环。
qianwen skills install @admin/tdd