ソフトウェア技術者に向けて、バグに関する基礎知識をまとめていく新シリーズ「バグ百科事典」。第9回は、常連バグの代表格である、境界値に関する仕様の不良や勘違いのバグ「境界値のバグ」を取り上げます。
バグ百科事典では、筆者が気になったバグを紹介し、読者の皆さまに「バグの早期発見」と「バグの未然防止」に役立てていただくものです。本コラムによって、より良いソフトウェア開発のお役に立てればと思います。
生活をする上では、領域と境界があると便利です。例えば、自分の土地と隣の土地の境界をきちんと作っておくと、お互いの家を区別できます。境界があることは非常に役に立ちますが、問題もあります。
昔、筆者の隣家の庭に木が植えてあり、隣の住人が木を切らなかったため、枝が筆者の家の駐車場に「越境」しました。プログラミングだと、他のプロセスのメモリ領域を爆撃したようなものですね。筆者の場合、隣人にお願いして枝を切ってもらいました。一般社会でも境界に多くの問題を抱えやすいように、ソフトウェア開発でも、圧倒的に多くのバグが境界付近に存在します。
常連バグの代表格が、境界値のバグ(境界値に関する仕様の不良や勘違いのバグ)です。境界値のバグとは、同値クラスの端にバグが存在することで、バグの多くは境界に存在します。例えば、条件式、変数の取りうる値、入力値などさまざまでしょう。
境界値を正しく考察できないと、テスト工程で思わぬバグに悩みます。今回は、境界値のバグを取り上げます。
境界値関連の用語を説明するため、今回は、体験アトラクションの入場料を計算するプログラムを使います(リスト1)。
/* 仕様: 下記に従って、入場料を算出する。 ・5歳より大きく、かつ、20歳未満は、入場料を1000円とする。 ・20歳以上、かつ、60歳未満は、入場料を2000円とする。 ・アトラクションの危険性を考え、それ以外の年齢は入場不可とする。 */ #include<stdio.h> int main(void) { int age; scanf("%d",&age); if (age >= 5 && age < 20){ //入場料1000円 } else if (age >= 20 && age < 60){ //入場料2000円 } else { //入場不可 } return 0; }
リスト1には、入場料を算出する仕様とプログラムを示します。なお、コンソール入力のscanfでは、プログラムが異常動作しない常識的な値を入力するとお考えください。
同値クラスとは、結果が同じになる値をグループ分けしたものです。この仕様では、「5歳より大きく、かつ、20歳未満の入場料は1000円」「20歳以上、かつ、60歳未満の入場料は2000円」「それ以外は入場不可」となります。この場合、「1000円」「2000円」「エラー」というグループ(同値クラス)ができ、このグルーピング作業を同値分割といいます※1)。
※1)有効な同値クラスを「有効同値」、無効な同値クラスを「無効同値」と言います。今では、プログラマーの常識となった「同値分割」という用語は、1978年にグレンフォード・マイヤーズが著した不滅の名著、『The Art of Software Testing』を京都大学の長尾真先生が1980年に『ソフトウェアテストの技法』として翻訳した際、「equivalent partitioning」の訳語として考えた造語です。「等価区画」や「同一区分」なども考えられた言葉ですが、「同値分割」は雰囲気の出た良い訳語だと思います。翻訳版の出版当時、日本ではコンピュータといえばメインフレームのことで、PCはApple IIや8ビット版がやっと普及しはじめた大昔。翻訳者の長尾先生は、ソフトウェア科学の黎明(れいめい)期の泰斗で、以降、京都大学の総長に就任し、フランスのレジオンドヌール勲章や文化勲章を受章するなど、ソフトウェア系で最も功成り名を遂げた研究者となりました。
次に境界値を考えます。境界値は、同値クラスの端の値です。この場合、例えば、5、6、19、20、59、60が境界値となります。なお、どの値を境界値とするかは、バリエーションがあり、例えば、年齢が0歳から始まり、最高年齢が120手前と考えると、−1、0、120、121を境界値として加えてもよいでしょう。
この入場料判定を見直します。「5歳より大きく、かつ、20歳未満は、入場料を1000円とする」と書いてありますが、プログラムは、「if (age >= 5)」となっています。つまり、5歳以上となっており、仕様と異なります。この「同値クラスの端に潜むバグ」が、境界値のバグです。
Copyright © ITmedia, Inc. All Rights Reserved.