在 VS Code 中设置测试驱动开发流程
测试驱动开发 (TDD) 是一种先编写测试再实现功能的软件开发方法。它能创建一个紧密的反馈循环,从而提高代码质量、及早发现 Bug 并确保代码符合需求。Visual Studio Code 的 AI 功能可以通过引导你完成编写测试、实现代码、运行测试和优化代码的各个阶段,来增强你的 TDD 工作流。
本指南展示了如何通过使用自定义代理、切换 (handoffs) 和自定义指令,在 VS Code 中设置 AI 辅助的测试驱动开发工作流。
TDD 概述
测试驱动开发的核心原则是先编写测试再实现功能。测试定义了你想要构建的功能的预期结果。通过先写测试,你可以明确需求并识别边缘情况,以确保代码按预期运行。
TDD 遵循一个被称为 红-绿-重构 (red-green-refactor) 的三阶段循环,并针对每一个小的功能增量进行重复。
三个阶段分别是:
-
红阶段 (Red phase):为你想要开发的功能编写一个会失败的测试。
-
绿阶段 (Green phase):编写使测试通过所需的最小应用程序代码。专注于让它运行起来,而不是追求完美。
-
重构阶段 (Refactor phase):在保持所有测试通过的同时改进代码质量。清理重复代码、优化命名并增强结构。
实现概览
你可以通过使用自定义代理在 VS Code 中实现 AI 辅助的 TDD 工作流。TDD 过程的每个阶段(红、绿、重构)都有特定的目标,并需要不同的 AI 行为。你可以为每个阶段创建一个自定义代理,定义该阶段的具体角色和指南。
借助自定义代理切换,你可以在 AI 完成任务后从一个阶段过渡到下一个阶段。这些自定义代理连接成一个闭环,反映了 TDD 的工作流:
- 红阶段 → 编写失败测试后切换到 绿阶段
- 绿阶段 → 运行测试以验证实现,然后切换到 重构阶段
- 重构阶段 → 运行测试以确保它们仍然通过,然后切回 红阶段以开始下一个循环
如果你已经确立了测试规范,可以使用 自定义指令 来设置测试上下文,引导 AI 生成符合你项目标准的测试。
下图展示了自定义代理如何协同工作以实现 TDD 工作流,以及切换功能如何实现阶段间的平滑过渡。

你还可以通过在循环开始前增加一个规划阶段来进一步增强 TDD 工作流。你可以使用内置的规划代理或创建一个自定义规划代理,帮助明确需求并识别需要测试覆盖的边缘情况。
第 1 步:设置测试指南
如果你有既定的测试规范和实践,请创建一个自定义指令文件 (testing.instructions.md),以帮助 AI 生成符合你项目标准的测试。
为什么要这样做:如果没有明确的测试规范,AI 可能会生成与项目风格不符、模式不一致或遗漏重要测试场景的测试。
设置测试指南的步骤
-
在命令面板中运行 Chat: Create Instructions File 命令,在工作区中创建一个新的指令文件。
- 选择
.github/instructions以在工作区中创建指令文件。 - 输入 "testing" 作为指令文件的名称。
注意通过使用
*.instructions.md文件而不是copilot.instructions.md文件,你可以选择性地仅将这些测试指南应用于项目中的测试文件,而不是将其包含在所有 AI 交互中。 - 选择
-
更新指令的
applyTo元数据,使其自动应用于测试文件。同时设置description元数据,以表明这些指令提供了测试上下文。以下示例将
applyTo字段更新为目标是tests/目录下的所有文件:--- description: 'Use these guidelines when generating or updating tests.' applyTo: tests/** --- -
将你项目的测试指南添加到指令文件的正文中。
以下示例为测试规范提供了一个起点:
--- description: 'Use these guidelines when generating or updating tests.' applyTo: tests/** --- # [Project Name] Testing Guidelines ## Test conventions * Write clear, focused tests that verify one behavior at a time * Use descriptive test names that explain what is being tested and the expected outcome * Follow Arrange-Act-Assert (AAA) pattern: set up test data, execute the code under test, verify results * Keep tests independent - each test should run in isolation without depending on other tests * Start with the simplest test case, then add edge cases and error conditions * Tests should fail for the right reason - verify they catch the bugs they're meant to catch * Mock external dependencies to keep tests fast and reliable提示你可以创建一个可选的测试结构模板,定义不同类型测试的章节和模式(例如
test-template.md)。在指令文件中引用该模板,这样 AI 在生成测试时就会使用它。
第 2 步:创建“红阶段”自定义代理
创建一个“TDD-red”自定义代理,专注于 TDD 的红阶段。该自定义代理仅负责根据提供的需求编写失败的测试,不应实现任何应用程序代码。完成后,该代理将切换到绿阶段自定义代理。
为什么要这样做:如果没有这种专注模式,AI 可能会将实现建议与测试创建混在一起,并偏离先写测试的核心 TDD 原则。
创建 .github/agents/TDD-red.agent.md 红阶段 自定义代理 的步骤:
-
在命令面板中运行 Chat: New Custom Agent 命令。
- 选择
.github/agents以在工作区中创建自定义代理定义。 - 输入 "TDD-red" 作为自定义代理的名称。
- 选择
-
更新自定义代理定义,描述红阶段的指南和规则,并指定切换到绿阶段自定义代理。
以下
TDD-red.agent.md文件为红阶段提供了一个起点。--- name: TDD Red description: TDD phase for writing FAILING tests infer: true tools: ['read', 'edit', 'search'] handoffs: - label: TDD Green agent: TDD Green prompt: Implement minimal implementation --- You are a test-writer: when given a function name, spec, or requirements, output a complete test file (or test function) that asserts the expected behavior, which must fail when run against the current codebase. Use the project’s style/conventions. Do not write implementation, only tests.
第 3 步:创建“绿阶段”自定义代理
创建一个“TDD-green”自定义代理,专注于 TDD 的绿阶段。该自定义代理仅负责编写使测试通过的最小实现代码,且不修改测试代码。实现后,该代理会运行测试以验证其通过,然后切换到重构阶段自定义代理。
创建 .github/agents/TDD-green.agent.md 绿阶段 自定义代理 的步骤:
-
在命令面板中运行 Chat: New Custom Agent 命令。
- 选择
.github/agents以在工作区中创建自定义代理定义。 - 输入 "TDD-green" 作为自定义代理的名称。
- 选择
-
更新自定义代理定义,描述绿阶段的指南和规则,并指定切换到重构阶段自定义代理。
以下
TDD-green.agent.md文件提供了一个起点。--- name: TDD Green description: TDD phase for writing MINIMAL implementation to pass tests infer: true tools: ['search', 'edit', 'execute'] handoffs: - label: TDD Refactor agent: TDD Refactor prompt: Refactor the implementation --- You are a code-implementer. Given a failing test case and context (existing codebase or module), write the minimal code change needed so that the test passes - no extra features. Do not write tests, only implementation. After implementing changes, run the tests to verify they pass.
第 4 步:创建“重构阶段”自定义代理
创建一个“TDD-refactor”自定义代理,专注于 TDD 的重构阶段,在保持所有测试通过的同时提高代码质量。该代理负责清理代码、消除重复、优化命名并增强结构,而不改变功能。重构后,该代理会运行测试以确保它们仍然通过,然后切回红阶段以开始下一个 TDD 循环。
创建 .github/agents/TDD-refactor.agent.md 重构阶段 自定义聊天代理 的步骤:
-
在命令面板中运行 Chat: New Custom Agent 命令。
- 选择
.github/agents以在工作区中创建自定义代理定义。 - 输入 "TDD-refactor" 作为自定义代理的名称。
- 选择
-
更新自定义代理定义,描述重构阶段的指南和规则。
以下
TDD-refactor.agent.md文件提供了一个起点。--- name: TDD Refactor description: Refactor code while maintaining passing tests tools: ['search', 'edit', 'read', 'execute'] infer: true handoffs: - label: TDD Red agent: TDD Red prompt: Start next TDD cycle with new test --- You are refactor-assistant. Given code that passes all tests, examine it and suggest or apply refactoring to improve readability/structure/DRYness, without changing behavior. No new functionality, no breaking changes. After refactoring, run the tests to ensure all tests still pass and behavior is preserved.
使用 TDD 工作流实现功能
既然 TDD 自定义代理已设置完毕,你就可以使用它们通过 TDD 工作流在项目中实现功能。
-
打开 Chat 视图,从代理下拉菜单中选择 TDD Red 代理。
-
提供一个提示,描述你想要测试的功能或行为。
例如
Write tests for user registration with email validation and password requirements. -
审查生成的测试,并使用切换操作来完成 TDD 循环的过渡。
- 测试编写完成后,选择 TDD Green 以实现使测试通过的最小代码。
- 绿阶段代理在实现后会自动运行测试。
- 测试通过后,选择 TDD Refactor 以提高代码质量。
- 重构代理在重构后会自动运行测试,以确保它们仍然通过。
- 选择 TDD Red 以开始包含额外功能的下一个循环。
故障排除与最佳实践
AI 进行 TDD 的常见误区
在没有切换的情况下进行 TDD:使用单个代理完成整个 TDD 循环会将人类排除在循环之外。切换提供了控制点,你可以在此评估每一步、验证 AI 的工作,并在进入下一阶段前引导代理走向正确的方向。
缺失功能的测试覆盖率:TDD 代理专注于让现有测试通过,不会实现没有对应测试的功能。在预期实现包含某个功能之前,确保规范中的每一项需求都有测试覆盖。
跳过红阶段:AI 可能会建议在编写测试之前实现代码。
过度实现:AI 可能会生成比通过当前测试所需代码更多的代码。批判性地审查实现并移除不必要的复杂性。
测试实现细节:测试应验证行为,而不是实现。如果重构需要更改测试,那么它们可能与实现细节耦合太紧了。
测试覆盖不完整:AI 可能会遗漏边缘情况或错误条件。批判性地审查生成的测试,并要求增加涵盖边界条件、错误场景和边缘情况的测试。
AI 进行 TDD 的最佳实践
为任务选择合适的模型:不同的语言模型有不同的优势。考虑将推理模型用于复杂的测试生成和边缘情况识别。在 Chat 视图中使用模型选择器在 TDD 工作流期间切换模型,或者在自定义代理属性中定义 model。
验证测试质量:AI 生成测试后,请仔细检查以确保它因为正确的原因而失败。在实现功能前运行测试,以验证它确实捕获了缺失的功能。
保持增量进度:在 TDD 循环中采取小步快跑的方式。编写一个测试,实现最小代码,重构,然后重复。小的迭代可以防止重大错误并保持代码库正常运行。
频繁运行测试:更改后立即执行测试。不要在测试前累积多个更改。频繁运行测试可以提供快速反馈并尽早发现问题。
使用测试覆盖率作为指南:高覆盖率不能保证质量,但低覆盖率意味着存在未测试的行为。要求 AI 为未覆盖的代码路径建议测试。
保持测试独立性:测试应以任何顺序运行且互不影响。如果测试依赖于执行顺序或共享状态,请重构它们以实现独立。
根据需要更新测试上下文:随着项目的演进,更新指令文件中的测试指南,以反映新的规范、框架或实践。
相关资源
了解有关 VS Code 中测试和 AI 自定义的更多信息