4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

※本記事は2018/6/15にHatenaBlogで公開していた記事を移転・再編集したものです。
なお、元記事は公開を終了(削除)しております。

皆さん「バグ」直してますか?

特にプログラムを始めたばかりの人は見たくもないと思ってるかもしれません「バグ」。

見たくないですよね〜。わかります。1

while (ture) { print("バグ"); } // つれー(笑)

そんな「バグ修正が苦手!」という方や「バグ修正なんかつまらない!」という方向けにバグ修正のアプローチを朝までには伝えることができたらと思います。
この記事を読み終わった後、きっとあなたはバグを修正したくてウズウズすることでしょう。

チャプター1:エラーログを読もう💡

なんといっても、まずはエラーログを読みましょう。ここには発生した時点の情報がたくさん詰まっています。

ログを読まずにバグ修正力が身につくことなんてまずありません。我慢して読んでみてください。

ログを読むときの観点

  1. このエラーはどういう意味か?🤔
  2. このエラーはどんなときに発生するか?🤔
  3. このエラーがなぜ発生したか?🤔

「英語だから分かんないよ!!(憤怒)」となる方もいるかもしれませんが安心してください。ただの単語の羅列です。
それでも難しい場合はGoogle先生に頼るのです。では行きますよ!せーの...

Hey, Siri!!

ポイント

  • 情報を集めることに専念する。(疑問を持つ → 解消する)
  • 英語がわからなければGoogle翻訳。いっそエラーメッセージそのままググってみる。
  • stackoverflowという検索上位にヒットするサイトを避けない。(英語だけど内容は難しくないよ)
  • コードはまだ触らない。

※2025年追記:現在はAIの登場により、エラーメッセージの意味を理解しやすくなりましたね、良い時代!

チャプター2:再現手順を確立させよう💡

再現手順とは、バグを発生させる手順のことです。
再現手順を確立させる目的は2つあると思っています。

  1. 修正後に本当に直ったか同じ手順で確認するため。
  2. 問題解決を行うためのヒントを得るため。

2. についてどういうことかというと、例えば...

「A → B → C」という手順で実行した時は問題が発生しないけれども、
「A → B → D → C」という手順で実行した時は問題が発生するとなれば、
「D」の入力に問題があるのかな?それとも「B」の出力かな?
と色々予想がつくと思います。

問題発生時は必ず正常時との差分が発生しています。
この差分の発生箇所根本原因が隠れていることが多いので再現手順を確立させることは重要なのです。

なお、タイミングによっては再現したりしなかったりということがあると思います。
こういう時は再現率も記録しておきましょう。
10回中1回起きるなら「再現率:1/10」といった感じで残しておきます。
これも調査に必要な情報となります。

ポイント

  • 再現手順を確立させる。
  • コードはまだ触らない。

チャプター3:何が原因かを考えてみよう💡

上で集めた情報を元に何が原因かを考えてみましょう。
この時コードを触りながらではなく で考えてください。
考えがまとまらない場合は、何が りなくて考えがまとまらないかを考えてください。

そして足りない情報はあらゆる を使って調べ、また考えてください。

さらに、これが 「根本原因だ!」 と言えるかを 自分に問うて ください。
そしてさらに 考えて ください...

あなたはきっとこう思ってるはずです。

「うわぁなんだか宗教じみてきたぞー😨」と。

ポイント

  • 根本原因(仮説)を他人に理由付きで説明できるようにする。
  • 15分考えてわからなかったら周りに聞く。
  • 他人を疑う前に自分を疑う。

チャプター4:仮説を検証しよう💡

仮説を元にそれが正しいか(根本原因が間違っていないか)を検証します。
検証方法としては以下のような感じがよくある手法かな思います。

「問題と思われるモジュールなどの入力値を、問題が起こるであろう値(仮説で立てた値)に無理やり変更し実行する」

なお、入力値とはモジュールが参照しうる動的変数全てのことを指します。
(関数の引数はもちろんのこと、クラスのメンバ変数や、グローバル変数も対象となります。)

ポイント

  • 根本原因を明確化する。(余計な修正をしないため)
  • 入力値=参照しうる全ての動的変数。(全ての値が静的なら問題は起きないはず!)
  • 非同期処理によるタイミング問題は別のアプローチが必要(割愛)

チャプター5:修正案を立てよう💡

「ここまでなげーよ!」と思ったかもしれません。(少なくとも私は思っています。)

実はここがバグ修正で一番楽しいところです!おめでとうございます!(ありがとうございます)

初心者のあなた(決めつけ)は、NullPointerException2が発生した時きっと...
「エラーが発生しないようにNullチェックでも入れておこう」
と安易な考えで対処してきたかもしれません。

でも今のあなたは問題の発生原因を説明できるようになっているはずです。
ということはあなたはNullPointerExceptionではなく、根本原因に目が向いているはずです。

根本原因に対してどう修正すれば良いかを考えてみましょう。
できれば案は2つ以上あったほうが比較できるので良いです。

ポイント

  • 根本原因の箇所がどうあるべきかを考えながら修正案を考える。
  • 修正案を2つ以上出すことにより、案同士で比較できるようになるので案の精度が高まる。
  • 複数人で修正案を考えることにより更に案の精度が高まる。

チャプター6:修正箇所の影響範囲を調べよう💡

修正箇所がもし複数の箇所から呼ばれるメソッドや関数だった場合、影響を受ける箇所が複数あるということになります。

バグ修正とはバグを修正しつつ今までの動きを変えないことです。
もし、今までの動きが変わってしまうようならそれは以下のどちらかになります。

  • デグレ
  • 仕様変更

デグレを起こさないためにも修正による影響範囲を把握し、リストアップしておきましょう。

ポイント

  • デグレは悪。
  • バグ修正ついでの仕様変更は絶対やめたほうがいい。(同じコミットなら尚更)
  • 影響範囲を調べることで修正案が揺らぐ(変わる)ことがある。

チャプター7:修正案を元に修正しよう💡

実際に修正してみましょう。

今ある武器は「揺るぎない根本原因」と「完璧な修正案」です。
今までずっとコードを触るのを我慢してきたのですから思いっきり楽しんでください。

仮にもし根本原因が間違っていたり、修正案が甘かったりした場合は一旦戦場から身を引きましょう。
もしこのまま足掻こうものならばおそらく沼にハマることでしょう...

ポイント

  • 楽しみながらコードを触る。
  • 沼にハマりそうな時は一旦引く。
  • 実装の不明点は常に取り除いておく。(わからないまま実装しない)

チャプター8:テストをしよう💡

修正のテストを行います。

ここでの観点は以下の通りです。

  1. 期待通り動作する。
  2. 影響範囲も正しく動作する。

そして行なったテストは必ず記録として残しておいてください。
これを行わないと自分の修正に自信が持てなくなってしまいます。

ポイント

  • 実施したテストのエビデンスを残す。
  • 「なおりました!」と自信を持って言うためのテストを行う。(テストケースを見極める)

チャプター9:コードをレビューしてもらおう💡

コードレビュー楽しいですよね〜。
えっ!?楽しくない??ズタボロに言われるのが嫌??

わかりますおじさん「わかります」

レビューはプログラマ同士が目の前のコードに対して会話ができる場所です。
でもそれが苦手ということはきっと以下に当てはまるのではないのでしょうか。

  • 自分のコードを説明できない。
  • 自分のコードに自信がない。
  • 眠い

要約すると、

  • 説明できない = 自分が何をしようとしているかわかっていない(コピペかな?)
  • 自信がない = 情報不足、テスト不足
  • 眠い = 睡眠不足

でもここまで苦痛に耐えながら読んでくれたあなたは、きっと自分の修正に対し説明できる自信もあるはずです!

もちろんレビュー指摘を一切受けなくなるということではありません。
でもきっと受けるレビューは「批判」ではなく「提案」に感じるようになります。
こうなれば「レビューたのしーー!!」って叫べるかもしれません。

さぁ!言ってみましょう!!今すぐベランダの窓を開けて!!!

(あっもしもし、警察ですか?)

ポイント

  • 不安要素を取り除く。

チャプター10:修正をリリースしよう💡

正直ここまで長すぎて書くのにちょっと疲れてしまいました。
プロジェクトのルールに従ってリリースしてください。

ポイント

  • プロジェクトのルールに従う。
  • みんなの喜ぶ顔を想像する。

まとめ📝

バグ修正一つにしても様々なフェーズがあります。

根本原因を特定するための「情報収集」「仮説立て」「検証
修正を行うための「情報収集」「修正案の立案」「実施
そして「テスト」「リリース」。

「ちょっとやること多くありません??」

まぁでもだからこそ楽しいし、やりがいがあると思います。
ここまで読んでくださった方々が少しでもバグ修正の楽しみを知っていただけたら幸いです。

  1. trueではなく、tureになっているため「バグ」が表示されないバグが表示されるというコード

  2. ぬるぽ

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?