测试用例生成中的上下文问题
生成测试是AI coding agent最常见的实际应用场景之一。然而,如果没有运行时代码覆盖数据,AI coding agent在推断测试缺口时只能静态分析源文件和测试文件,以推测哪些代码可能已被覆盖。这种方法并不可靠:agent无法区分一个通过多层间接调用的函数和一个从未执行过的函数,也无法可靠地检测死代码。
代码覆盖率解决方案(如Coco)可将真实测试运行中精确到每个插桩点的执行数据作为上下文提供给agent。后续调用Coco可以构建反馈循环,推动测试代码生成工作流在搜索空间中朝着覆盖目标持续迭代。
在本系列博客的第一篇 第1部分 中,我们借助Coco CLI工具实现了上述工作流,用于生成单元测试并最大化代码覆盖率。现在,我们正式发布Coco MCP Server Preview,开发者、测试工程师、管理者以及CI/CD流水线均可在生成式AI驱动的工作流中加以使用。
初次接触代码覆盖率?
代码覆盖率衡量源代码中哪些部分已被测试执行。所用的指标可以是已执行的函数、代码行或分支,也可以是更复杂的指标,例如评估语句中的独立条件。
您将使用 Coco instrumented(插桩)构建版本,它的作用类似于计数器:记录已执行代码行的计数,并将这些行与您的测试用例相匹配。应用程序的功能不会发生变化,您可以对所有测试(包括手动测试和功能测试)使用同一个插桩构建版本。
Coco MCP Server介绍
Coco MCP Server是一个 模型上下文协议(MCP)服务器,它将Coco命令行界面(CLI)工具封装在一个结构化接口中。Agent无需直接调用cmreport 和cmcsexeimport 并解析返回输出,而是调用MCP Server中专门构建的工具,获取结构化数据并高效处理,同时不会污染上下文窗口。
MCP是连接AI coding agent与外部工具和数据源的事实行业标准。所有主流AI coding agent均支持该协议并充当MCP主机,包括VS Code中的GitHub Copilot和Claude Code——因此Coco MCP Server可跨所有MCP主机使用,无需对工作流提示词做任何修改。下图展示了具体配置:
Coco MCP Server的优势包括:
Token敏感性: 通过去除覆盖率摘要中的冗余字段,以及对覆盖报告各节采用流式传输而非全量加载,降低所需的token数量并限制上下文规模。Coco MCP Server还通过渐进式披露的方式提供覆盖率数据,使AI coding agent最初仅接收最少的有用信息,随后在需要时获取更精准、更详细的内容。
CLI工具易用性:Coco CLI参数标志较为繁琐,相关复杂性已封装在MCP工具调用中。
内置工作流:Coco MCP Server内置了使用代码覆盖时必须定义的工作流。
我们认为上述功能对于大型项目尤为实用——对于小型项目,AI coding agent直接使用Coco CLI工具仍然可以取得良好效果。
Coco MCP Server提供 的工具
如前所述,工具集经过结构化设计,使agent仅获取当前决策所需的数据量,从而保持响应简洁,并使agent的上下文窗口保持专注。
check_coverage_summary
一个轻量级健全性检查,调用 cmreport 并返回单个布尔值。若为 false,表示数据库中没有执行结果,后续的报告调用将返回空数据。此时,agent 应先调用 import_execution_report 。
import_execution_report
通过cmcsexeimport将 .csexe执行报告合并到 .csmes数据库中。此调用完成后,后续所有工具均可获取覆盖率数据。
get_coverage_overview
返回全局覆盖率百分比、每文件明细以及可选的每函数明细——足以使agent识别哪些文件和函数值得深入调查。Agent以此进行优先级排序,无需逐一查看每个文件的详情。
示例输出(判定覆盖率,parser示例):
文件 | 覆盖率 | 判定覆盖点 | 复杂度 |
parser.cpp | 47.6% | 137/288 | 121 |
error.cpp | 25.0% | 9/36 | 19 |
variablelist.cpp | 47.1% | 8/17 | 11 |
functions.cpp | 0.0% | 0/17 | 7 |
parser.h | 100% | 9/9 | 7 |
error.h | 100% | 4/4 | 4 |
Global | 45.0% | 167/371 | — |
get_file_coverage_detail
返回按覆盖状态分组的精确file:line位置(unexecuted、dead-code、executed)。Agent以此精确定位编写新测试时需要针对的具体行,无需读取整个源文件并推断可能缺少的内容。
status_filter将响应范围缩小到agent需要处理的状态 (通常为 ["unexecuted"])。对于大型代码库,已执行的行数量庞大,否则将主导响应内容,而其中并无可操作的信息。
当include_tests=True时,响应还会将每个插桩点映射到执行它的测试名称列表。这在agent修改特定代码段前需要了解现有测试覆盖情况,或在针对性更改后决定运行哪些测试时非常有用。
an alyze_patch_coverage / a nalyze_patch_coverage_from_diff
该工具提供了Coco的补丁分析功能:根据补丁的差异(unified diff),它返回覆盖已修改行的现有测试集 合及其当前通过/失败状态。Agent以此判断代码变更后哪些测试面临风险——实现精准的针对性重新执行,而非运行完整测试套件。该工具接受补丁文件路径或内联差异字符串,因此agent可直接从git diff的输出中调用,无需写入中间文件。
工作流示例
以下是AI coding agent在Coco parser示例上使用Coco MCP Server的示例会话。
提示词: "构建 parser 示例并分析其当前判定覆盖率"
步骤 | Coco MCP Server | 结果 |
构建插桩二进制文件 | - | 生成 unittests.exe + unittests.exe.csexe |
健全性检查 | check_coverage_summary | has_coverage_data: false — 尚未导入结果 |
合并测试结果 | import_execution_report | .csexe 已合并至 .csmes |
确认数据可用 | check_coverage_summary | has_coverage_data: true |
获取判定覆盖率 | get_coverage_overview(decision,global + source-tree + function-tree) | 全局 45.0%;functions.cpp 0%,error.cpp 25%,parser.cpp 47.6% |
提示词: "提升 parser.cpp 的覆盖率"
步骤 | MCP 工具 | 结果 |
读取源码和现有测试 | - | 读取 parser.cpp、unittests.cpp 以了解结构 |
获取精确未执行行 | get_file_coverage_detail (status_filter: unexecuted, file: parser.cpp) | 识别出 151 个未执行插桩点 |
编写针对性测试 | - | 针对位运算、比较、算术、数学和三角函数运算符添加了新测试用例 |
重新构建插桩二进制文件 | - | 生成更新后的 unittests.exe.csexe |
合并更新结果 | import_execution_report | 新执行数据已合并 |
验证改善效果 | get_coverage_overview(decision,global + source-tree) | parser.cpp 47.6% → 88.9%;全局 45.0% → 80.1% |
后续计划
我们将持续向MCP Server中添加并提供更多Coco功能。近期候选项包括 变更风险反模式(Change Risk Anti-Patterns,CRAP)指标、对Python的支持、集成agent技能 以及QML的代码覆盖率支持。