mcpField
C
codebase:testing

codebase:testing

github.com/yeluyang测试与质量239 次安装15 周前更新
代码仓库

关于 codebase:testing

codebase:testing 是一项用于规划、审查、补全和精简生产代码单元测试的 Skill。它强调先独立设计用例、按函数隔离测试,并在去除冗余时保持覆盖范围。

主要功能

  1. 01先规划用例再检查现有测试
  2. 02按输入与逻辑分支审查覆盖
  3. 03模拟协作者以隔离被测单元
  4. 04按项目风格补充缺失用例
  5. 05去除重复用例且不损失覆盖
  6. 06精简后运行完整测试套件

适用场景

  1. 01评估文件或包的单元测试覆盖
  2. 02查找生产代码中的测试缺口
  3. 03减少冗余或脆弱的单元测试
  4. 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、断言总是通过、测试已不存在的代码,或断言错误行为的用例。
  • 使用更好的惯用写法压缩代码:使用项目支持的惯用写法(表驱动、参数化、共享设置/辅助函数),以更简洁的代码覆盖相同数量的用例。压缩时,每个用例都必须保留可识别的标签,以便失败时能定位到具体场景。
  • 不得丢失覆盖率:精简后,被测函数在每个维度上的用例数量不得低于精简前的数量。精简只去除冗余和冗长代码,不得减少覆盖率。

精简后,运行完整测试套件并确认全部通过(或仅剩有意跳过的用例)。

评论

支持 Markdown