バグの少ないプログラムの作り方

記事
IT・テクノロジー

バグの少ないプログラムの作り方

プログラムが想定通りに動かない原因を「バグ」と呼んでいます。現状では、バグを完全になくすことは難しいとされています。対策としては十分なテストをして、可能な限りのバグを修正してからリリースすると言う方法が取られています。しかし、プログラムを書く人によって、プログラムに潜んでいるバグの数の差はかなり大きな開きがあるのも現実です。

この記事では、バグの少ないプログラムを作成するコツを紹介しています。


バグの分類

一言に「バグ」といってもいろいろなタイプ(種類)のバグがあります。まずは、バグのことを理解するために大まかに分類していみます。

コンパイルや実行時の文法エラーなどはここでは除外して考えます。そうすると、大まかに以下のようなバグを想定することができます。

* 入力のミス
* プログラムの論理的なミス
* 想定外の動作
あたりがバグの大きな分類です。

入力のミスは、例えばループのカウントで使っている変数、「i」が正しい変数であるのに、実際は「j」と入力されている場合です。あるいは、Python などのように変数を宣言しないで利用できるプログラミング言語の場合、本来「abc」と言う変数を使う場面で、「dbc」などと入力するような場合です。 いずれの場合も本来使うべき変数と別の変数を使うことになるので、殆どの場合は、プログラムは正しく動作しません。

この種類のバグは、プログラムを入力する際に発生するバグです。プログラムを動かす前に注意深くチェックすれば見つけることは可能です。しかし、多くの場合、気づかずにプログラムを実行して運が良ければ見つかる種類のバグになります。

最近は、プログラムを入力するエディタもこうしたミスをある程度チェックできるようになっているので、以前に比べると件数的には減っているとバグです。

動作がおかしい場合は、デバッガーなどで変数の値を追跡すると見つかる場合が多いので、不具合が出た場合は、比較的簡単に見つけることができます。

防止方法は、最新のエディタなどを使ってミスを事前に防ぐのが一番です。

プログラムの論理的なミス
これは、プログラムの処理の根本的な方法のミスです。この種類のバグは厄介で、見つけるのは困難なバグです。この手のバグは、動作がおかしくても原因を特定するのが難しいバグです。プログラムの記述自体には謝りがないので、コードを眺めても原因を特定するのは一般的に難しくなります。

こうした問題の検証は、フローチャートを確認したりして、プログラムの処理の流れに間違いがないかを細かく検証する必要があります。というかそれ以外に余り効果的な方法が無いのが現状です。

こうした問題を最小限にするには、プログラムを作成する前にきちんとしたドキュメントを作成して、複数の人でレビューをするのが一番効果的です。処理の流れや、条件の設定に問題が無いかなど、処理の「論理」を中心に確認する事が、こうした問題を最小限に抑えるこつと言えます。

想定外の動作
これは、プログラムが想定外の動作をする事による不具合です。 殆どのプログラムは、設計者が想定している動作はきちんと動作するのが普通です。 設計者が想定しているケースは、しっかりプログラムに記述されますし、テストも行われる場合が殆どです。従って、最初は問題があっても、プログラムが完成した時には動作するようになっていると言うのが普通です。

ところが、逆に設計者が想定していないケースというのは、意外にきちんと動作しなかったり、予想外の動作に繋がる場合が多くなります。つまり、設計者が想定していないので、コード上にきちんと記述され中たり、設計者が想定していないのでテストされない場合が殆どです。しかし、設計者が想定していない状況になる事でも実際の運用では発生する事も多く、その場合には、予想外の動作をしたり、プログラムが想定外の状態に陥ることがあって、大きな問題になることも少なくありません。

これも、これといった効果的な対策があるわけではありませんが、プログラムを書く上で工夫できる事はたくさんあります。

一つは、条件分岐(if 文や switch 分)の書き方です。これらを利用する場合には、全部の組み合わせに関して処理を書くと想定外をかなり減らすことができます。良くあるのは、設計者がこの条件は「絶対に起きない」と考えてプログラムの記述を書かない場合です。設計者がないと思う条件でも、実際には意外に起こるものです。その際は、明確な処理が書かれていないので、想定外の事がプログラムで発生する場合が多くなってしまいます。絶対に起きないと思っている部分でも、発生を知らせるような出力を出したり、ログを残すだけでも、原因究明に役立ちます。

データによる問題、データも全てのデータをテストするのは現実的に難しい場合が多いので、ある特定のデータで問題が発生することが良くあります。数値のデータの場合は、実際に想定される数値の範囲の両端と真ん中、そして、外側の数値のデータを当てはめてテストをするとかなり多くのケースをカバーする事ができます。しかし、データが文字列などの場合はこうした範囲の設定ができないのでテストは難しくなる場合が多くなります。

いずれにしても、できるだけ場合を分けて、想定外が最小限になるようにプログラムの記述をしたり、テストするデータの工夫をすることでかなり減らす事ができます。

スコープを絞る
バグの種類によって、対策のやり方、見つけ方が違うのはおわかりいただけたでしょうか? ここまで書いてきた種類毎の対策を取れば、バグを最小限に抑えることはある程度可能です。しかし、処理の論理の間違いや想定外を減らすのは簡単ではありません。

そこでもう 1 点工夫できる事があります。

それは、「スコープ」を絞る事です。

大きなプログラムを作ると、いろいろな条件やデータの種類を選ぶのも簡単ではありません。 しかし、関数や、クラスなどを上手く利用して、一つ一つの処理を細かく分けてプログラムの規模を小さくすると、一つ一つは見通しが良くなります。そうすることで、条件の抜けや、テストするデータの種類を限定する事が可能になります。そうすると、プログラムの致命的なバグはある程度防ぐことが可能になります。

また、各モジュール間のデータの受け渡しをチェックすることで、どの部分の処理が問題かの特定もやりやすくなります。テストも、まずは、小さなモジュール単位で行って、その上で組み合わせたテストをするようにすると、テストも効率的に行えて、問題の発見や特定も容易になります。

人間は、広い範囲を見ると見落とすことも多いですが、範囲を限定することができれば、見落としも最小限にすることが可能になります。

上であげたバグのタイプを良く理解した上で、スコープを絞ることでプログラムの品質は確実に向上します。

まとめ
バグのないプログラムを開発するのは至難の技ですが、バグの少ないプログラムを作るための工夫は意外に簡単にできるものです。

大切なのは、どんな問題が起きる可能性があるかを良く理解することです。これを理解していると、プログラムを書く上でもいろいろ工夫が可能になります。問題点の性質を良く理解した上で、見る範囲をしぼる、つまり、スコープを絞って集中することで、かなりの問題を防いだり、見つけたりする事が効率的にできるようになります。

さらに、バグの少ないプログラムを作ることは、管理しやすい、つまり、読みやすくわかりやすいプログラムの記述にも繋がるので、プログラムを運用して行く上でもとても重要です。

プログラマーにとってバグは、大きな課題の一つですが、バグを良く理解することでバグの少ないプログラムを書くことができます。プログラムの勉強で意外に軽視されがちですが、バグを意識したプログラミングはとても重要です!
サービス数40万件のスキルマーケット、あなたにぴったりのサービスを探す