triage-flaky-test について
特定の不安定なテストを調査し、失敗履歴や分類を確認して、修正・隔離・エスカレーションを提案するエージェントスキルです。`dd-pup` スキルが必要で、Datadog MCP ツールまたは `pup` CLI を利用します。
主な機能
- 01不安定なテストの詳細取得
- 02直近の失敗履歴を分析
- 03影響を受けたパイプラインの把握
- 04根本原因に基づく対応提案
- 05承認後のテスト隔離
活用シーン
- 01断続的なテスト失敗の原因特定
- 02CI 失敗の影響範囲の評価
- 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を入力して読み込まれたか確認します。
詳細
不安定なテストのトリアージ
1 行での概要:特定の不安定なテストを調査します。履歴、失敗パターン、カテゴリを確認し、修正、隔離、エスカレーションのいずれかを推奨します。
必要条件:dd-pup スキル(pup CLI のインストールおよび認証が必要です)。
バックエンド
検出 — 呼び出しのたびに、アクションを実行する前に、使用するバックエンドを判定します。
- ユーザーがどこかで
--backend pupを渡した場合 → 直ちに pup モードを使用します。手順 2~4 はスキップします。 - 利用可能なツールに
get_datadog_flaky_testsがあるか確認します。 - 存在する場合 → 全体を通して MCP モードを使用します。このスキルのワークフローの各セクションに記載された名前どおりにツールを呼び出します。
- 存在しない場合 →
pupを実行できるか確認します。Bash 経由でpup --versionを実行します。コマンドが正常終了した場合(終了コード 0)、pup を利用できます。 - pup が応答する場合 → 全体を通して pup モードを使用します。このファイルの末尾にあるツールリファレンス付録を使って、すべてのツール呼び出しを変換します。
- どちらも利用できない場合 → 処理を中止し、ユーザーに次のように伝えます。
"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) |
| リポジトリ | 小文字、スキーマなしの URL(例:github.com/org/repo)。指定がない場合は git remote get-url origin から導出します。 |
ワークフロー
STEP 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
検証時のフォールバック: STEP 1 で結果が返されない場合は、リポジトリのフィルターを指定せずに検索して、正しいリポジトリを確認します。
Tool: search_datadog_test_events
query: @test.name:"<test-name>"
from: now-30d
test_level: test
結果から @git.repository.id_v2 を抽出し、確認した値を使って STEP 1 を再試行します。
STEP 1 — 不安定なテストの詳細を取得
推奨 — 判明している場合は fingerprint_fqn を使用します(fingerprint_fqn は有効な CI Visibility 検索ファセットです)。
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 でフィルターしないでください。状態にかかわらずテストを返します。
注:クエリフィルターのファセットは flaky_test_state ですが、返されるレスポンス属性は flaky_state です。クエリフィルターに flaky_state:active を使用しないでください。
結果から次の情報を抽出します。
fingerprint_fqn— テストを一意に識別する ID。STEP 5 の書き込み呼び出しでidとして使用します。存在しない場合は、隔離に進まないでください。STEP 5 を参照してください。flaky_state— 現在の状態(active / quarantined / disabled / fixed)test_stats.failure_rate_pct— 失敗する実行の割合flaky_category— 根本原因のカテゴリcodeowners— 担当チームpipeline_stats.total_lost_time_ms— CI で失われた合計時間
STEP 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値(STEP 3)
STEP 3 — 影響範囲を確認
STEP 2 のパイプライン ID を使って、影響を受けたパイプラインの数を数えます。
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
STEP 2 の最初の 10 個のパイプライン ID を使用します(上限は 10 個です。さらに ID がある場合は 2 回目のバッチを実行し、バッチ間で @ci.pipeline.name ごとの件数を合算して結果をまとめます)。影響範囲は、影響を受けた一意のパイプラインの合計数と、失敗が特定のブランチに限定されるか広範囲に発生しているかとして報告します。
注:パイプラインの失敗が、必ずしもこの不安定なテストだけに起因するとは限りません。影響範囲は決定的な件数ではなく、状況を示すシグナルとして扱ってください。
STEP 4 — 修正または隔離を推奨する
STEP 1 の flaky_category と STEP 2 のエラーメッセージを使用します。
まず根本原因を特定します:
- エラーのトレース全体を下から上へ読みます。連鎖したエラーは実際の原因を隠すことがあります。根本原因は最初の行ではなく、最も内側のエラーです。
- 非決定性の正確な原因(競合、順序、古い状態、タイミング)を特定します。
- 根本原因が CI インフラストラクチャの問題(ランナーが利用できない、Docker デーモンの障害、ネットワーク障害)の場合、コード修正を提案してはいけません。
infraに分類し、再試行を推奨します。 - 根本原因が不明で、スタックトレースから確認できない場合は、修正を見送り、隔離に進みます。
適切なレイヤーで修正します:
- テストの問題 → テストまたはテストヘルパーのみを修正します。
- テストで明らかになった本番環境のバグ → 本番コードを修正します。
- 複数のテストで使用される共有ヘルパー → ヘルパーを修正し、すべての呼び出し箇所も更新します。
禁止事項 — 以下を提案してはいけません:
- タイミング調整:タイムアウトの延長、スリープの追加、時間枠の拡大、再試行の追加。
- 問題の隠蔽:アサーションを緩和する(例:完全一致 → 1 件以上)こと、検証の削除。
- 部分的な修正:複数の呼び出し箇所で根本原因を共有しているのに、そのうち 1 箇所だけを変更すること。
カテゴリ別の修正パターン:
| カテゴリ | アプローチ |
|---|---|
timeout | 時間のかかる操作を特定し、同期的または決定論的にします。タイムアウト定数を単に引き上げてはいけません |
concurrency | 決定論的な同期(バリア、チャネル、ロック)を追加し、テスト間の共有可変状態を取り除きます |
network | 境界でネットワーク呼び出しをモックまたはスタブ化します。テストに実際の接続が必要な場合は、テストサーバーを使って分離します |
time | 制御可能なクロックを注入し、実時間に対するアサーションを相対的またはイベント駆動型のチェックに置き換えます |
order_dependency | セットアップ/ティアダウンでテスト状態を分離し、実行順序やグローバル状態への依存をなくします |
environment_dependency | 環境変数と外部設定をモックし、共有ディレクトリやシングルトンではなくテスト専用のフィクスチャを使います |
resource_leak | テストで開いたリソースがすべてティアダウン時に閉じられるようにし、失敗時にも実行されるクリーンアップフックを使います |
randomness | テスト実行の乱数シードを固定し、ランダムな生成ではなく決定論的な入力を使います |
asynchronous_wait | 固定時間のスリープを、ハードタイムアウト付きの条件ポーリングまたはイベント/シグナル駆動型の待機に置き換えます |
io | ティアダウン時にクリーンアップされる一時ファイル/ディレクトリを使い、ファイルシステムとのやり取りをモックまたはスタブ化します |
unknown | 修正を見送り、隔離に進みます |
コード変更を提案する前に、以下をすべて確認してください。1 つでも満たさない場合は修正を見送り、隔離を推奨します:
- 根本原因は表面的な症状ではなく、トレース内の最も内側のエラーです。
- 失敗の原因は 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 を実行 |