debug-failure
テストの失敗、エラー、想定外の動きを見つけたときに、修正する前に原因を特定し、根本原因を直す skill。実装や確認の途中で問題に気づいたときに使用する。意図して失敗させたテストには使わない。
SKILL.mdskills/debug-failure/SKILL.md
GitHubDebug Failure
目的
問題を見つけたら、原因を特定してから直す。
当てずっぽうの修正は、症状を隠すか、別の問題を生みやすい。
使うタイミング
- テスト、build、型チェック、lint が失敗したとき
- エラーや想定外の動きを見つけたとき
- ユーザーから不具合を報告されたとき
TDD の RED のように、未実装を確かめるために意図して失敗させたテストには使わない。
エラーメッセージから原因と修正が一意に決まる失敗では、手順を簡略化してよい。 例として、typo による syntax error や import 漏れがある。
直す範囲
- 今回の作業で加えた変更が原因: 言われるのを待たずに直す
- ユーザーから修正を頼まれた: 直す
- それ以外: 原因と直し方の案を報告する。直すかどうかはユーザーが決める
修正を頼まれていない既存の不具合や、原因の調査だけを頼まれた場合は「それ以外」に当たる。
Workflow
- 再現する
- 範囲を絞る
- 仮説を立てて確かめる
- 根本原因を直す
- 直ったことを確かめる
- 後片付けをする
1. 再現
同じ手順で同じ失敗が起きることを確かめる。 エラーメッセージと stack trace は最後まで読む。
再現できない場合は、ログや環境の差など、起きる条件を絞る情報を集める。 一度だけ起きて再現しない失敗は、その事実を報告に残す。
再現を試す前に、接続先の設定を確かめる。 本番環境や実在の外部サービスに接続する設定なら、実行前にユーザーへ確認する。
2. 範囲の絞り込み
次の方法で、原因のある場所を絞る。
- 直近の変更を確認する
- 正しく動く経路や過去の状態と比べる
- 失敗する入力を小さくする
- 処理の境界で値を確認する
過去の状態とは、作業ツリーを書き換えない方法で比べる。 調査用のログに、credentials などの秘密情報を出力しない。
3. 仮説の確認
仮説は 1 つずつ確かめる。 「X が原因なら、Y が観察できるはず」の形で、観察できる結果を先に決める。
1 つの仮説につき、試す変更は 1 つにする。 仮説が外れた変更は、次を試す前に戻す。
4. 根本原因の修正
次のような、症状を抑えるだけの修正はしない。
- 例外を握りつぶす
- retry や sleep で失敗を隠す
- テストの期待値を、誤った実装に合わせる
既存のテストで再現できない問題は、修正前に回帰テストを追加する。 回帰テストは、利用側から見える振る舞いを検証する。
5. 修正の確認
元の再現手順で失敗しないことと、関連テストが通ることを確かめる。 修正が影響する既存の振る舞いも、影響に見合った方法で確かめる。
6. 後片付け
- 調査用に加えたログやスクリプトを取り消す
- 調査のために起動したプロセスやコンテナを止める
- 取り消すのは自分が加えた差分だけにし、Git の破壊的な操作で戻さない
止められなかったものや残したものは、報告に書く。
止まる判断
次の場合は、直すのをやめてユーザーに報告する。
- 修正を試すたびに、問題が残るか別の箇所が壊れ、それが 3 回続いた
- 再現しない失敗で、原因を絞る手がかりがなくなった
- 依頼や既存の仕様を超えて、利用者から見える振る舞い、公開仕様、互換性、データの扱いを変える必要がある
- 権限や credentials が足りない
- 破壊的・不可逆な操作が必要になる
報告には、試したこと、それぞれの結果、分かったこと、残る仮説を書く。
環境が原因の場合
依存関係の未インストールやローカルのサービスの未起動など、ローカルで解決できる原因は自分で解決する。
権限、credentials、外部サービスが原因の場合は、回避せずに報告する。
判断の範囲
次のことは自分で判断して進める。
- 調査のための一時的なログ、再現用のスクリプト、ローカルでの実行
- 技術的な直し方の選択
次のことはユーザーに確認する。
- 「止まる判断」に当てはまること
- 「直す範囲」で、ユーザーが決めるとしたもの
- 本番環境や外部サービスへの書き込みなど、外部に影響する操作
報告
完了報告では、次の項目を分けて書く。
- 確かめたこと: 実行したコマンドや操作と、観察した結果
- 原因と修正: 見つけた問題、その原因、直した内容。直していない場合は直し方の案
- 判断したこと: 自分で決めたことと、その理由
- 未確認のこと: 確かめられなかった範囲、理由、残るリスク、一度だけ起きた失敗
credentials などの秘密情報は、報告や出力に含めない。