关于 codebase:testing
codebase:testing 是一项用于规划、审查、补全和精简生产代码单元测试的 Skill。它强调先独立设计用例、按函数隔离测试,并在去除冗余时保持覆盖范围。
主要功能
- 01先规划用例再检查现有测试
- 02按输入与逻辑分支审查覆盖
- 03模拟协作者以隔离被测单元
- 04按项目风格补充缺失用例
- 05去除重复用例且不损失覆盖
- 06精简后运行完整测试套件
适用场景
- 01评估文件或包的单元测试覆盖
- 02查找生产代码中的测试缺口
- 03减少冗余或脆弱的单元测试
- 04反复审查直至覆盖缺口收敛
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ yeluyang/ skills --skill codebase:testing安装后在 Claude Code 中输入/codebase:testing确认已加载。
附带文件agents/openai.yaml
详细介绍
单元测试
为范围内的生产代码规划一套完整的单元测试用例体系,检查现有测试已经覆盖的内容,补齐缺口,最后进行精简。核心方法:先思考理想的用例体系,再与实际情况对照,避免受现有测试影响,也避免遗漏。
核心原则
- 先规划,再审查:独立规划每个函数/方法_应当_包含哪些测试用例,然后再检查现有测试已经覆盖了哪些内容。先看现有测试会产生偏见,而“看起来够了”的感觉会让你漏掉应该测试的内容。
- 隔离被测单元:测试函数 A 时,如果 A 调用 B,就假定 B 正确,对 B 进行模拟,并只验证 A 与 B 的交互——其输入和输出——是否符合预期。绝不要在 A 的测试中详细编写各种用例来证明 B 正确——B 有自己的测试。一旦打破这个边界,协作者中的一个错误就会导致所有调用它的函数测试一齐失败,使问题归因变得混乱。
- 接受无法编写的测试:有些单元测试确实很难编写——模拟成本太高、无法准备测试数据,或庞大的上帝类难以进行全面测试。这不是执行者的过错——应当果断舍弃,不要勉强拼凑脆弱或空洞的测试。舍弃时,在用例计划中注明原因。
- 重复运行应逐渐收敛:此技能可以重复运行,以发现并补齐缺口。健康的重复运行结果应该是“新增用例很少”,而不是每次都发现一批新的缺口。如果每次运行仍然遗漏很多,问题在于规划或审查不够深入,而不是代码。
范围
解析用户参数,确定编写单元测试的范围:
| 用户输入 | 范围 |
|---|---|
| 无参数 | 整个项目——针对所有生产代码,逐个函数进行规划 |
| 目录或包路径 | 该子树——分析其中所有可测试的生产代码 |
| 特定文件、类或方法 | 仅该目标——为其规划用例 |
明确范围后,按顺序执行步骤 1–4。
步骤 1:规划用例体系
针对范围内的每个函数/方法,规划其对应的测试用例体系。规划时不要查看现有测试。
用例计划涵盖以下三个维度。
1.1 显式参数的取值组合
不是穷举所有参数排列,而是针对函数逻辑设计有代表性的取值组合:
- 冒烟用例:选择一组符合函数预期的参数,不引入零值、空值或极端值等挑战,确认函数对最简单的输入也能正确运行。这是回归基线。
- 零值:每种类型的零值(
0、""、false、nil/null/None)。 - 空值:空字符串、空数组、空集合、空映射——各种空容器。
- 参数类型的上下界:对于标量类型,取其边界值,例如
int/uint/float32的最大值和最小值,以及浮点数的正负零和精度边界。 - 容器元素数量:空容器已由“空值”覆盖;此外,还要加入单元素容器(恰好为 1)和多元素容器(>= 2),以覆盖迭代、第一个/最后一个元素以及差一错误。
- 非法输入:包括向枚举参数传入非枚举成员,以及任何违反函数参数校验约定的输入。
1.2 隐式输入的取值组合
函数的输入不只限于它的参数。以下「隐式输入」也需要设计取值组合:
- 全局变量:函数引用的包级/全局变量,考虑它们不同的值或状态。
- 类成员变量:类方法访问的实例字段,构造处于不同状态的对象。
- 外部调用:函数调用的其他函数、方法或网络/文件/数据库操作。这些隐式输入主要通过模拟来覆盖——但请注意,这里要覆盖的不是被模拟函数的输入取值组合,而是它的返回值组合:正常返回值、边界返回值,以及抛出错误的情况,以验证被测函数如何处理协作者的各种输出。
1.3 逻辑分支
梳理函数体内的控制流分支:
- if/switch 分支:设计能触发各个分支的取值组合(显式参数或模拟返回值)。
- 错误处理逻辑:被测函数捕获协作者的错误后采取的重试、转换、传播、降级路径——通过模拟错误返回值来触发这些路径。
- 没有测试价值的分支:有些分支本身没有可验证的行为,例如只记录一条消息,或原样传递错误。这些分支不会产生需要断言的输出或状态变化,不值得设计测试用例,可以跳过。
- 难以触达的分支:如果某个分支的触发条件在单元测试环境中极难构造,就根据「接受无法编写的测试」原则舍弃它,并记录下来。
第 2 步:审查现有测试
现在查看现有测试并完成两件事。
2.1 了解测试风格
弄清代码库的单元测试惯例,让你添加的用例融入其中,而不是显得格格不入:
- 测试命名风格
- 测试文件的目录和命名惯例
- 使用的测试框架和组织方式(表驱动、子测试、describe 块等)
- 模拟工具和模拟习惯
- 断言风格、设置/清理惯例
2.2 对照覆盖情况
根据第 1 步的计划逐项对照现有测试,判断计划中的哪些部分已被现有测试覆盖。判断时:
- 如果现有测试覆盖了同一函数的同一维度,就标记为已覆盖,不要编写重复用例。
- 现有测试有时会覆盖计划未考虑到的场景——评估这些场景是否确实值得保留;如果值得,就纳入计划,否则记录为待删除项。
- 审查必须深入到用例维度,细查取值组合(无论是显式还是隐式),不能止步于「这个函数有测试」。函数有测试不等于测试充分。
收敛自检(关键):如果现有测试看起来相当完整,但你仍打算提出大量新用例,请停下来重新思考。这项技能常常会被反复运行,以发现并填补遗漏,预期结果是逐步收敛——不能每次重复运行都冒出一大批遗漏。请如实判断以下哪种情况适用:
- 之前几轮确实写得太少:那么如何确保本轮一次性补齐,让后续运行趋于收敛?应全面补齐,覆盖应当涵盖的维度,而不是敷衍地随手加几个用例。
- 现有体系实际上已足够:你是否为了堆工作量而列出了一堆看似有用、实则重复或无意义的用例?删掉它们。
- 对现有体系理解不足:你是否没看出已有测试已经覆盖了某些维度,误将其判断为遗漏?返回 2.2,进行更细致的审查。
步骤 3:补充缺失的用例
遵循现有的测试风格,补充计划中尚未被现有测试覆盖的用例。
编写测试时,对于难以构造的测试(模拟成本高、数据无法准备、上帝类),根据“接受无法编写的测试”原则予以舍弃,不要勉强编写脆弱的测试。
步骤 4:精简测试用例
从范围内的测试中删减冗余,保持覆盖率不变,同时减少代码:
- 删除重复用例:多个用例覆盖同一函数的同一维度时,保留最准确的用例。
- 删除无价值用例:删除没有测试意义的用例,例如只测试 getter/setter、断言总是通过、测试已不存在的代码,或断言错误行为的用例。
- 使用更好的惯用写法压缩代码:使用项目支持的惯用写法(表驱动、参数化、共享设置/辅助函数),以更简洁的代码覆盖相同数量的用例。压缩时,每个用例都必须保留可识别的标签,以便失败时能定位到具体场景。
- 不得丢失覆盖率:精简后,被测函数在每个维度上的用例数量不得低于精简前的数量。精简只去除冗余和冗长代码,不得减少覆盖率。
精简后,运行完整测试套件并确认全部通过(或仅剩有意跳过的用例)。