mcpField
C
code-testing

code-testing

github.com/dotnet测试与质量5.8k1.0k 次安装1 天前更新
代码仓库

关于 code-testing

code-testing 是用于生成、修复和加强测试的技能,会按任务范围选择工作流。它协调调研、规划、实现和验证;处理广泛任务时,在可用情况下调用 test-engineer Agent。

主要功能

  1. 01针对性与广泛任务工作流
  2. 02需求与测试覆盖映射
  3. 03按仓库约定验证测试
  4. 04广泛测试任务的委派

适用场景

  1. 01为函数或类生成测试
  2. 02修复或扩展现有测试套件
  3. 03规划项目级全面测试覆盖

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/dotnet/skills --skill code-testing

安装后在 Claude Code 中输入/code-testing确认已加载。

附带文件unit-test-generation.prompt.md

详细介绍

代码测试技能

用于生成、修复和增强测试的可靠隐式入口。它会直接处理范围明确的工作,并将广泛或多阶段的请求交由公共 test-engineer Agent 处理。

不可妥协的执行约定

首先检查流水线归属。 如果当前 Agent 是 test-engineer(包括 dotnet-test:test-engineer 之类带插件限定名称的情况),或调用方为你分配了该流水线中的某个阶段,则不得委派给其他生成器。请在当前流程中继续完成分配的工作。此保护规则优先于下文所有广泛范围委派指示,即使此技能是自动加载的也不例外。

编辑前先对范围进行分类:

  • 广泛范围(覆盖整个项目或包的测试套件,或涉及多个生产文件/模块):在实现前,于已解析且不可暂存的 <TESTAGENT_DIR> 中创建 research.md 和 plan.md;完成最终测试质量审查后,再在该目录中创建 status.md。如果 test-engineer 可用,应在实现前调用该具名自定义 Agent;不得用带有相同标签的通用子 Agent 替代,也不得在当前流程中直接实现广泛范围的请求。若缺少状态文件,则广泛范围工作流尚未完成。
  • 范围明确(用户明确将工作限制在一个函数/类/文件,或一个缺失的方法):不要创建中间状态文件,也不要分派给多个 Agent。即使项目只有一个源代码模块,范围稀疏的项目级请求仍属于广泛范围。

无论属于哪种范围,都要运行最精简且相关的测试命令,并确保其正常退出。始终遵循适用于报告的测试名称与结果验证,即使调用方提供了约定也不例外。将此约定传达给受委派的实现者/测试人员;保留边界情况数据,并验证已配置的报告,而不只是检查控制台输出。 交接内容应与工作量相称:对于一至三项范围明确的需求,使用 Requirement coverage 标签,并以简洁的项目符号列表列出测试名称和成功执行的命令;对于范围更广或包含多项需求的工作,使用 Requirement | Evidence 表格。每项请求的行为都必须引用一个精确的测试名称。

发送广泛范围工作的最终回复前,检查回复本身是否包含 | Requirement | Evidence |,且每个行为行都包含精确的测试名称。子报告或内部计划中的表格不够。不得将这些测试名称概括成模块级项目符号,或改用 Area | Tests 表格。

中间状态文件仅供内部使用,绝不是交付物。将 <TESTAGENT_DIR> 保持为不可暂存,不得将其或其中的文件放入受版本控制的工作区内容,也不得修改 .gitignore 来隐藏这些文件。

完整性应按需求矩阵评估,而非按测试数量衡量。为每个单独请求的状态、边界、错误路径或交互添加各自具体的断言。只有当一次执行确实验证了整个组合时,才可合并多个用例;不得让参数化的成功路径用例代替空状态、无效判别值或之前/恰好/之后的边界情况。对于点名多个生产模块或层的广泛请求,应针对每个点名模块的非平凡公开行为,直接编写测试。跨模块测试可以验证组合,但不能替代所要求的模块级覆盖。应依据行为矩阵判断范围,而不是追求达到或超过某个测试数量。

在公共入口处,将广泛范围的工作委派给 test-engineer 一次。研究、计划、实现和审查仍是必需环节,但不必分别通过独立的子 Agent 调用完成。 仅使用当前运行时中可用的能力。缺少某项技能时,不要使用别名重试,也不要让其他 Agent 重试被策略禁止的操作。 直接从调用方提供的或运行时列出的 code-testing-extensions 目录及其对应的语言文件中读取语言指南。这些内容仅供参考,不是可调用的技能。如果该套件不存在,请使用清单和有代表性的测试,并报告缺少参考资料;不要搜索安装目录。 如果不允许使用临时存储,请将研究和计划保留在上下文中,继续执行允许的测试编辑,并报告缺少的状态文件。如果不允许执行,请继续进行允许的静态审查,并报告测试未运行,绝不可声称测试通过。上述任何阻碍都不能成为修改生产代码或降低要求的理由。

对于范围广或全面的请求,明确列出的矩阵只是最低要求,并非上限。将每个请求的模块或层视为一个清单标题,而不是单一行为:将其扩展为范围明确的公共操作,以及各自不同的验证路径、分支、边界、交互和状态转换。 满足明确列出的矩阵后,检查每个目标 API,找出提示中未提及但可观察到的等价类和不变量:标识、空值、单例和具有代表性的内部输入;精确边界及其相邻值;无效输入类;以及实现所隐含的排序、单调性、回绕、容量、截断或状态不变量。对于尚未验证的每个不同输入类,添加一个与变异相关的用例;只有在参数化或表驱动用例能验证相同的行为时,才将同类情况归并。覆盖率达标只是验证,不是停止扩展的条件。当剩余输入只会触及相同分支和不变量时才停止,而不是在完成明确清单后就停止;绝不要只为提高数量而添加用例。

何时使用此技能

在以下情况下使用此技能:

  • 为整个项目或指定文件生成单元测试
  • 提高现有代码库的测试覆盖率
  • 创建符合项目惯例的测试文件
  • 编写能够实际编译并通过的测试
  • 为新功能或尚未测试的代码添加测试
  • 生成或扩展 MSTest 测试套件;在此入门技能确定范围和项目惯例后,将 writing-mstest-tests 作为补充指南加载

何时不使用

  • 运行或执行现有测试(使用 run-tests 技能)
  • 在测试框架之间迁移(使用迁移技能)
  • 回答不涉及生成测试的 MSTest API/模式或现代化问题(使用 writing-mstest-tests)
  • 仅分析诊断失败测试,且未请求代码或测试更改

工作原理

此技能通过 研究 → 计划 → 实现 流程协调多个专业 Agent:

流程概览
┌─────────────────────────────────────────────────────────────┐
│                     TEST GENERATOR                          │
│  Coordinates the full pipeline and manages state            │
└─────────────────────┬───────────────────────────────────────┘
                      │
        ┌─────────────┼─────────────┐
        ▼             ▼             ▼
┌───────────┐  ┌───────────┐  ┌───────────────┐
│ RESEARCHER│  │  PLANNER  │  │  IMPLEMENTER  │
│           │  │           │  │               │
│ Analyzes  │  │ Creates   │  │ Writes tests  │
│ codebase  │→ │ phased    │→ │ per phase     │
│           │  │ plan      │  │               │
└───────────┘  └───────────┘  └───────┬───────┘
                                      │
                    ┌─────────┬───────┼───────────┐
                    ▼         ▼       ▼           ▼
              ┌─────────┐ ┌───────┐ ┌───────┐ ┌───────┐
              │ BUILDER │ │TESTER │ │ FIXER │ │LINTER │
              │         │ │       │ │       │ │       │
              │ Compiles│ │ Runs  │ │ Fixes │ │Formats│
              │ code    │ │ tests │ │ errors│ │ code  │
              └─────────┘ └───────┘ └───────┘ └───────┘

分步说明

步骤 1:确定用户请求

在编辑前,先对意图和范围进行分类:

  • 生成或扩展:遵循下方的生成工作流。
  • 修复:复现范围明确的故障,确定问题出在测试还是生产行为,进行授权范围内的最小修复,并重新运行覆盖该问题的命令。
  • 审查后修复:调用 test-engineer,由其协调内部质量专家和实现工作。

确保理解用户的请求及其范围。 如果用户未对测试风格、覆盖率目标或惯例提出明确要求,请从 unit-test-generation.prompt.md 获取指南。此提示文件提供有关发现项目惯例、参数化策略、以行为为核心的覆盖率以及特定语言模式的最佳实践。

步骤 2:调用任何工具前先评估请求的规模

让执行流程匹配工作范围。对于仅涉及一个文件的请求,运行完整流程只会消耗轮次和工具调用次数,并不会让测试更好。

范围具体情况执行方式
聚焦一个函数、类或文件;“只为 X 编写测试”;为现有测试套件补充缺失的用例跳过中间状态文件和子 Agent 扇出。把需求清单记在心里(或列在最终表格中),只阅读目标文件和一个相邻测试文件以了解惯例,编写测试,运行范围最窄的测试命令,并在原位检查自己的断言。
广泛一个项目、软件包或模块集合;“全面的测试套件”;需要跨多个文件达到某个覆盖率阈值按照步骤 3 运行完整的 Research → Plan → Implement 流程,在 <TESTAGENT_DIR> 下创建中间状态文件,并遵循下方的完成契约。

如有疑问,先从聚焦范围开始,只有在请求涉及多个文件时才扩大范围。扩大范围只需多进行一轮;对聚焦请求运行广泛流程则需要多轮。

结束聚焦范围的请求前,确认以下三个条件都已满足:

  1. 每项指定行为都有具体断言,包括要求覆盖的每个边界情况或错误路径;
  2. 范围最窄的测试命令成功退出;
  3. 最终交接内容将这些行为对应到确切的测试名称,并注明该成功命令。

不要用笼统的已覆盖领域列表代替需求级别的证据。

步骤 3:调用 Test Generator(广泛范围)

首先调用指定的 test-engineer 自定义 Agent,并提出测试生成请求。不要使用仅仅名为 test-engineer 的通用 Agent:

You are the sole pipeline owner for this request. Do not invoke code-testing or another test-engineer; complete the phases in your current context. Generate unit tests for [path or description of what to test], following the [unit-test-generation.prompt.md](unit-test-generation.prompt.md) guidelines. Treat the current workspace as authoritative even when it is sparse, gutted-looking, synthetic, or missing tracked files; never restore or reconstruct it, including with `git checkout`, `git restore`, `git reset`, or `git clean`.

Test Generator 负责整个流程。它返回后,使用其记录的质量检查、验证结果和需求矩阵,不要再重复步骤 4 和步骤 5,另行运行一遍流程。不要重新加载审查技能,也不要重新运行未发生变化且已通过的命令。最终交接中须保留其证据中的确切测试名称。如果缺少证据,请检查或跟进具体缺口,不要重新启动生成流程。若报告指出某项功能整体被拒绝,同样的限制也适用于调用方;不要尝试使用该功能执行其他命令。

如果 test-engineer 不可用,不要跳过工作流。请在当前上下文中按相同的 Research → Plan → Implement 顺序执行,按照下文所述解析 <TESTAGENT_DIR>,并在那里创建中间状态文件,同时遵循相同的完成契约。

对于广泛范围的请求,在创建中间状态文件前,先解析出唯一的绝对路径 <TESTAGENT_DIR>:

  1. 优先使用主机提供的会话产物目录或临时目录。
  2. 否则,如果位于 Git 工作树中,运行 git rev-parse --path-format=absolute --git-path testagent;该命令会返回工作树专属 Git 元数据中的路径,该路径无法被暂存。
  3. 如果不在 Git 工作树中,则在操作系统的临时目录下创建一个唯一目录。

将绝对路径传给每个流程 Agent。该路径可以位于仓库的 .git 元数据目录中,但不能是受版本控制的工作区内容,不能出现在 git status 中,也不能被暂存。

第 4 步:在有限上下文中执行

对于多文件请求:

  1. 在实施前,将用户的每项明确要求转换为检查清单。包括所请求的层、需要模拟的协作者、边界情况、集成、覆盖率阈值和报告产物。逐字复制包含多个条件的要求——每项要求都必须对应一个覆盖完整组合的测试。
  2. 仅研究所请求的模块或项目,并将检查清单及精简的目标清单写入 <TESTAGENT_DIR>/research.md。
  3. 使用清单、符号引用和确定性配对工具,而不是阅读每个源文件和测试文件。
  4. 如果有可用的 find-untested-sources 技能,且它适用于大规模多文件清单,则运行一次,并复用其配对结果和建议路径输出。否则,只手动配对一次范围有限的目标;不要探查是否存在不可用的技能。
  5. 每个目标文件只规划一次,然后按顺序分阶段实施。将每项检查清单内容映射到至少一个具体测试,或说明受阻原因。
  6. 在修复周期中构建并测试范围有限的目标。只有在工作范围较广、仓库约定要求使用该入口,或更改可能影响其他项目时,才在最后运行一次工作区级验证。
  7. 在报告成功之前,重新打开生成的测试,并根据具体测试名称和断言核实每项检查清单内容。仅有覆盖率不能证明测试了所要求的模拟接口、边界、状态转换或属性组合。
  8. 只有在仓库中没有代表性测试且基础扩展不足时,才从 code-testing-extensions 中阅读对应语言的示例。
  9. 对于 .NET,在选择命令或创建文件之前,先判断项目是 SDK 风格还是经典非 SDK 风格。对于经典项目,保留 packages.config、现有框架和模拟库版本以及自定义基础测试夹具;将所有新增测试文件添加到项目明确列出的 <Compile Include> 项中,并使用仓库的 MSBuild/测试运行器命令。切勿仅为生成测试而升级项目或依赖栈。
  10. 对于 MSTest,在选择异常断言之前,先检查固定的包版本。MSTest 3.5.x 使用 Assert.ThrowsException<T>;不要改用 [ExpectedException]、Assert.Throws<T> 或 Assert.ThrowsExactly<T>。
完成约定

每个范围都必须满足以下第 3–5 点。第 1 和第 2 点是广范围的产物:对于聚焦请求,同样的推理会内联完成,不会写入中间状态文件。

只有在以下条件全部满足后,才能报告完成:

  1. (广范围) <TESTAGENT_DIR>/research.md 记录有界目标清单、现有测试约定和验收清单。
  2. (广范围) <TESTAGENT_DIR>/plan.md 将清单中的每一项映射到计划中的测试或明确的阻碍因素。
  3. 生成的测试通过最窄的相关测试命令编译并通过,同时满足通用的报告安全命名和结果验证约定。
  4. 每项明确的用户要求都有具体测试和断言作为支撑。即使覆盖率已经达标,也要补齐缺失的 mock 接缝、边界情况、状态转换和属性组合。在最终摘要中,为清单中的每一项至少引用一个生成的测试名称,以便审计完成情况;如果某项没有可引用的测试,就继续实现或报告阻碍。对于搭建脚手架、范围限制、命令或覆盖率产物等非行为要求,应引用相关文件、命令或报告,而不是强行映射到测试名称。 测试通过但测试数量较少,并不意味着覆盖较弱:应根据每项独立要求的行为是否都有直接且不冗余的证据来判断完整性,而非只看测试数量。 对于广泛/全面的范围,还要验证有界目标 API 中发现的每个可观测等价类和不变量都至少有一个与变异相关的用例,即使提示中没有明确提及。 当请求涉及多个模块时,除端到端组合测试外,还要确保每个模块自身的非平凡公共行为都有直接的测试证据。
  5. 检查生成的测试,找出行为缺口和薄弱断言。对于广范围,在可用时调用 test-gap-analysis 和 assertion-quality,并在 <TESTAGENT_DIR>/status.md 中记录发现的问题和修复内容。对于聚焦范围,应内联完成同等审查:对照源代码重新检查每条生成的断言,不要启动额外审查流程。

最终回复必须逐项提供需求证据。对于一至三项聚焦需求,在 Requirement coverage 标签下使用精简的项目符号;对于更广的范围,使用 Requirement | Evidence 表格。行为证据应引用准确的生成测试名称。非行为证据应引用相关项目文件、验证命令或覆盖率报告。泛泛列出已测试的范围,不能替代逐项证据。

每项证据都要保留用户的确切含义;只有当原话能区分某种必需组合时,才逐字引用。仅仅调用了相同协作者的测试,不能满足关于它们交互方式的要求;对于按类提出的要求,必须逐类引用证据。

引用成功运行,而非尝试记录。 最终证据所依据的命令必须成功完成:引用最终通过的测试摘要;如果指定了阈值,还要引用一次退出码为 0 的运行所产生的逐模块覆盖率表。如果最后一次覆盖率运行退出码非零,就先修复并重新运行,再报告;绝不能根据失败或未完成的运行推断阈值已达标。

报告前,检查最终工作树变更,并确认 research.md、plan.md、status.md 以及其他任何中间状态文件都不在计划提交的变更中。

状态管理

范围较广的运行会将中间状态文件存储在不可暂存的 <TESTAGENT_DIR> 中,该目录由主机临时存储、Git 元数据或操作系统临时目录提供支持。针对性请求不会创建这些文件:

文件用途
<TESTAGENT_DIR>/research.md代码库分析结果
<TESTAGENT_DIR>/plan.md分阶段实施计划
<TESTAGENT_DIR>/status.md最终质量审查和修复

Agent 参考

Agent用途
test-engineer协调流程
code-testing-researcher分析代码库
code-testing-planner制定测试计划
code-testing-implementer编写测试文件
code-testing-builder编译代码
code-testing-tester运行测试
code-testing-fixer修复错误
code-testing-linter格式化代码

要求

  • 项目必须配置构建/测试系统
  • 应已安装(或可安装)测试框架
  • 安装了 GitHub Copilot 扩展的 VS Code

如果现有构建/测试工具链可用,则支持经典的非 SDK .NET 项目。如果当前计算机上无法使用该工具链,Agent 仍可添加并注册与版本兼容的测试,但必须报告测试执行受阻,不得改用 dotnet test。

故障排除

测试无法编译

code-testing-fixer Agent 会尝试解决编译错误。查看 <TESTAGENT_DIR>/plan.md,了解预期的测试结构。根据提供的 code-testing-extensions 目录,阅读对应的语言文件以查找错误代码说明(例如,.NET 对应 dotnet.md)。

测试失败

生成的测试中,大多数失败是由断言中的预期值错误导致的,而非生产代码缺陷:

  1. 阅读实际测试输出
  2. 阅读生产代码以了解正确行为
  3. 修复断言,而非生产代码
  4. 切勿仅为让测试通过而将测试标记为 [Ignore] 或 [Skip]
检测到的测试框架不正确

在初始请求中指定首选框架:“Generate Jest tests for...”

依赖环境的测试失败

依赖外部服务、网络端点、特定端口或精确计时的测试会在 CI 环境中失败。请改为专注于使用模拟依赖的单元测试。

更广泛的验证失败

实现过程中,构建并测试范围较窄的目标。仅在工作范围较广、仓库约定要求使用该入口,或目标更改可能影响其他项目时,才运行解决方案或工作区级别的命令。不要将针对性的测试请求变成无条件的完整非增量构建。

评论

支持 Markdown