ジャンルから探す

QA English

同値分割と境界値分析の効率的なテスト設計の基礎と応用

同値分割と境界値分析は、「テストケースを減らしながら、バグが出やすい場所は外さない」ための技法です。この2つはセットで使います。

実務でより重要なのは、テスト実行時ではなく仕様レビューの段階で使うことです。境界を書き出すと、「仕様書にその値の扱いが書かれていない」という抜けが必ず見つかります。実装前にそれを潰せるかどうかで、後工程の手戻りが大きく変わります。

この記事では、2つの技法の基本と、実務で漏れやすい境界(文字数・日付・全角数字)まで具体例で解説します。

スポンサーリンク

同値分割とは

「同じ結果になるはずの入力」をグループにまとめ、各グループから代表値を1つだけ選ぶ技法です。

年齢入力欄(0〜120歳)を例にすると、次のように分けられます。

クラス 範囲 代表値
有効値クラス 0〜120 30
無効値クラス(下) -1以下 -5
無効値クラス(上) 121以上 130

根拠は「同じクラスの中なら、どの値を入れても同じ処理を通る」という前提です。30 で通るなら 31 も 32 も通るはずなので、全部試す必要はありません。

この前提が崩れる場合は分割し直します。 たとえば「20歳未満は購入不可」という別の条件が加わるなら、有効値クラスをさらに「0〜19」と「20〜120」に分ける必要があります。

境界値分析とは

同値クラスの「境目」を狙う技法です。 不具合は範囲の真ん中ではなく、ほぼ境界で起こります。<<= の書き間違い、i < ni <= n の取り違えが原因です。

年齢入力欄の境界値は次のようになります。

-1 | 0 ... 120 | 121
   ↑            ↑
 下の境界     上の境界

2値と3値のどちらを使うか

境界値分析には2つの流儀があります。どちらを使うかをチームで決めておかないと、担当者ごとにテストケース数がばらつきます。

取る値 年齢の例(0〜120) ケース数
2値 境界と、その外側の隣 -1, 0, 120, 121 4
3値 境界と、その両隣 -1, 0, 1, 119, 120, 121 6

通常は2値で十分です。 3値は、境界付近の処理が特に複雑な場合や、事故が起きたときの影響が極端に大きい場合(決済金額の上限など)に使います。

スポンサーリンク

2つの技法の関係

同値分割で「どこを見るか」を決め、境界値分析で「どの値を入れるか」を決めます。 順番が逆になることはありません。

  • 同値分割:入力の範囲をグループに分ける → テストすべき箇所が明確になる
  • 境界値分析:各グループの境目を特定する → 実際に入れる値が決まる

この2つを組み合わせると、「代表値1つ+境界値」だけで、範囲全体をカバーしたことにできます。0から120まで121通り試す必要はありません。

実践例1:年齢入力欄

仕様:年齢は0〜120歳の間で受け付ける。

期待結果 技法
-1 エラー 境界値
0 OK 境界値
30 OK 同値分割(代表値)
120 OK 境界値
121 エラー 境界値

ここで止めてはいけません。 数値の境界だけを見ていると、実務では次の抜けが残ります。

入力 仕様に書かれているか
空欄 必須なのか任意なのか
全角数字「30」 受け付けるのか、変換するのか、弾くのか
小数「30.5」 整数のみか
前後に空白「 30 」 トリムするのか
文字列「abc」 エラーメッセージは何になるか

この表を作って開発者に見せると、たいてい何行かは「決まっていない」と分かります。 それを実装前に潰すのが、この技法の一番の価値です。

スポンサーリンク

実践例2:クーポン適用条件

仕様:購入金額が1,000円以上の場合にクーポンを適用する。

期待結果
999円 適用されない
1,000円 適用される
1,001円 適用される

「1,000円以上」の日本語は、1,000円ちょうどを含みます。 しかし仕様書に「1,000円を超えた場合」と書かれていたら、1,000円ちょうどは含みません。この違いが実装の >=> の差になります。

金額の場合、確認すべき点がもう一つあります。

  • 判定に使うのは税込か税抜か:仕様書に書かれていないことが非常に多い
  • 送料は含むか
  • 他のクーポンで割引された後の金額か、割引前か

「1,000円以上」という短い一文に、これだけ確認事項が隠れています。

実践例3:パスワードの文字数

仕様:パスワードは8〜16文字。

文字数 期待結果
7文字 エラー
8文字 OK
16文字 OK
17文字 エラー

文字数の境界では「1文字をどう数えるか」が問題になります。 ここは実務で最も漏れやすいポイントです。

  • 絵文字:JavaScript の length では絵文字1つが2文字と数えられます(サロゲートペア)
  • 結合文字:「が」を「か」+濁点で表現すると2文字になります
  • 改行\r\n は2文字。OSによって送信される文字数が変わります
  • 全角文字:バイト数で制限している実装なら、全角は3バイト(UTF-8)

「16文字」の定義がフロントエンドとサーバーで食い違っていると、画面では通るのに保存でエラーになります。 絵文字を1つ入れたテストケースを必ず1本入れてください。

日付の境界は特に注意する

日付は境界の見つけ方が数値と違います。範囲の端だけを見ていると漏れます。

境界
月末 1月31日、4月30日
うるう年の2月29日 2024-02-29(2100年はうるう年ではない
年またぎ 12月31日 → 1月1日
日付の変わり目 23:59:59 → 00:00:00
タイムゾーン UTCとJSTで日付が1日ずれる時間帯

「今日から30日後」のような相対日付の仕様では、実行するタイミングによって結果が変わります。 テストは日付を固定できる状態で書いてください。

無効値は1つずつ変える

これは技法そのものより、テストケースの書き方の話です。 無効値を複数同時に入れてはいけません。

悪い例:年齢に「-1」、名前を空欄、メールを不正形式 → まとめて1ケース
       → エラーになったが、どの項目で弾かれたのか分からない

良い例:他の項目はすべて正常値にして、年齢だけ「-1」にする
       → 年齢のバリデーションが動いていることが確認できる

複数の無効値を同時に入れると、最初に検出された1つでエラーになり、残りのチェックが動いているかどうか確認できません。「実は年齢のチェックが実装されていなかった」という不具合を見逃します。

逆に有効値は組み合わせて構いません。すべて正常な値を1ケースで通すのが基本です。

出力側にも同値分割を使う

入力だけを見ていると、出力の分岐を見落とします。

たとえば「送料は、購入金額に応じて0円・300円・550円のいずれか」という仕様なら、出力が3クラスあることになります。入力金額の境界だけでなく、3種類の送料がすべて出ることを確認してください。

条件が複数絡む場合は、決定表テストで組み合わせを整理する方が確実です。

使うときの注意点

ケースを作りすぎない

同値分割の目的は「減らすこと」です。 同じクラスから2つも3つも値を選んでいるなら、クラスの切り方が間違っているか、減らす意図を忘れています。

境界の定義を間違えない

「100件まで表示」の境界は 100 と 101 です。0件と1件も境界です。 リストが空のときの表示は、実装漏れが非常に多い箇所です。

この技法だけでは足りない領域がある

状況 使う技法
条件が複数絡む業務ロジック 決定表テスト
画面や状態が遷移する 状態遷移テスト
設定項目の組み合わせが多すぎる ペアワイズテスト

同値分割と境界値分析が扱うのは「1つの入力項目の範囲」です。項目どうしの関係は別の技法の担当になります。

まとめ

  • 同値分割でどこを見るか、境界値分析でどの値を入れるかを決める
  • 境界値は2値(境界と外側の隣)で通常は十分。3値を使うかはチームで統一する
  • 数値の境界だけで終わらせない。 空欄・全角数字・小数・前後の空白を必ず確認する
  • 「1,000円以上」は1,000円を含む。税込か税抜かも仕様書に無いことが多い
  • 文字数は絵文字と結合文字で数え方が変わる。テストケースを1本入れる
  • 日付は月末・うるう年・年またぎ・タイムゾーンが境界
  • 無効値は1ケースに1つだけ。 有効値は組み合わせてよい
  • 入力だけでなく出力の同値クラスも分ける
  • 0件・空リストの表示は境界。実装漏れが多い

この技法の本当の価値は、テスト実行ではなく仕様の穴を見つけることにあります。 上流工程での使い方はウォーターフォール開発におけるQAの重要性とテスト技法の活用法にまとめました。