在VS Code中建立一个测试驱动的开发流程

测试驱动开发(TDD)是一种软件开发方法,在实现功能之前先编写测试。这形成了一个紧密的反馈循环,提升代码质量,早期发现错误,并确保代码符合你的需求。Visual Studio Code 的 AI 功能可以通过引导你完成测试编写、代码实现、运行测试和优化代码的不同阶段,提升你的 TDD 工作流程。

本指南将向您展示如何通过自定义代理、切换和自定义指令,在VS Code中建立AI辅助的测试驱动开发流程。

TDD概述

测试驱动开发的核心原则是在实现前编写测试。测试定义了你想构建的功能的期望结果。通过先写测试,你可以明确需求并识别边缘案例,确保代码符合预期。

TDD遵循称为红绿重构的三相循环,每个功能增量都会重复。

三个阶段分别是:

  • 红色阶段:为你想开发的功能写一个失败测试。

  • 绿色阶段:编写使测试通过所需的最小应用代码。专注于让它正常工作,而不是追求完美。

  • 重构阶段:在保持所有测试通过的同时,提升代码质量。清理重复,改进命名,增强结构。

实现概述

你可以在VS Code中使用自定义代理实现AI辅助的TDD工作流程。TDD流程的每个阶段(红、绿、重构)都有特定目标,并需要不同的AI行为。你为每个阶段创建一个自定义代理,定义该阶段的具体角色和指南。

通过自定义代理切换,你可以在AI完成任务后从一个阶段过渡到下一个阶段。自定义代理以镜像TDD工作流程的循环连接:

  • 红色阶段→在考试失败后交给绿色阶段
  • 绿→阶段运行测试以验证实现,然后交接到重构阶段
  • 重构阶段→运行测试以确保它们仍然通过,然后交回红阶段开始下一周期

如果你已经建立了测试规范,可以使用自定义指令来设置测试上下文,指导AI生成符合你项目标准的测试。

下图展示了定制代理如何协同实现TDD工作流程,切换实现了阶段间的平滑过渡。

图示展示了VS Code的TDD实现图,包含测试指令和红、绿、重构阶段的自定义代理。

提示

你可以通过在启动周期前添加规划阶段来进一步提升TDD工作流程。你可以使用内置的计划代理,或创建自定义规划代理,帮助澄清需求并识别需要通过测试覆盖的边缘案例。

步骤1:制定检测指南

如果你已经建立了测试惯例和实践,可以创建一个自定义指令文件(testing.instructions.md帮助AI生成符合你项目标准的测试。

这有帮助的原因:如果没有明确的测试规范,AI可能会生成与项目风格不符、使用不一致模式或遗漏重要测试场景的测试。

制定测试指南:

  1. 在命令调色板中运行聊天:创建指令文件命令,在你的工作区创建一个新的指令文件。

    • 精选.github/instructions在你的工作区创建指令文件。
    • 输入“testing”作为指令文件的名称。
    注释

    通过使用*.instructions.md文件代替copilot.instructions.md你可以选择性地将这些测试指南应用于项目中的测试文件,而不是将它们包含在所有 AI 交互中。

  2. 更新说明应用元数据,可以自动应用到测试文件上。同时设置描述元数据表明这些指令提供了测试上下文。

    以下示例更新了应用用于针对所有文件的字段测试/目录:

    ---
    description: 'Use these guidelines when generating or updating tests.'
    applyTo: tests/**
    ---
    
  3. 将项目的测试指南添加到说明文件正文中。

    以下示例为测试约定提供了起点:

    ---
    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红色阶段的“TDD-red”定制代理。该定制代理仅负责根据所提供需求编写失败测试,不应实现任何应用代码。完成后,该代理会交给绿色阶段的定制代理。

为什么这样有用:如果没有聚焦模式,AI可能会把实现建议和测试创建混在一起,从而忽略TDD中先写测试的核心原则。

以创建.github/agents/TDD-red.agent.md红相定制代理

  1. 在命令面板中运行聊天:新自定义代理命令。

    • 精选.github/agents在你的工作区创建自定义代理定义。
    • 输入“TDD-red”作为定制代理的名称。
  2. 更新自定义代理定义,描述红阶段的指导方针和规则,并指定向绿阶段自定义代理切换。

    如下TDD-red.agent.mdFile为红色阶段提供了起点。

    ---
    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绿色阶段的“TDD-green”定制代理。该自定义代理仅负责编写使测试通过的最小实现代码,而不修改测试代码。实现后,该代理运行测试以验证通过,然后交给重构阶段的定制代理。

以创建.github/agents/TDD-green.agent.md绿阶段定制代理

  1. 在命令面板中运行聊天:新自定义代理命令。

    • 精选.github/agents在你的工作区创建自定义代理定义。
    • 输入“TDD-green”作为定制代理的名称。
  2. 更新自定义代理定义,描述绿色阶段的指南和规则,并指定向重构阶段的自定义代理切换。

    如下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重构”定制代理,专注于TDD的重构阶段,以提升代码质量,同时保持所有测试通过。该代理负责清理代码、消除重复、改进命名和增强结构,同时不改变功能。重构后,该代理运行测试以确保仍通过,然后交回红阶段开始下一个TDD周期。

以创建.github/agents/TDD-refactor.agent.md重构阶段定制聊天代理

  1. 在命令面板中运行聊天:新自定义代理命令。

    • 精选.github/agents在你的工作区创建自定义代理定义。
    • 输入“TDD-refactor”作为定制代理的名称。
  2. 更新自定义代理定义,描述重构阶段的指导方针和规则。

    如下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 工作流程的功能。

  1. 打开聊天视图,从代理下拉菜单中选择TDD红色代理。

  2. 提供一个提示,描述你想测试的功能或行为。

    例如:

    Write tests for user registration with email validation and password requirements.
    
  3. 查看生成的测试,并使用切换动作来过渡TDD周期:

    • 编写测试后,选择TDD Green实现使测试通过的最小代码
    • 绿色代理在实现后会自动运行测试
    • 测试通过后,选择TDD重构以提升代码质量
    • 重构代理在重构后会自动运行测试,以确保它们仍然通过
    • 选择TDD Red以开始带有额外功能的下一个循环

故障排查与最佳实践

AI常见的TDD陷阱

运行TDD而不切换:用单个代理完成整个TDD循环,可以让人工脱离循环。切换提供了控制点,你可以评估每一步,验证AI的工作,并在进入下一阶段前引导代理朝正确方向前。

缺乏特征的测试覆盖:TDD代理专注于让现有测试通过,不会实现没有相应测试的功能。确保规范中的每个要求都有测试覆盖,然后才期望实现包含测试覆盖。

跳过红色阶段:AI可能会建议在写测试前先实现代码。

过度实施:AI可能生成的代码超过当前测试所需的数量。批判性地审查实施,消除不必要的复杂性。

测试实现细节:测试应验证行为,而非实现。如果重构需要更改测试,测试可能与实现细节耦合得太紧。

测试覆盖不完整:AI可能会遗漏边缘情况或错误条件。批判性地审查生成的测试,并要求额外的测试涵盖边界条件、错误情景和边缘情况。

与人工智能合作的TDD最佳实践

为任务选择合适的模型:不同的语言模型各有优势。考虑使用推理模型进行复杂测试生成和边缘情况识别。在聊天视图中使用模型选择器在你的TDD工作流程中切换模型,或者定义模型在你的定制代理房产中。

验证测试质量:AI生成测试后,复核以确认失败原因正确。在实现前先跑测试,确认它能捕捉到缺失的功能。

保持渐进式进步:在TDD循环中迈出小步伐。写一个测试,实现最小代码,重构,然后重复。小迭代可以防止重大错误,保持代码库正常运行。

频繁运行测试:在更改后立即执行测试。测试前不要积累多次更改。频繁的测试运行能提供快速反馈,并及早发现问题。

以测试覆盖率为参考:高覆盖率不保证质量,但覆盖率低表示未测试行为。让AI建议对未暴露的代码路径进行测试。

保持测试独立性:测试应按任意顺序运行,不会影响彼此。如果测试依赖于执行顺序或共享状态,则重构使其独立。

根据需要更新测试上下文:随着项目的发展,更新说明文件中的测试指南,以反映新的惯例、框架或实践。

了解更多关于VS Code测试和AI定制的信息: