バグを減らすための正しい努力とは

はぁ……
どうしたの、レオ君。ため息なんかついちゃって。
あ、ユキ先輩。実は、僕が作ったプログラムにバグがあることが判明して……
あらあら。そんなに落ち込まなくてもいいと思うけど。
だって、すごく頑張って作ったプログラムだったんですよー。

バグをゼロにする方法はあるか

バグを発生させない方法が一つだけあるのだけど。レオ君は知ってるかしら?
わぁ、そんな方法があるんですか?教えてください!
それはね……プログラムを作らないことよ。
えー、からかわないでくださいよー。
ふふふ。からかってるわけじゃないのよ。

プログラミングをしなければ、バグが発生することもないでしょう。でも、プログラムを作る仕事をする以上は、間違いの頻度はゼロにはなりません。例えば、長いプログラムを書くときに、1度もコンパイルエラーを出さずに済むとは考えにくいですね。できたとしても、一発で期待通りに動作するケースは稀です。

これは、絶対に落ちない飛行機や絶対に沈まない船、絶対に衝突しない自動車を作れないのと似たようなものです。絶対に間違えないプログラムの書き方というのは、存在しません。

誰にでも間違いはあるものよね。だったら、プログラミングを頑張っている人だけがバグを経験できるんだって考えてみるのはどうかしら?
そっかぁ。そうですよねー。
だからバグがあっても胸を張って、もっといい方法を考えればいいのよ。

バグを減らすための「つらい」方法

誰も好んで間違えようとしているわけでもないのに、プログラムを作り続ける限り、バグは何度でも発生します。では、バグの発生頻度を減らすにはどうすればいいでしょうか。

バグはどうすれば減らせると思う?
リリース前に、たくさんテストをすればいいんじゃないですか?
うん、その心意気は買わせてもらうわ。でも、それだとバグの発生を抑えたことにはならないわね。
あ、そっか。

たしかに、リリース前にプログラムをテストするのは重要なことです。細部まできっちりテストを実施すれば、実害のあるバグはほぼ発見できるでしょう。しかし、これはバグの発生を抑えることとは違います。

それに、リリース前のテストは、プログラムが想定どおりに機能しているかどうかの確認作業として行いたいものです。バグの発見が主目的にすり替わってしまうのは、あまり健全とはいえません。

じゃあ、もう一歩踏み込んで考えてみましょうか。そもそもバグを発生させないようにするために、何かできることはないかしら?
そうですね……もっと慎重にやればバグは減るとは思うんですけど……
ふむふむ。ということは?
あ、レビューを増やすっていうのはどうですか?厳しくレビューしながら開発を進めたら、バグは減らせそうな気がします。
うんうん。それも間違ってはいないわ。ただ、時間をかけて頑張る方向に発想が向かいがちなのがちょっと気になるところね。

テストと同様、レビューも重要であることは間違いありません。実装を始める前に設計方針をレビューしたり、実装中にコードレビューを実施したりすれば、早い段階からバグを防げます。これは、チームで知恵を出し合って、ベストだと思える選択をすることにより得られる効果です。

でも、バグを減らそうとするあまり、レビューを厳しくしすぎるのは考えものです。それは、時間がいくらあっても足りない方法だからです。「もっと慎重に」とレビューにかける時間を増やし続けていけば、しだいに開発のペースは落ちていくことになるでしょう。

時間をかけてレビューを頑張ればバグは減るかもしれないけれど、生産性も落ちてしまったら……
そっか。それは、やりたいこととは違う気がします。
ちなみに、生産性が落ちたら、その結果としてもバグは減るわね。
えっ?
だって、バグを発生させない唯一の方法は、何も作らないことだったでしょう?
あ、はい……なるほど。作る量が減ったら、その分バグも減るはずですね。
そうなったら、バグが減った理由が「レビューを増やしたから」なのか「作る量が減ったから」なのか、分からなくなってしまいそうじゃない?
たしかに……うーん。それは嫌だなぁ……
そうよね。そういう努力のしかたは、あまり長続きしないと思うわ。

バグには「仕組み」で対処しよう

どれだけバグが減っても、作れなくなってしまったら意味がありません。では、どうすれば生産性を犠牲にすることなく、バグの発生に対処できるでしょうか。

結局、バグを減らすのは難しいってことですか?
まぁ、簡単ではないわね。それじゃあ、発想の転換をしましょうか。
発想の転換……ですか?
そう。考え方を「バグがあったら直す」から、「バグを積極的にあぶり出す」に変えるのよ。
んんん?どう違うんです?
バグの原因は、プログラムに埋め込まれるものよね。
はい。
でも、問題として表面化するまでには、タイムラグがあるでしょう?
タイムラグ……そっか!原因を作ってしまったからといって、すぐに問題が発生するとは限らないんですね!
そういうこと。バグには潜伏期間があるということよ。
なるほどー。
で、長く潜伏していたバグほど、直すときには苦労しがちよね。
そうかも。作ってから時間が経っちゃうと、思い出すのが大変ですもんね。

プログラム中に埋め込まれてしまったバグは、すぐに発見されるとは限りません。それが問題として表面化して「バグがあるぞ」と認識するまでには、ある程度のタイムラグがあるのが普通です。また、タイムラグが大きいほど、原因究明に苦労するケースが多くなります。

反対に、作ってからすぐにバグを発見できた場合は、すんなり直せることが多いでしょう。これは、問題点を早期にあぶり出すための「仕組み」があれば、生産性を損わずにバグに対処できることを意味しています。

生産性のことを考えるなら、問題が表面化するより前に原因を摘み取れたらベストね。
それが「バグを積極的にあぶり出す」っていう考え方なんですね。
そういうこと。そのためには、時間や労力を節約できる「仕組み」を考えることが大切なの。
ここがポイント!
バグをゼロにすることはできません。バグをなくすために時間を使いすぎるより、バグを早期発見するための仕組みづくりにフォーカスしましょう。
ふむふむ。「仕組み」を考えることが大切と……でも、具体的にどうすればいいんですか?
まずはテストとレビューについて考え直すことかしらね。いつ、何をチェックすれば、どんな問題を最速で取り除けるか。
やっぱり、テストとレビューが基本ってことには変わりないんですね。
それはそうよ。まぁ、でもね……ここはソフトウェアエンジニアらしく、「デバッグコード」の書き方を覚えるのはどうかしら。
デバッグコードって何ですか?
プログラムを作るときに、バグを捕らえるための「罠」を仕掛けるテクニックのことよ。まだ記憶に新しいうちにデバッグコードを書いておくことで、問題に早く気付けるようになるわ。
わぁ、なんかすごそうですね!ぜひ教えてください!