mcpField
T
triage-flaky-test

triage-flaky-test

github.com/datadog-labs测试与质量180253 次安装6 天前更新
代码仓库

关于 triage-flaky-test

用于调查单个不稳定测试的 Agent 技能,可查看失败历史、模式和类别,并建议修复、隔离或升级。它依赖 dd-pup 技能,并可通过 Datadog MCP 工具或 pup CLI 工作。

主要功能

  1. 01查看不稳定测试详情
  2. 02分析近期失败历史
  3. 03统计受影响流水线
  4. 04按根因提出处理建议
  5. 05获批后隔离测试

适用场景

  1. 01定位测试失败的间歇性根因
  2. 02判断失败影响范围
  3. 03为高频失败测试制定隔离方案

MCP 相关

若可用,此技能会调用 Datadog MCP 工具查询测试和流水线数据,并在获批后更新测试状态;否则可通过 pup CLI 操作。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/datadog-labs/agent-skills --skill triage-flaky-test

安装后在 Claude Code 中输入/triage-flaky-test确认已加载。

详细介绍

不稳定测试分诊

一句话概述:调查某个不稳定测试——获取历史记录、失败模式和类别,然后建议修复、隔离或升级处理。

需要:dd-pup 技能(已安装并通过身份验证的 pup CLI)。


后端

检测——每次调用开始时,采取任何操作之前,先确定要使用的后端:

  1. 如果用户在任何位置传入了 --backend pup → 立即使用 pup 模式。跳过步骤 2–4。
  2. 检查可用工具中是否包含 get_datadog_flaky_tests。
  3. 如果包含 → 全程使用 MCP 模式。严格按照本技能工作流各部分中的名称调用工具。
  4. 如果不包含 → 检查 pup 是否可执行:通过 Bash 运行 pup --version。如果命令成功退出(退出代码为 0),则 pup 可用。
  5. 如果 pup 有响应 → 全程使用 pup 模式。使用本文件底部的工具参考附录转换每次工具调用。
  6. 如果两者都不可用 → 停止并告知用户:

    “Datadog MCP 服务和 pup CLI 均不可用。请连接 MCP 服务或安装 pup(brew install datadog-labs/pack/pup)。”

pup 调用规则:

  • 通过 Bash 调用。pup 始终输出 JSON——直接解析。
  • 传给 pup 的仓库 ID 必须全部为小写(API 不接受大小写混合的值)。
  • 以 - 开头的排序值必须使用 = 语法:--sort="-last_flaked"(不要使用 --sort "-last_flaked")。
  • 如果 pup 返回 401/403,请告知用户运行 pup auth refresh 或 pup auth login。

输入

参数说明
测试名称完整限定的测试名称(例如 TestMyFunc 或 com.example.MyTest)
仓库全小写、不带 schema 的 URL(例如 github.com/org/repo)。如果未提供,则从 git remote get-url origin 推导。

工作流

步骤 0 — 解析输入

如果未提供仓库,则从 git 推导仓库 ID:

git remote get-url origin
# Strip protocol and trailing .git, then lowercase the result
# e.g. https://github.com/DataDog/my-repo.git → github.com/datadog/my-repo

验证回退: 如果步骤 1 未返回结果,则不使用仓库筛选条件进行搜索,以确认正确的仓库:

Tool: search_datadog_test_events
query: @test.name:"<test-name>"
from: now-30d
test_level: test

从结果中提取 @git.repository.id_v2,并使用确认后的值重试步骤 1。

步骤 1 — 获取不稳定测试详情

首选——已知 fingerprint_fqn 时使用它(fingerprint_fqn 是有效的 CI Visibility 搜索 facet):

Tool: get_datadog_flaky_tests
query: fingerprint_fqn:<fqn>
sort_field: last_flaked
sort_order: desc

回退——使用名称 + 套件 + 仓库:

Tool: get_datadog_flaky_tests
query: @test.name:"<test-name>" @test.suite:"<suite>" @git.repository.id_v2:"<repo>"
sort_field: last_flaked
sort_order: desc

如果未知,则省略 @test.suite。不要按 flaky_test_state 筛选——无论测试处于何种状态,都要返回该测试。

注意:查询筛选 facet 是 flaky_test_state;返回的响应属性是 flaky_state——不要使用 flaky_state:active 作为查询筛选条件。

从结果中提取:

  • fingerprint_fqn — 唯一的测试标识符;在步骤 5 的写入调用中用作 id。如果缺失,则不要继续隔离——请参阅步骤 5。
  • flaky_state — 当前状态(active / quarantined / disabled / fixed)
  • test_stats.failure_rate_pct — 运行失败的百分比
  • flaky_category — 根因类别
  • codeowners — 负责的团队
  • pipeline_stats.total_lost_time_ms — CI 总耗时损失
步骤 2 — 获取近期失败历史
Tool: search_datadog_test_events
query: @test.name:"<test-name>" @test.suite:"<suite>" @test.status:fail @git.repository.id_v2:"<repo>"
from: now-7d
test_level: test

提取:

  • 错误消息和堆栈跟踪(@error.message、@error.stack)
  • 失败分支(@git.branch)——仅特定分支还是普遍出现
  • 频率模式——随机时间点还是由特定条件触发
  • 用于评估影响范围的唯一 @ci.pipeline.id 值(步骤 3)
步骤 3 — 检查影响范围

使用步骤 2 中的 pipeline ID 统计受影响的不同 pipeline 数量:

Tool: aggregate_datadog_ci_pipeline_events
query: @ci.status:error @ci.pipeline.id:(<id1> OR <id2> OR ...) @git.repository.id_v2:"<repo>"
ci_level: pipeline
aggregation: count
group_by: ["@ci.pipeline.name"]
from: now-7d

使用步骤 2 中最先出现的 10 个 pipeline ID(最多 10 个;如果还有更多,则运行第二批查询,并按批次对每个 @ci.pipeline.name 的数量求和后合并结果)。报告影响范围时,说明受影响的唯一 pipeline 总数,以及失败是仅发生在特定分支还是普遍出现。

注意:pipeline 失败不一定完全由此不稳定测试导致——应将影响范围视为参考信号,而非确定的计数。

步骤 4 — 建议修复或隔离

使用步骤 1 中的 flaky_category 和步骤 2 中的错误消息。

先找根本原因:

  • 从底部向上阅读完整的错误跟踪信息——链式错误会掩盖真正的原因;最内层的错误才是根本原因,而不是第一行。
  • 找出不确定性的确切来源(竞争、顺序、过时状态、时序)。
  • 如果根本原因是 CI 基础设施问题(运行器不可用、Docker 守护进程故障、网络中断)→ 不要提出代码修复方案;将其分类为 infra,并建议重试。
  • 如果根本原因不确定,且无法通过堆栈跟踪确认 → 跳过修复,转到隔离。

在正确的层级修复:

  • 测试问题 → 仅在测试或测试辅助工具中修复。
  • 测试暴露的生产环境 Bug → 在生产代码中修复。
  • 多个测试共用的辅助工具 → 修复该辅助工具,并更新所有调用点。

禁止——不要提出以下方案:

  • 时序技巧:延长超时时间、添加休眠、扩大时间窗口、添加重试。
  • 掩盖问题:放宽断言(例如,将精确匹配改为至少 1 个)、删除验证。
  • 局部修复:当多个调用点存在相同根本原因时,只修改其中一个。

各类别的修复模式:

类别方法
timeout找出耗时操作,并使其同步或确定化——不要只提高超时常量
concurrency添加确定性同步机制(屏障、通道、锁);消除测试之间共享的可变状态
network在边界处模拟或替代网络调用;如果测试需要真实连接,则使用测试服务器隔离连接
time注入可控时钟;将墙上时钟断言替换为相对检查或事件驱动检查
order_dependency使用 setup/teardown 隔离测试状态;消除对执行顺序或全局状态的依赖
environment_dependency模拟环境变量和外部配置;使用测试专属的固定数据,而非共享目录或单例
resource_leak确保测试中打开的每个资源都在 teardown 时关闭;使用即使在失败时也会运行的清理钩子
randomness为测试运行固定随机种子;使用确定性输入,而非随机生成的数据
asynchronous_wait将固定休眠替换为条件轮询,或带硬性超时的事件/信号驱动等待
io使用在 teardown 时清理的临时文件/目录;模拟或替代文件系统交互
unknown跳过修复尝试 → 转到隔离

提出代码更改之前,请验证以下所有事项——任何一项未通过,都应跳过修复并建议隔离:

  • 根本原因是跟踪信息中的最内层错误,而非表面症状。
  • 失败属于代码问题,而非 CI 基础设施问题。
  • 修复能够消除根本原因(而非仅降低出现不稳定的概率)。
  • 修复位于正确的层级(测试、生产代码或共享辅助工具)。
  • 所有共享代码的调用点都已更新。
  • 没有引入时序技巧或放宽断言。

决策:

  • 如果类别为 unknown,或上述验证未通过 → 跳过修复,建议隔离
  • 如果类别已知、根本原因已确认且修复有效 → 提出具体的代码更改
第 5 步——生成分诊简报并采取行动
Flaky Test Triage Brief
=======================
Test:           <fully qualified test name>
Service:        <@test.service>
Category:       <flaky_category>
Failure Rate:   <test_stats.failure_rate_pct>%
Duration Lost:  <pipeline_stats.total_lost_time_ms>ms
Codeowners:     <codeowners>
Blast Radius:   <N> pipelines (<branch-specific | widespread>) [approximate — other failures in the same pipeline runs may not be related]

Evidence:
  <1-2 key error message lines from STEP 2>

Recommendation: <fix | quarantine | escalate>
Confidence:     <high | medium | low>
Action:         <specific next step>

决策阈值:

  • failure_rate_pct > 10 或影响范围 > 5 条流水线 → 隔离
  • failure_rate_pct ≤ 10,且类别已知并且有明确的修复方案 → 修复
  • failure_rate_pct ≤ 10,且类别为 unknown → 将分诊简报升级给代码所有者

如果建议隔离,请先向用户说明并要求其明确批准,然后再写入:

Proposed action: quarantine "<test-name>"
  id (fingerprint_fqn): <fingerprint_fqn from STEP 1>
  Effect: test still runs but failures are suppressed (CI will not be blocked)
  Reversible: yes — set new_state: active to restore

Approve? (yes/no)

如果步骤 1 未返回 fingerprint_fqn(测试尚未进入 FTM,或查询未返回结果):不要尝试写入。请显示错误,并要求用户直接打开 Flaky Test Management UI 手动隔离。

只有在获得明确批准且确认了 fingerprint_fqn 后:

MCP 模式:

Tool: update_datadog_flaky_test_states
test_ids: ["<fingerprint_fqn>"]
new_state: quarantined

pup 模式:

cat > /tmp/flaky-update.json <<'EOF'
{
  "data": {
    "type": "UpdateFlakyTestsRequest",
    "attributes": {
      "tests": [{"id": "<fingerprint_fqn>", "new_state": "quarantined"}]
    }
  }
}
EOF
pup test-optimization flaky-tests update --file /tmp/flaky-update.json

撤销操作:使用 new_state: active / "new_state": "active" 重复上述操作。


工具参考

本附录仅适用于 pup 模式。在 MCP 模式下,请直接使用工作流各部分中的工具名称。

MCP 工具pup 命令
get_datadog_flaky_tests(按 fingerprint_fqn 查询)pup cicd flaky-tests search --query "fingerprint_fqn:<fqn>" --sort="-last_flaked" --limit 5
get_datadog_flaky_tests(按名称 + 套件 + 仓库查询)pup cicd flaky-tests search --query "@test.name:\"...\" @test.suite:\"...\" @git.repository.id_v2:\"...\"" --sort="-last_flaked" --limit 10
search_datadog_test_events(验证备用方案)pup cicd tests search --query "@test.name:\"<test-name>\"" --from 30d --limit 5
search_datadog_test_events(失败历史)pup cicd tests search --query "@test.name:\"...\" @test.suite:\"...\" @test.status:fail @git.repository.id_v2:\"...\"" --from 7d --limit 20
aggregate_datadog_ci_pipeline_events(影响范围)pup cicd events aggregate --query "@ci.status:error @ci.pipeline.id:(...) @git.repository.id_v2:\"...\"" --compute count --group-by "@ci.pipeline.name" --from 7d
update_datadog_flaky_test_states将请求正文写入 /tmp/flaky-update.json,然后执行 pup test-optimization flaky-tests update --file /tmp/flaky-update.json

评论

支持 Markdown