项目文章联系
← 返回文章列表
技术实践2026-09-19

Test Repair Agent

一、项目整体流程

CI 测试失败
  ↓
Playwright 读取测试报告
  ↓
生成结构化失败上下文
  ↓
绑定 Gerrit change、revision 和当前代码
  ↓
校验报告中的文件、函数、代码片段和行号
  ↓
读取 OpenAPI / 领域契约
  ↓
沿测试 → 接口 → Application → Domain → Infrastructure 回溯
  ↓
定位最早可观测偏离点
  ↓
判断代码、测试、Mock 或运行环境问题
  ↓
输出可追溯修复建议

Playwright 只负责确定性提取报告事实:日志、堆栈、失败步骤、报告链接和测试操作。输出上下文时区分:

facts      报告直接观察到的事实
locations  经当前 revision 校验后的候选位置
warnings   路径漂移、字段缺失、版本冲突等不确定性

Agent 不直接使用报告原始行号作为修改位置。它需要结合文件路径、函数名、代码片段和 Gerrit Diff 重新定位;证据不足时降级到函数级、文件级,或输出 need_evidence。

二、Test Repair Skill 的核心流程

读取失败事实
  ↓
确认代码位置
  ↓
提取测试预期
  ↓
回溯领域调用链
  ↓
寻找最早偏离点
  ↓
判断根因类型
  ↓
生成修复方案
  ↓
反思与结果校验

1. 只读事实,不下结论

Skill 首先读取:

  • 测试名称和失败操作;
  • 异常、堆栈和响应;
  • 当前 revision 和 Gerrit Diff 摘要;
  • 初始代码位置候选;
  • 测试输入、Fixture 和 Mock。

这一阶段禁止输出根因和修改方案,避免把模型猜测写入事实上下文。

2. 位置是进入诊断的门禁

报告行号可能来自旧 revision,或者来自构建环境路径。Skill 需要让程序完成:

报告路径 → 仓库相对路径
报告行号 → 当前 revision 代码
函数名 / 片段 → 当前代码唯一匹配
候选位置 → Gerrit Diff 关联

定位结果分为:

LINE      行范围可以确认
FUNCTION  只能确认函数
FILE      只能确认文件
NEED_EVIDENCE  无法确认位置

没有通过位置门禁时,Skill 不允许进入修复判断。因为后续即使调用链分析正确,也可能是在错误代码上推理。

3. 还原测试真正验证的行为

Skill 需要从测试中提取:

  • 输入数据和前置状态;
  • Fixture、Mock 和外部依赖;
  • 调用的 API、Command 或事件;
  • 断言期望和实际结果;
  • 需要满足的领域前置条件。

例如:

输入:customer_id = U001
操作:POST /orders
预期:创建订单成功,buyer_id = U001
实际:buyer_id 为空,领域校验失败

4. 沿领域边界回溯

Skill 不按“最后报错的目录”直接归因,而是沿调用链检查:

Test Fixture
  → OpenAPI Interface
  → Application Service
  → 其他 Bounded Context
  → Domain Aggregate
  → Repository / Event / Shared Infrastructure

OpenAPI 用来检查接口输入输出;Application 用来检查 DTO 到 Command 的映射;Domain 用来检查业务不变量;Infrastructure 用来检查 RPC、数据库、消息和配置;测试层用来检查 Fixture 和 Mock 是否符合契约。

三、最难的细节:如何找到最早偏离点

“最早偏离点”不是堆栈中最早出现的文件,而是:

例如失败信息是:

POST /orders 返回 500
ValueError: buyer_id is required

回溯表:

| 顺序 | 层级 | 预期 | 实际 | 判断 |

|---:|---|---|---|---|

| 1 | Test Fixture | customer_id = U001 | 有值 | 正常 |

| 2 | HTTP Interface | DTO 有 customer_id | 有值 | 正常 |

| 3 | Application | buyer_id = U001 | 为空 | 首次偏离 |

| 4 | Domain | buyer_id 非空 | 为空 | 正确触发校验 |

| 5 | HTTP Response | 返回 201 | 返回 500 | 结果传播 |

结论:

失败暴露位置:Order Domain
最早偏离位置:Order Application 的字段映射
根因类型:代码回归

如果第 3 步正常,继续检查 User RPC:

User 服务返回字段错误 → User Context 或 Order ACL
只有 Mock 字段错误 → 测试 / Mock 问题
RPC 超时、数据库不可用 → 运行环境问题
领域规则与新业务契约冲突 → Domain 或测试预期问题

Skill 必须区分:

真实最早偏离点
最早可观测偏离点

如果中间没有日志或 Trace,只能输出:

当前只能确认偏离发生在 Application 到 Domain 之间,
需要补充 Command 组装日志或运行 Trace。

不能伪造精确函数和行号。

四、根因分类规则

代码问题

当前 Gerrit Diff 改变了失败路径,并且代码行为违反 OpenAPI、跨领域契约或领域不变量。

测试用例问题

代码符合当前业务契约,但测试仍验证旧行为或错误预期。

Mock / Fixture 问题

测试准备的数据或 Mock 返回结构不符合当前接口、领域或事件契约。

运行环境问题

业务输入和代码契约均满足,但网络、权限、数据库、配置、依赖或超时导致失败。

没有足够证据时,Skill 输出候选根因、已有证据和缺失证据,不强行选择一个答案。