同値分割・境界値分析の2値の選択と3値の選択 | 仙台ソフトウェアテスト勉強会のブログ

仙台ソフトウェアテスト勉強会のブログ

2012年から立ち上げた仙台ソフトウェアテスト勉強会のことなどを綴っていきます。

JaSST東海'12 のチュートリアル 「【テスト1年生シリーズ】はじめてのテスト技法
~テスト技法でバグ退治~」に参加してきました。(急遽スタッフwとして)

そこで同値分割・境界値分析について面白い話があったので書いておきます。


# 2012/12/01 最初に書いた解説が間違っていましたので修正しました。

# 秋山さん、指摘ありがとうございます。m(_ _)m


# 2012/12/02 さらに修正しました。

# 秋山さん、何度もありがとうございました。m(_ _)m

# やり取りはまとめましたので直接見たい方はそちらをどうぞ。まとめ


# 2012/12/03 もう少し修正しました。onポイントとoffポイントに関しては別途まとめようと思います。

# onポイントとoffポイントという言葉は知っていましたが、自分は誤解していました。。。


【問題】
入力の値が1~300(整数値)の値のときの同値分割・境界値分析はどうしますか??


同値分割クラスは以下になります。

 ①無効同値クラス:~ 0,
 ②有効同値クラス:1~300
 ③無効同値クラス:301~


②の有効同値クラスについて考えてみます。

仕様に書かれている1と300をonポイントと言い、境界を挟んで一番近い値である0, 301をoffポイントと言います。

境界値分析だと基本的にはonポイントとoffポイントの選択をしていきます。


今回の問題だと以下のようになります。テストケースは4ケース。

0(off) | 1(on) , 300(on) | 301(off)

※ただし、| を境界とする


これはJSTQBでも採用しているBeizer方式というようです。うーん初めて知りました。。。


このとき、コードは仕様に書かれている値(=onポイント)を使って以下のように書かれていると仮定します。(この仮定が重要!!)

if ((x >= 1) && (x <= 300)){

}
else{

}


何か間違えた場合にバグを検出することができるでしょうか?

if ((x > 1) && (x <= 300)){ ← [エラー] >=と>を間違えてしまった

}
else{

}


これは1を入力値としたテストケースで検出できますね。


ではこれだとどうでしょうか?

if ((x == 1) && (x <= 300)){ ← [エラー] >=と==を間違えてしまった

}
else{

}


>=と==を間違えてしまった場合は最初のテストケースだと0は無効、1は有効となりバグは検出できないですね。

(※この場合は上の方の境界値の300のケースで失敗することになりますが)


これを回避する一つの方法として中間値を取る方法があります。

これは以前の勉強会 で実施したハジ・ハジ・中間値の中間値に当たるものです。


②の有効同値クラスについてだと以下のようになります。テストケースは5ケース。

0(off) | 1(on) , 150(in), 300(on) | 301(off)

※ただし、| を境界とする




もう一つ回避する方法として、"3値の選択"というのがあるとのことです。

このときは仕様に書かれている値(=onポイント)を挟んで前後の値を取得することで3値ということになります。

今回の場合は問題より、1と300がonポイントになります。



②の有効同値クラスについて境界値分析するとonポイント+その前後で以下のようになります。テストケースは6ケースですね。

0(off) | 1(on) ,2(in), 299(in), 300(on) | 301(off)

※ただし、| を境界とする


この方法はJorgensenの方法(英国標準BS 7925-2で採用)というようです。こちらも聞くのは初めて。。。

これで>=を==としてしまったときでもエラーが検出されることになりました。


納得です!!



テストケース数が変わってきますので、どれを選ぶのかはちょっと悩みますね。

2値にするのか、2値+中間値も含めるのか、3値にするのか、是非考えてみてください。


どちらの方法を使うか、秋山さんの選択基準を教えてもらいました。参考までに。

********************************************************

どちらを使うか? ですが、私は、開発者本人が行うコンポーネントテストでは3値が良いと思っています(コーディングとテストで同じ間違えを犯すことを救うため)。

第三者がテストする際には仕様をきちんと読み直し2値で実施するのが良いと思っています。

********************************************************



今回この演習を通して、コードの書き方も大切だということを再認識しました。

同じことをやるのにもコードの書き方は沢山ありますね。

どれが理解しやすいのか、テスタビリティが高いのか、変更に強いのかを考える必要があると思います。


皆さんはどの書き方がいいと思いますか??


【その1】 仕様から想定するコード

if ((x >= 1) && (x <= 300)){


}
else{

}


【その2】無効の値を判定に使ったコード。整数なので上手くいく。

if ((x > 0) && (x < 301)){


}
else{

}


【その3】その1と逆で有効同値の処理をelseで実施しているコード

if ((x < 1) || (x > 300)){

}

else{ ← 1~300をelse内で処理・・・


}


【その4】 数値の順に判定しているコード

if (x < 1){

}
else if ((x >= 1) && (x <= 300)){

}
else if (x > 300){

}


【その5】if文の順序が変わると判定が変わってしまうコード

if (x <= 0){

}
else if ((x >= 0) && (x <= 300)){ ←0は上で引っかかっているので、入ってはこないが・・・

}
else if (x >= 301){

}