みなさん、こんにちは。品質管理グループ所属の鎌倉です。入社してから12年ほど、ぐるなびの各種サービスのテストに従事しております。
みなさんはシステムをテストする際の入力値をどのように選んでいますか? 全パターンをひとつひとつテストすることは現実的でない場合が多いですよね。かといってパターンを思い付きで選んでいたのでは、偏りが生じて欠陥(バグ)を見落とすリスクが高まってしまいます。
では、どうやって入力値を選べばよいのでしょうか。今回から複数回に分けて、入力値を選ぶためのテスト技法と活用法をご紹介していきます。第1話のテーマは「同値分割法」です。
第1話 同値分割法とは
同値分割法のしくみ
同値分割法はブラックボックステスト(プログラムのソースコードを見ないで行うテスト)の技法のひとつで、同じ出力結果が得られる入力値をグループに分類し、それぞれのグループから代表となる入力値をピックアップしてテストします。
同値クラスの考え方
同値分割法では、同じ出力結果が得られる入力値のグループのことを「同値クラス」と呼びます。さらに同値クラスは、正常値のグループである「有効同値クラス」と異常値のグループである「無効同値クラス」の2種類に分類されます。
例えば「入力された半角文字が数字かどうか」の判定を行う処理の場合、有効同値クラスには「0」~「9」の数字10個が含まれ、無効同値クラスには「A」、「a」、「*」といった数字以外の文字すべてが含まれます。
なお、有効同値クラスと無効同値クラスは複数存在することもあります。学校で実施される試験の点数に応じて「優」、「良」、「可」、「不可」の成績をつけるような場合です。無効同値クラスについても、入力エラーの種類ごとにメッセージを変えたいような場合には複数の無効同値クラスを準備する必要があります。
代表値の選び方
入力値を有効同値クラスと無効同値クラスに分類できたら、代表値を選びます。守らなければいけないルールは「各同値クラスから代表値を最低1つ選ぶ」ということだけです。
先ほどの「入力された半角文字が数字かどうか」の判定を行う処理でいうと、有効同値クラスの代表値は「0」~「9」のどれを選んでも構いません。無効同値クラスの代表値は「A」、「a」、「*」などから1つを選べばよいでしょう。代表値を複数選べば手厚くテストすることもできますが、代表値の数に比例して時間的コストも増加します。
テストケースを設計してみよう
それでは、実際に例題をもとにテストケース(テスト項目)を設計してみましょう。
【例題】
ECサイトで会員の年齢に応じてお酒をカートに追加する際の制御に関するテストケースを設計しています。仕様の概要は次のとおりです。
会員の生年月日を元に算出された年齢がn歳のとき、
① 20≦n≦150の場合、成年なのでお酒をカートに追加できる
② 0≦n<20の場合、未成年なのでお酒をカートに追加できない
③ n>150の場合は生年月日の登録不備と判断し、お酒をカートに追加できない
同値クラスに分割
まずは有効同値クラスから考えましょう。20~150が有効同値クラスに分類されます。0~19は「未成年なのでお酒をカートに追加できない」という無効同値クラス、151以上は「生年月日の登録不備と判断し、お酒をカートに追加できない」という無効同値クラスです。追加できない理由が異なるため、別々にテストする必要があります。
代表値の選定
有効同値クラスの代表値ですが、20~150の整数であれば何でもかまいません。真ん中の85を選んでもいいですし、50や100のようにキリがよい数を選んでも大丈夫です。今回は85にしておきます。
0~19の無効同値クラスからは真ん中でキリがよい数が10なので、10を代表値にしましょう。151以上の無効同値クラスには値の上限がないため、真ん中の値はありません。ここではキリがよい200を代表値とします。
テストケースに落とし込む
各同値クラスの代表値が決まったので、各代表値をテストするためのテストケース(テスト項目)を作成してみましょう。さきほど選定した3つの代表値の85、10、200についてテストケースを記述します。実務で使うテストケースよりだいぶ簡略化していますが、下の表のようなイメージです。
このようにして、無限に存在する年齢の中から3つだけ選んでテストケースを設計することができました。
実践演習
最後は実践演習といきましょう。次の問題にチャレンジしてみてください。
【問題】
プログラミングの題材によく登場する「FizzBuzz問題」に使う関数のテストケース(テスト項目)を設計しています。関数の仕様は次のとおりです。
① 引数nは整数
② nは1以上であることを想定しており、nが0以下だった場合は「Error」を表示する
③ nが3の倍数の場合、「Fizz」を表示する
④ nが5の倍数の場合、「Buzz」を表示する
⑤ ただしnが3の倍数かつ5の倍数の場合は「FizzBuzz」を表示する
⑥ nが3の倍数でも5の倍数でもない場合、nの値を表示する
⑦ 引数nの型が合わない場合のチェックは必要ないものとする
この関数を同値分割法でテストする場合、テストケースは最低何パターン必要でしょうか。
正解と解説
この問題の場合、入力値nを出力内容ごとの同値クラスに分ける必要があります。有効同値クラスは
(A)「Fizz」を表示する同値クラス(3、6、9、……)
(B)「Buzz」を表示する同値クラス(5、10、20、……)
(C)「FizzBuzz」を表示する同値クラス(15、30、45、……)
(D)nの値を表示する同値クラス(1、2、4、7、……)
の4つに分けられます。この他に無効同値クラスとして
(E)「Error」を表示する同値クラス(0、-1、-2、……)
が必要です。
これら5つの同値クラスから代表値を最低1つずつ選ぶ必要がありますね。この問題ではnの値に上限と下限がないので、真ん中の値は存在しません。桁数が少なく、分かりやすい値を選びましょう。一例を示すと、(A)の代表値が9、(B)の代表値が10、(C)の代表値が15、(D)の代表値が7、(E)の代表値が-5といった具合です。
これらの代表値ひとつひとつにテストケースを割り当てることになるので、テストケースは最低5パターン必要となります。テストケースは次のようなイメージです。
まとめ
今回はブラックボックステストのテスト技法、「同値分割法」をご紹介しました。押さえておくべきポイントとしては、
- 入力値を同じ出力結果が得られる「同値クラス」に分割する
- 同値クラスには「有効同値クラス」と「無効同値クラス」がある
- 「有効同値クラス」と「無効同値クラス」は複数存在する場合がある
- 各同値クラスから代表値を最低1つ選ぶ
といったものがあります。同値分割法を使うと、「パスワードが8文字以上であるかチェックする」のように入力値のパターンが無限に存在するケースでも、効率よくテストができそうですね。
第2話では同じブラックボックステストのテスト技法、「境界値分析」をご紹介する予定です。どうぞお楽しみに!
※2023/04/25 代表値の選定について誤りがありましたので修正しました