はじめに
テスト技法について学びなおす機会があり、備忘録を作りました。
本記事では、以下6つのテスト技法について紹介しています。
・同値分割
・境界値分析
・デシジョンテーブル
・組み合わせ表・直交表
・状態遷移図・状態遷移表
・Nスイッチカバレッジ
テスト技法の目的
テスト技法の目的は、
限られたリソースで効果的に不具合を見つけ、ソフトウェア品質を高めること
です。
全てのテストパターンを網羅することは現実的ではありません。
テスト技法は「重要なポイントを絞り込む」ための指針を提供します。
これにより、テスト件数を減らしつつ、不具合が発生しやすい箇所に集中してテストできます。
同値分割テスト(Equivalence Partitioning)
入力データを同値パーティション(同じ動作が期待される条件の集まり) に分け、
各グループから代表値を選んでテストする方法です。
この手法は、数値入力の検証などに役立ちます。
具体例
同値クラス分析の考え方について、以下の簡単なコードを使って説明します。
入力値が「有効年齢(0~120歳)」かどうか判断するコードです。
public class ageValidator {
public String ageValid(int age){
if (age < 0) {
return ("年齢は0歳以上でなければいけません。");
} else if (age <= 120) {
return ("有効年齢");
} else {
return ("年齢は120歳以下でなければいけません。");
}
}
public static void main (String[] args) {
//ageValidメソッドを呼び出し
}
}
このコードの同値クラスは、出力メッセージを基準に次の3つに分けることができます:
・有効な年齢(0歳以上、120歳以下)
・無効な年齢(負の数)
・無効な年齢(121歳以上)
「有効・無効を調べるのに、同値クラスは2つで十分では?」と思うかもしれません。
しかし、例のコードでは無効年齢でも0歳未満、121歳以上で出力メッセージが異なります。
つまり、期待される動作が異なるため、同値クラスとして分ける必要があるのです。
例示したコードを、同値クラス2つで足りるように修正すると、以下のようになります:
public class ageValidator {
public String ageValid(int age){
if (age <= 0 && age <= 120) {
return ("有効年齢");
} else {
return ("年齢は0歳以上120歳以下でなければいけません。");
}
}
public static void main (String[] arge) {
//ageValidメソッドを呼び出し
}
}
境界値分析
境界値(仕様条件の境界となる値)とその隣の値に注目してテストを行う技法です。
バグは境界付近に集中しやすく、境界値の前後にテストケースを設定することが有効です。
具体例
同値クラスのパラグラフで使用したサンプルコードを再利用します。
public class ageValidator {
public String ageValid(int age){
if (age < 0) {
return ("年齢は0歳以上でなければいけません。");
} else if (age <= 120) {
return ("有効年齢");
} else {
return ("年齢は120歳以下でなければいけません。");
}
}
public static void main (String[] args) {
//ageValidメソッドを呼び出し
}
}
境界値=異なる同値パーティションが隣り合っている部分と理解してください。
境界値は、数直線上に表すと非常にわかりやすくなります。
図で示した通り、境界値分析では境界値(0歳、120歳)に加え、その直前・直後の値(-1、1、119、121)もテストケースに含めます。
デシジョンテーブル
デシジョンテーブルは、複雑な条件分岐を整理するための手法です。
複数の入力条件があり、それら条件の組み合わせによって異なる結果が得られる場合、
条件と結果を表形式でまとめることができます。
デシジョンテーブルの考え方
デシジョンテーブルの作成にあたって、以下2点を考える必要があります:
・条件(各アクションの発生に必要な状態・前提)
・アクション(条件の組み合わせによって発生する動作結果)
例として、会員種別(会員 / 非会員)と購入金額(5000円未満 / 5000円以上)に基づく割引ルールをデシジョンテーブルで表現してみます。
この例における条件・アクションを以下のように設定します。
| 会員・非会員 | 購入金額 | 割引率 |
|---|---|---|
| 会員 | 5000円未満 | 5% |
| 会員 | 5000円以上 | 10% |
| 非会員 | 5000円未満 | 0% |
| 非会員 | 5000円以上 | 3% |
デシジョンテーブルにおけるデータの数は、条件数をnとすると、基本的に2のn乗 です。
各条件が必ず「成立する」「成立しない」という2つの状態のいずれかをとるためです。
言い換えると、各条件が真・偽などの2値をとらない場合・デシジョンテーブルを簡略化した場合などは、この限りではありません。
各条件の組み合わせをすべてカバーするデシジョンテーブルは、以下のようになります。
組合わせ表・直交表(Combination Table/Orthogonal Array)
組み合わせ表(直交表)は、複数の入力条件がある場合に全ての組み合わせをテストせず、効果的にテストケースを選定するための手法です。直交表を用いることで、必要なテストケース数を大幅に減らすことができます。
直交表では、条件の組み合わせを均等に選んで、テストケースを最小化します。インターネットや書籍では、様々な直交表テンプレートやツールが提供されており、これらを活用することができます。
具体例
以下のルールに基づいて画面遷移が異なるeコマースサイトを考えてみます。
・条件A: カートの中身(空 / 商品あり)
・条件B: 会員ステータス(会員 / 非会員)
・条件C: 支払い方法(クレジットカード / 現金)
それぞれの条件は因子と呼ばれ、各因子がとりうる状態(カートが空・カートに商品がある等)を水準と呼びます。上記のルールは3因子2水準ということになりますね。
この水準数を満たす、最適な直交表のテンプレートを選択します。
状態遷移図・状態遷移表
状態遷移図(または状態遷移表)は、システムが取り得る状態と、その間の遷移をモデル化したものです。状態遷移図は、特に状態に依存するシステムに対して有効な手法です。状態遷移を視覚的に表現することで、どの入力がどの状態に遷移するかを明確に理解でき、効率的にテストケースを設計できます。
具体例
自動販売機の動作を考えた場合、以下のような状態遷移を考えることができます。
初期状態:お金を入れていない
お金を入れる → 「商品選択状態」
商品のボタンを押下 → 「商品出力状態」
商品出力後・またはエラーメッセージ表示後一定時間経過 → 「初期状態」
お金が足りない場合 → 「エラー状態」
状態遷移図は以下のようになります。
状態を丸で示し、各状態に移動するイベントを矢印とともに示しています。矢印の方向が遷移先です。

実は上記の例は遷移条件の洗い出しが不十分です。
そのため、状態遷移表に移動すべき状態が不明な状態・イベントの組み合わせがあります(黄色部分)。
このように、状態遷移図は状態遷移が視覚的に理解しやすいものの、遷移条件がすべて洗い出せているかわかりづらいという欠点があります。
状態遷移表は反対に、遷移条件の不足が一目でわかります。
状態遷移図と状態遷移表を両方使うことで、システムの動作を視覚的に理解しやすく、テストケース設計や仕様の確認が行いやすくなります。
Nスイッチカバレッジ
状態遷移の経路を網羅するテストで、スイッチとは「事前状態と事後状態の間にある状態」を意味します。
0スイッチは事前状態・事後状態の間に何も状態がないことを意味し、A→Bのような一度のイベント遷移を指す、といった具合です。
システムにおける複数の条件が連鎖的に影響を与える場合に有効なテスト技法です。
具体例
以下のような状態遷移図のストップウォッチの1スイッチ・2スイッチカバレッジを考えます。

0スイッチカバレッジ
0スイッチ=1つの状態遷移を網羅すればよいので、縦列の事前状態から1つのイベントを経て横列の事後状態へ遷移する形で表します。
1スイッチカバレッジ
1スイッチ=2つの状態遷移を網羅すればよいので、縦列の事前状態から2つのイベントを経て横列の事後状態へ遷移する形で表します。
各イベントの組み合わせにおいて、左から順に書いていき、「、」で区切る形で表記します。
おわりに
ソフトウェアテスト技法は目的に合わせて様々な手法がありますので、使いこなすまでには慣れが必要かと思いますが、頑張って覚えましょう。
半分自分のために作成した記事ですが、テスト技法に初めて触れる方、あるいは学び直したい方にも何らかの利があれば幸いです。





