Microsoft宣布推出code-testing-generator,这是一个用于生成单元测试的多语言开源代理。该代理不只是创建看似正确的测试,而是首先从项目代码库中学习,然后确定需要测试的代码、所使用的测试框架、文件放置位置以及构建和运行命令,随后验证测试是否能够在代码库的常规测试路径中被发现。
该代理作为dotnet/skills代码库中的dotnet-test扩展提供。它会隔离被测代码,同时为外部服务和其他依赖项创建模拟。当前范围不包括集成测试、端到端测试、浏览器测试或性能测试。
在编写测试前先理解代码库
代理不会直接开始生成代码,而是会查找需要测试的部分,识别所使用的语言和测试框架,检查现有测试,以了解新测试的放置位置和编写方式。它还会确定构建命令和测试运行命令。
这种方式有助于避免出现这样的情况:新的测试项目能够单独成功构建和运行,但没有被纳入解决方案或持续集成环境使用的测试命令。因此,代理会检查代码库发现测试的方式,并确认新测试能够在其中显示。
代理会根据请求规模选择工作级别:
- 直接:读取相关代码,编写测试,然后验证结果。
- 单次传递:进行一次搜索和规划,然后执行计划。
- 迭代:重复搜索、规划和执行循环,以覆盖大型请求或达到指定的覆盖率目标。
验证测试是否有用,而不仅仅是验证测试是否成功
对于较大的任务,代理会列出需要测试的代码,从最简单的部分开始,然后转向依赖项更多的代码。它还会将每种行为与测试文件关联起来,遵循项目的本地惯例,并在工作过程中运行测试。
如果生成的代码无法构建,代理会进行修复;如果某个断言不正确,它会返回源代码并修正测试。代理在生成测试时不会修改生产代码,也会避免编写调用外部地址、打开端口或依赖精确计时的单元测试。
在完成前,代理会执行一组检查,包括进行一些应当使测试失败的小改动,这是一种简化的变异测试;查找薄弱或缺失的断言;并确认每个所需场景都有对应测试。它还会构建整个工作区并运行完整的测试集,同时验证代码库中的测试命令能否找到新测试。
内部测试结果
在最近一次内部基准测试中,该代理完成了152项任务中的140项,完成率为92.1%;使用相同模型的标准版 Copilot 完成了120项,完成率为78.9%。Microsoft表示,失败案例数量下降了63%。
最大的差异出现在含义模糊、将大多数决策留给代理的请求中;专业代理完成了89项任务中的79项,而标准版 Copilot 完成了59项,失败案例从30项降至10项。对于详细请求,结果则较为接近,代理完成了63项任务中的61项。
在要求为代码中的特定更改编写测试的15项任务中,代理完成了全部任务,而标准版 Copilot 一项也未完成。在共同结果方面,两个系统共同完成了119项任务,专业代理单独完成了21项任务,标准版 Copilot 单独完成了1项任务,两个系统均失败了11项任务。
该代理生成了6,963个测试,而标准版 Copilot 生成了7,129个测试;最终平均行覆盖率分别为72.4%和72.2%,平均分支覆盖率分别为49.8%和49.1%。此外,专业代理的平均任务耗时为359秒,标准版 Copilot 为380秒。Microsoft表示,收益来自可靠性,而不是生成更多测试。
支持多种语言并提供扩展
随附指南包含对 .NET、Python、TypeScript、JavaScript、Java、Go、Ruby、Rust、Swift、Kotlin、PowerShell 和 C++ 的支持。测试显示,该代理能够学习每个代码库的惯例,而不是将 C# 模式应用于所有项目。
在针对 SWE Atlas 基准的另一项包含44项任务的测试中,该代理完成了16项,完成率为36.4%;标准版 Copilot 完成了12项,完成率为27.3%。此外,生成的测试通过了550个测试案例,并成功捕获了360个注入错误;标准系统对应的数字分别为493个和316个。Microsoft承认,该基准更加困难,其完成率也低得多。
该扩展可用于 GitHub Copilot CLI,也可通过扩展支持在 Visual Studio Code 和 VS Code Insiders 中使用,但该支持仍处于预览阶段。Microsoft也在开发对 Visual Studio 的支持。要在 GitHub Copilot CLI 中安装该扩展,用户需要使用/plugin marketplace add dotnet/skills命令添加扩展市场,然后使用/plugin install dotnet-test@dotnet-agent-skills进行安装,重启 CLI,并选择code-testing-generator代理。