📖 読了目安 約18分
この記事の目次

不具合対応の進め方

不具合(バグ)の調査と修正の進め方を学びます。1年目のうちは「調査しても原因が分からない」「修正したのに直らない」ということがよく起きます。ここで紹介する手順を踏むことで、効率的に原因を特定し、確実に修正できるようになります。

補足:デバッガやログなど調査に使うツールの使い方は、デバッグの基本 を参照してください。

不具合対応の流れ

flowchart LR
    A[報告確認] --> B[再現確認]
    B --> C[原因調査]
    C --> D[修正]
    D --> E[修正確認]
    E --> F[報告]

各ステップにはそれぞれ重要な意味があります。「面倒だから」と飛ばすと、後で余計な時間がかかることが多いです。

Step 1:不具合報告を確認する

確認すること

項目 内容
現象 何が起きているか
再現手順 どうすれば再現するか
期待結果 本来どうなるべきか
発生環境 どの環境で発生したか
発生頻度 毎回か、たまにか

情報が不足していたら

報告内容が不明確な場合は、報告者に確認します。

  • 「再現手順をもう少し詳しく教えてください」
  • 「どの環境で発生しましたか?」
  • 「エラーメッセージは表示されましたか?」

Step 2:再現確認する

なぜ再現確認が必要か

再現確認は不具合対応で最も重要なステップです。これを飛ばすと、以下のような問題が起きます。

flowchart TB
    A[再現確認をスキップ] --> B[間違った箇所を調査]
    A --> C[修正しても直っていないことに後で気づく]
    A --> D[別の問題と混同して調査が混乱]

再現確認をする理由

理由 詳細
現象を正確に理解するため 報告だけでは分からない細かい動作を確認できる。「ボタンを押しても反応しない」と言われても、実際に見ると「1秒遅れて反応している」だったりする
原因調査の起点にするため 再現できれば、デバッガで止めて変数を見たり、ログを確認したりできる。再現できなければ調査のしようがない
修正後の確認のため 「修正前は再現した」→「修正後は再現しない」で修正できたことを証明できる
報告内容の認識齟齬を防ぐため 報告者と自分で「何が問題か」の認識がずれていることがある。再現確認で齟齬に気づける

1年目あるある:再現確認せずに「たぶんここが原因だろう」と修正して、実は全然違う問題だった。結果的に何時間も無駄にしてしまった…

再現できない場合

再現できないときは、焦らず情報を集めることが大切です。

  1. 報告者に詳細を確認

    • 「手順の〇番と〇番の間に、他に操作はありましたか?」
    • 「ログインしているユーザーはどのアカウントですか?」
  2. 環境の違いを確認

    • 開発環境とテスト環境の違い
    • OSやブラウザのバージョン
    • データベースのデータの違い
  3. 発生条件を絞り込む

    • 特定のユーザーだけで発生するか
    • 特定の時間帯だけで発生するか
    • 特定のデータでだけ発生するか
  4. 「再現できませんでした」と報告

    • 試したことを具体的に伝える
    • 追加情報をもらう

Step 3:原因を調査する

なぜ「仮説を立てる」ことが重要か

1年目がやりがちな調査方法は、**「なんとなくコードを眺める」「手当たり次第にログを出す」**です。これでは時間がいくらあっても足りません。

flowchart LR
    subgraph 効率の悪い調査
        A1[コードを眺める] --> A2[分からない]
        A2 --> A3[別の場所を眺める]
        A3 --> A4[また分からない]
        A4 --> A5[無限ループ...]
    end
flowchart LR
    subgraph 効率の良い調査
        B1[仮説を立てる] --> B2[仮説を検証]
        B2 --> B3{正しかった?}
        B3 -->|Yes| B4[原因特定!]
        B3 -->|No| B5[別の仮説]
        B5 --> B2
    end

仮説を立てることのメリット

メリット 詳細
調査範囲を絞れる 「どこを見ればいいか」が明確になる。全コードを読む必要がなくなる
検証可能になる 「この仮説が正しければ、〇〇のはず」と確認ポイントが決まる
進捗が見える 「仮説Aは違った、仮説Bを検証中」と状況を説明できる
相談しやすくなる 「〇〇が原因だと思うのですが」と具体的に相談できる

ポイント:仮説は外れても良い。「仮説が外れた」=「原因ではない箇所が分かった」なので、調査は確実に前進しています。

調査の進め方

1. 仮説を立てる

現象から、原因の仮説を立てます。最初は間違っていても構いません。

仮説の立て方

  • 現象を言葉にする:「〇〇の画面で△△すると、□□になる」
  • 関係しそうな処理を考える:「〇〇の画面は、この Controller が処理している」
  • 仮説を作る:「Controller の△△メソッドに問題がありそう」

仮説の例

  • 「バリデーションのロジックに問題がありそう」
  • 「データベースの値が想定と違うかも」
  • 「条件分岐が間違っているかも」
  • 「nullチェックが漏れているかも」

2. 仮説を検証する

仮説に基づいて、確認すべきポイントを決めて調査します。

仮説:「バリデーションのロジックに問題がありそう」
  ↓
確認ポイント:「バリデーションメソッドに渡される値は何か?」
  ↓
調査方法:「デバッガでバリデーションメソッドにブレークポイントを置く」
  • 関連するコードを読む
  • デバッガで値を確認
  • ログを確認

3. 絞り込む

「正常な箇所」と「異常な箇所」の境界を見つけます。

入力 → [処理A] → [処理B] → [処理C] → 出力
         ↑正常      ↑正常      ↑異常!

→ 処理Cに問題がある可能性が高い
  • 「ここまでは正常、ここから異常」を特定
  • 二分探索で効率的に絞り込む(処理の真ん中あたりで確認→前半か後半かを判断→さらに半分で確認…)

調査に役立つ手法

手法 内容 詳細
デバッガ ブレークポイントで停止して変数を確認 デバッガの使い方を参照
ログ出力 処理の途中経過を出力 ログの活用を参照
差分確認 正常時と異常時の違いを比較 git diff などで変更箇所を確認
直近の変更確認 最近変更された箇所を確認 git log、git blame で確認

あなたのケースに合った調査アプローチを選ぶ

不具合の調査は、状況によってアプローチが大きく変わります。以下のフローチャートで、自分のケースに合ったアプローチを確認してください。

flowchart TB
    Start[調査開始] --> Q1{手元で再現できる?}

    Q1 -->|Yes| Q2{デバッガは使える?}
    Q1 -->|No| Case4[ケース4へ]

    Q2 -->|Yes| Q3{再現率は?}
    Q2 -->|No| Case3[ケース3へ]

    Q3 -->|100%| Case1[ケース1へ]
    Q3 -->|時々| Case2[ケース2へ]

ケース1:手元で再現でき、デバッガが使え、100%再現する

最も調査しやすいケースです。

flowchart LR
    A[再現操作] --> B[デバッガで停止]
    B --> C[変数を確認]
    C --> D[原因箇所を特定]

やること

  1. 再現する操作を行う
  2. 関係しそうな処理にブレークポイントを設定
  3. 変数の値を確認しながら、ステップ実行で処理を追う
  4. 「ここまでは正常、ここからおかしい」という境界を見つける

:「ユーザー登録でエラーになる」 → 登録処理のメソッドにブレークポイントを置いて、どの時点で値がおかしくなるか確認


ケース2:手元で再現できるが、再現率が低い(たまにしか再現しない)

条件の特定が重要なケースです。

flowchart LR
    A[条件を変えて試す] --> B{再現した?}
    B -->|Yes| C[条件を記録]
    B -->|No| D[別の条件を試す]
    D --> A
    C --> E[再現条件を絞り込む]

やること

  1. 何度か試して、再現するときとしないときの違いを観察
  2. 条件を変えて試す(データ、タイミング、操作順序など)
  3. 再現条件が分かったら、ケース1と同じ方法で調査
  4. 条件が分からなければ、ログを仕込んで情報収集

よくある原因

  • タイミング依存(処理の順番、レースコンディション)
  • データ依存(特定の値のときだけ発生)
  • 状態依存(特定の画面遷移の後だけ発生)

ケース3:手元で再現できるが、デバッガが使えない

ログが頼りのケースです。

flowchart LR
    A[ログを仕込む] --> B[再現操作]
    B --> C[ログを確認]
    C --> D{原因分かった?}
    D -->|No| E[別の箇所にログ追加]
    E --> A
    D -->|Yes| F[原因特定]

やること

  1. 処理の要所にログ出力を追加
  2. 再現操作を行う
  3. ログから処理の流れと変数の値を確認
  4. 二分探索的にログを追加して、原因箇所を絞り込む

ログを追加する場所

  • メソッドの入口と出口(引数と戻り値)
  • 条件分岐の前後(どの分岐に入ったか)
  • エラーが発生しそうな箇所

ケース4:手元で再現しない(本番環境でのみ発生など)

最も難易度が高いケースです。

flowchart TB
    A[本番ログを確認] --> B{情報は十分?}
    B -->|Yes| C[ログから原因を推測]
    B -->|No| D[ログ追加を依頼]
    C --> E{原因特定できた?}
    E -->|Yes| F[修正へ]
    E -->|No| G[環境差・データ差を調査]
    G --> H{手元で再現できた?}
    H -->|Yes| I[ケース1〜3へ]
    H -->|No| J[先輩に相談]

やること

  1. 本番環境のログを確認
  2. 発生時刻、ユーザー、操作内容などから情報を収集
  3. 環境やデータの違いを調査して、手元で再現を試みる
  4. 再現できれば、ケース1〜3の方法で調査
  5. 再現できなければ、先輩に相談

確認すべき環境差

観点 確認内容
環境 OS、ミドルウェアのバージョン、設定ファイル
データ 本番データの特徴、テストデータとの違い
タイミング 発生時間帯、負荷状況、同時アクセス数
操作 ブラウザ種類、操作の順番やスピード

再現率と発生条件の確認が重要な理由

再現率によって調査難易度が大きく変わります

flowchart LR
    A[再現率 100%] --> B[難易度:低]
    C[再現率 50%] --> D[難易度:中]
    E[再現率 10%] --> F[難易度:高]
    G[再現率 1%] --> H[難易度:非常に高]
再現率 特徴 調査アプローチ
100% 条件が特定できている デバッガで止めて調査。最も楽
50%〜90% ほぼ再現するが、たまに再現しない 何度か試して再現を待つ。再現時に情報を取得
10%〜50% 条件が絞り切れていない まず条件の特定に注力。ログを仕込んで情報収集
10%未満 ほとんど再現しない 発生時のログが頼り。早めに先輩に相談

発生条件を絞り込む質問

  • 「特定のユーザーでだけ発生しますか?」
  • 「特定のデータでだけ発生しますか?」
  • 「特定の時間帯にだけ発生しますか?」
  • 「特定の操作の後にだけ発生しますか?」
  • 「同時に複数人が操作しているときに発生しますか?」

1年目へのアドバイス:再現率が低い不具合は難易度が高いです。「どういう条件で発生するか」を報告者に詳しく聞くことが第一歩です。分からなければ早めに先輩に相談しましょう。

「表面的な原因」と「根本原因」の違い

1年目がよくやる失敗は、「表面的な事象」を原因だと思って修正してしまうことです。

例:「画面にエラーメッセージが表示されない」という不具合

flowchart TB
    A[表面的な原因と思いがち] --> B["エラーメッセージの表示処理がない"]
    B --> C["表示処理を追加して修正完了!"]
    C --> D["→ 別の画面で同じ問題が再発..."]

    E[根本原因を調べると] --> F["エラー情報がAPIから返されていない"]
    F --> G["API側でエラーハンドリングを修正"]
    G --> H["→ 全画面で正しく動作するようになった"]

表面的な原因で修正すると何が起きるか

問題 詳細
同じ問題が別の場所で再発する 根本が直っていないので、関連する他の機能でも同じ問題が起きる
新たな問題を引き起こす 本来不要な「回避コード」を追加することで、コードが複雑になり別のバグを生む
技術的負債になる 「なぜこんなコードがあるのか分からない」という負債が溜まる

根本原因を見つけるためのチェックポイント

  1. 「なぜ?」を繰り返す

    • 現象:エラーメッセージが表示されない
    • なぜ? → 表示処理が呼ばれていない
    • なぜ? → エラー情報が渡されていない
    • なぜ? → API がエラー情報を返していない ← これが根本原因
  2. 「この修正で本当に直るか?」を考える

    • 「表示処理を追加する」→ 他の画面は?APIの問題は残ったまま?
    • 「APIを修正する」→ 全ての画面で正しくエラーが表示されるか?
  3. 類似箇所を確認する

    • 同じ処理を使っている他の箇所で問題が起きていないか?
    • 起きていなければ、なぜ起きていないか?

先輩への相談ポイント:「〇〇が原因だと思うのですが、これが根本原因で合っていますか?」と確認すると、見落としに気づけることが多いです。

原因が分からない場合

30分〜1時間調べても分からなければ、相談しましょう。相談するときは、調査内容をまとめて伝えます。

相談の仕方

「〇〇の不具合を調査しています。
現象:△△すると□□になる
調べたこと:
  - ××を確認 → 正常だった
  - ◇◇を確認 → ここで値がおかしくなっている
仮説:◇◇の処理に問題があると思うのですが、
      ここから先の調べ方が分かりません。」
  • 「ここまで調べて、〇〇が怪しいと思うのですが」と伝える
  • 一人で抱え込まない(時間をかけすぎると、チーム全体の進捗に影響する)

Step 4:修正する

修正の原則

1. 根本原因を修正する

  • 表面的な対処ではなく、根本原因を直す
  • なぜその修正で直るのかを理解する

2. 影響範囲を確認する

  • 修正が他の機能に影響しないか
  • 関連する箇所を確認

3. 最小限の修正にする

  • 必要以上に変更しない
  • 「ついでに」の修正は別の対応にする

修正時の注意点

  • 修正前のコードを理解してから修正
  • 「なぜこう書かれていたか」を考える
  • 意図せず他の機能を壊さないように

Step 5:修正を確認する

確認すること

  1. 元の不具合が直っているか

    • 報告された再現手順で確認
    • 不具合が再現しないことを確認
  2. 他の機能に影響がないか

    • 関連する機能のテスト
    • 回帰テスト
  3. 類似のケースは大丈夫か

    • 同じロジックを使っている他の箇所
    • 類似の条件での動作

Step 6:報告する

報告の内容

## 対応完了報告

### 不具合
ユーザー登録時、メールアドレスのバリデーションが動作しない

### 原因
バリデーション処理で使用している正規表現のパターンに誤りがあった。
「@」の後ろの文字列チェックが不十分だった。

### 修正内容
- 正規表現パターンを修正
- 関連するテストケースを追加

### 確認結果
- 元の不具合が解消されたことを確認
- 正常なメールアドレスで登録できることを確認
- 他のバリデーションに影響がないことを確認

### 関連コミット
abc1234

調査資料の作成

複雑な不具合は、調査資料を作成することがあります。

調査資料の構成

# 〇〇不具合 調査報告

## 現象
(何が起きているか)

## 再現手順
1. ...
2. ...

## 調査内容
- 〇〇を確認 → △△だった
- □□を確認 → ◇◇だった

## 原因
(なぜ発生しているか)

## 対応案
1. 案A:〇〇を修正
   - メリット:...
   - デメリット:...
2. 案B:△△を修正
   - メリット:...
   - デメリット:...

## 所感
(その他気づいたこと)

よくある失敗と対策

失敗1:再現確認せずに調査を始めた

何が問題か

  • 報告と実際の現象が違っていた場合、間違った方向に調査してしまう
  • 「直った」と思っても、そもそも再現していなかっただけかもしれない
  • 修正後に「まだ直っていない」と言われて二度手間になる

どうすれば良いか

  • 必ず最初に再現を試みる
  • 再現できたら、その手順をメモしておく(修正後の確認に使う)
  • 再現できなければ、報告者に追加情報をもらう

失敗2:原因を特定せずに「たぶんここだろう」で修正した

何が問題か

  • 本当の原因が別の場所にあった場合、修正しても直らない
  • 運良く直ったように見えても、根本原因が残っているので再発する
  • 不要なコードを追加してしまい、後で混乱の原因になる

どうすれば良いか

  • 修正する前に「なぜこの修正で直るのか」を説明できる状態にする
  • 「この行を変えるとこうなるから、不具合が直る」と論理的に説明できれば OK
  • 自信がなければ、先輩に「この修正で合っていますか?」と確認する

失敗3:修正の影響範囲を確認しなかった

何が問題か

  • 修正したことで、別の機能が壊れる(デグレード、回帰バグ)
  • 「不具合を直したら別の不具合が出た」という最悪のパターン
  • 信頼を失い、以降の修正も疑われるようになる

どうすれば良いか

  • 修正する箇所を「どこから呼ばれているか」を確認する
  • 呼び出し元の機能も動作確認する
  • 既存のテストを実行して、失敗するものがないか確認する
  • 不安なら、先輩に「影響範囲はここだけで大丈夫でしょうか」と相談する

失敗4:調査に時間をかけすぎた

何が問題か

  • 1日かけて調べても分からないことを、ベテランは10分で解決できることがある
  • 一人で抱え込むと、チーム全体の進捗に影響する
  • 「困っているなら早く言ってほしかった」と言われてしまう

どうすれば良いか

  • 30分〜1時間を目安に、進展がなければ相談する
  • 相談するときは「調べたこと」と「分からないこと」を整理して伝える
  • 「何も分からない」状態でも相談して良い(調べ方を教えてもらえる)

失敗5:修正後のテストが不十分だった

何が問題か

  • 「直した」と報告したのに、実は直っていなかった
  • 報告者やテスト担当者に再度確認してもらう手間が発生
  • 信頼性が下がり、以降の報告も疑われるようになる

どうすれば良いか

  • 報告された手順で再現しないことを確認する
  • 関連する他のケースも確認する(類似パターン、境界値など)
  • 修正前と修正後の動作の違いを明確に説明できるようにする

まとめ

不具合対応を進めるときは:

  1. 報告内容を正確に理解する
  2. 再現確認してから調査を始める
  3. 仮説を立てて検証する
  4. 根本原因を修正する
  5. 影響範囲を含めて確認する
  6. 原因と修正内容を報告する