入力を同じ結果になるグループに分け代表値でテストする技法。
同値分割(同値クラス分割)とは、入力を「同じ結果になるグループ(同値クラス)」に分け、各グループから代表値を1つ選んでテストする技法です。プログラムの中身を見ず、仕様(入力と出力の関係)だけからテストを設計する「ブラックボックステスト」の代表的な手法です。
身近な例で考えると、テストの点数で成績をつけるのに似ています。0〜59点は「不可」、60〜100点は「合格」のように、点数を意味のあるグループに分け、それぞれの代表(たとえば30点と80点)で確認すれば、全点数を1点ずつ試さなくても挙動を確かめられます。
上のツールで▶ボタンを押すと、「1〜100を有効とする入力」を有効・無効の3クラスに分け、それぞれ代表値を選んで3件のテストに絞り込む流れを確認できます。
同値クラスとは「中のどの値を入れてもプログラムが同じ振る舞いをする入力のかたまり」のことです。同値クラスは大きく2種類に分けて考えます。
・有効同値クラス:仕様どおり正しく受理される値の集まり(例: 1〜100)
・無効同値クラス:エラーや拒否になる値の集まり(例: 0以下、101以上)
クラスを作るときのコツは次のとおりです。
・有効クラスだけでなく無効クラスも必ず作る:エラー処理が正しく動くか確認するため
・クラス内のどの値でも結果が同じになるよう分ける:そうでなければ分け方が粗い
・各クラスから代表値を1つだけ選ぶ:全部試さず効率よくカバーする
こうしてグループ分けすると、無限にあり得る入力値を少数の代表値だけで効率よく確認できます。上のツールでは、有効(50)・無効(-5)・無効(110)の3つの代表値が選ばれる様子を見られます。
同値分割だけでは弱点があります。代表値はクラスの「真ん中あたり」を選びがちで、クラスの境目(境界)に潜むバグを見逃しやすいのです。たとえば「100まで有効」なのに「100まで」と「100未満」を取り違えるバグは、代表値50では見つかりません。
そこで実務では、同値分割と限界値分析(=境界付近の値を重点的に試す技法)を組み合わせて使います。同値分割で「どこを区切ればよいか」を決め、その境界の前後を限界値分析で重点的にテストする、という役割分担です。
「1〜100」の例では、次のような値を追加でテストします。
・下の境界付近:0(無効)・1(有効の最小)
・上の境界付近:100(有効の最大)・101(無効)
同値分割で全体をもれなくカバーし、限界値分析で危険な境界を重点的に守る。この2つはセットで使うことで、少ないテスト数でも見落としの少ない検証ができます。
同値分割が効率的な理由は、同じ結果になる値はいくつ試しても1回と変わらないという前提にあります。
たとえば「1〜100が有効」というプログラムに 2・3・4…99 を入れても、すべて「有効」として同じ処理が走ります。つまりこのクラス内では代表値1つで十分であり、残り98個を試すのは時間の無駄です。
一方で、クラスが違えば結果も違うので、必ず別々に試す必要があります。有効クラスだけ確認して無効クラスを試さないと、「エラーのとき正しくメッセージを出すか」という確認が丸ごと抜けます。クラスを分けること自体が「どこを必ず試すべきか」の地図になっているのです。
上の図のように、無数の入力値を「同じ振る舞いのグループ」に整理すると、テストの件数をグループ数(例: 3件)まで絞り込めるのが同値分割の力です。
| よくある間違い | どう直すか |
|---|---|
| 有効クラスしか作らない | 無効クラス(小さすぎる・大きすぎる)も必ず作る |
| 各クラスから複数の値を選ぶ | 1クラス1代表値で十分。中の値はどれも同じ結果になる |
| クラスの分け方が粗すぎる | 処理が変わる境目ごとに区切る。境目が複数あれば複数のクラスに分ける |
同値分割で一番大切なのは「クラスの分け方が正しいか」です。分け方の基準はシンプルで、「この入力だと処理はどう変わるか?」を仕様書で確認し、振る舞いが変わる場所で区切るだけです。
たとえば「年齢入力で、0〜17は未成年・18〜64は一般・65以上は高齢者」という仕様なら、振る舞いが変わる境目は「18」と「65」の2か所なので、クラスは次の4つに分けます。
・無効(0未満):負の年齢は仕様外
・有効(未成年):0〜17
・有効(一般):18〜64
・有効(高齢者):65以上(上限がある場合はさらに無効クラスも追加)
上のツールでも同じように、仕様から境目を読み取ってクラスを作り、代表値を1つずつ選ぶ流れを確認できます。