『ソフトウェアテスト技法練習帳』の勉強会で、めちゃくちゃいい質問がありました。
その場で答えてはみたのですが、すごく大事な話だと感じたので、ブログ記事にしておきたいと思います。ただわたし自身の理解も足りていないかもしれないので、お気づきの点があればフィードバックお願いいたします。
3行まとめ
- デシジョンテーブルテストは、「複数の条件を組み合わせた場合の動作」を検証する技術である。
- 「組み合わせる前の単一条件の動作」は、デシジョンテーブルテストの前に検証しておく必要がある。
- デシジョンテーブルで2つ目もカバーできると思っていると、痛い目に合うかもしれない。
デシジョンテーブルの超圧縮!?
対象の問題は、本書「2.3 紳士服店の割引率」。
問題を雑に簡略化するとこうなります。
以下の仕様に基づいて、デシジョンテーブルを書け。
「ワイシャツとネクタイを含めて7点以上買えば、7%引きになる」
単純には、以下のようになります。
7点以上⋀ワイシャツあり⋀ネクタイあり ならば、7%引き。それ以外は割引なしと。
特にヒネリはありません。
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
---|---|---|---|---|---|---|---|---|
7点以上 | T | T | T | T | F | F | F | F |
ワイシャツあり | T | T | F | F | T | T | F | F |
ネクタイあり | T | F | T | F | T | F | T | F |
割引7% | T | F | F | F | F | F | F | F |
これに対して、以下の質問をもらいました。
「ワイシャツあり」「ネクタイあり」の条件を別々にせず、「ワイシャツとネクタイが入っている」という1つの条件にしてはいけないのか。
なるほど。これをヨシとすると、以下のようになります。
1 | 2 | 3 | 4 | |
---|---|---|---|---|
7点以上 | T | T | F | F |
ワイシャツとネクタイあり | T | F | T | F |
割引7% | T | F | F | F |
なんと、テストケース数が半分になりました!
ただそんなうまい話があるわけもなく、何か失っているものがありそうです。何しろ、これを突き詰めていくと、これでもいいのですからね・・・。
1 | 2 | |
---|---|---|
7点以上でワイシャツとネクタイあり | T | F |
割引7% | T | F |
具体的なテストケースを考えてみると・・
さて、少し話が変わります。
デシジョンテーブルでテストケースを導出したとして、ではそのままテストができるでしょうか?
いいえ、必ずしもそうではありません。
たとえば最初のテーブルの#1のテストケース、「7点以上」という条件がTになっていますが、具体的には何点にしましょうか。また「ワイシャツあり」とありますが、ワイシャツは何点含めましょう。
てな感じで、実際にテストを行うにはもうワンステップ、テストデータの具体化が必要なわけです。
では、2つ目のデシジョンテーブル(以下再掲)のために、こんなテストデータを用意します。
1 | 2 | 3 | 4 | |
---|---|---|---|---|
7点以上 | T | T | F | F |
ワイシャツとネクタイあり | T | F | T | F |
割引7% | T | F | F | F |
- #1: ワイシャツ×3、ネクタイ×3、ソックス×4
- #2: ソックス×10
- #3: ワイシャツ×3、ネクタイ×3
- #4: ソックス×3
もし実装が以下のようになっていれば、このテストはすべて通るでしょう。
7点以上 ⋀ (ワイシャツあり ⋀ ネクタイあり) → 割引7%
一方、以下のように実装が間違えまくっていても、このテストはすべて通ります。
9点以上 ⋀ (ワイシャツあり ∨ ネクタイあり) → 割引7%
デシジョンテーブルで網羅的にテストをしたはずなのに、一体、何が悪かったのでしょうか・・?
ブレイクタイムに書かれた重要な注意書き
実はこの2.3のコラム欄「ブレイクタイム」に、こんなことがさらっと書かれています。
デシジョンテーブルを使ってテストをしたからといって、十分にテストをしたとは言えません。なぜなら、デシジョンテーブルは条件の組み合わせを網羅するものであり、個々の条件をテストするものではないからです。
これは、単体テスト→統合テスト→システムテストと、小さな範囲のテストを積み上げていくことに似ています。部品の組み合わせのテストをする前に、部品自体のテストをする必要があるということです。
では、先のデシジョンテーブル(以下再掲)を元に、部品である個々の条件を調べてみましょう。
1 | 2 | 3 | 4 | |
---|---|---|---|---|
7点以上 | T | T | F | F |
ワイシャツとネクタイあり | T | F | T | F |
割引7% | T | F | F | F |
条件「7点以上」
「7点以上」という単一の条件自体が正しく動作するかを確認してみましょう。
この場合は、デシジョンテーブル上で「7点以上」の値だけが結果に影響を与えるテストケースを選んで、境界値テストをすることができます。
1 | 3 | |
---|---|---|
7点以上 | T = 8点 | F = 7点 |
ワイシャツとネクタイあり | T | T |
割引7% | T | F |
ここでもし実装が上述のように
9点以上 ⋀ (ワイシャツあり ∨ ネクタイあり) → 割引7%
と誤っていれば、#1のテストが失敗(割引7%がFになってしまう)で検知できることになります。
条件「ワイシャツとネクタイあり」
「ワイシャツとネクタイあり」という条件が正しく効いているのかの確認には、テストケース#1と#2を使います。
1 | 2 | |
---|---|---|
7点以上 | T | T |
ワイシャツとネクタイあり | T ワイシャツあり ネクタイあり |
F ワイシャツあり ネクタイなし ワイシャツなし ネクタイあり ワイシャツなし ネクタイなし |
割引7% | T | F |
そう、デシジョンテーブルの中で1つの条件に丸めることで、一見テストケースが減ったように見えましたが、部品の確認のために結局、ワイシャツとネクタイのあるなしの組み合わせを個別に確認する*1ことになるのです。
つまり、やるべき具体的テストケースの数は別に減っちゃいないということですねー。
まとめ
再掲。
- デシジョンテーブルテストは、「複数の条件を組み合わせた場合の動作」を検証する技術である。
- 「組み合わせる前の単一条件の動作」は、デシジョンテーブルテストの前に検証しておく必要がある。
- デシジョンテーブルで2つ目もカバーできると思っていると、痛い目に合うかもしれない。
勉強会での質問を受けて、あらためて認識しました。これを説明しているところって、意外に少ない気がしましたが、どうでしょう*2?
なお本稿は、ネモトノリユキさん、しましまさん、ブロッコリーさんにレビューいただきました。ありがとうございます。
追記 (2024/9/24)
秋山さんから以下のコメントをいただきました。
先に条件(condition)と判定(decision)を教えてからデシジョンテーブルテストの説明をしないとそう言う質問がくるかもですね。
— あきやま🏀 (@akiyama924) 2024年9月23日
疑問に思っても質問しない人が多いから良い質問だけれど。
ここでいう「条件」とは、「7点以上である/ない」「ワイシャツがある/ない」「ネクタイがある/ない」の、各単一条件を指します。
判定とは、単一条件を組み合わせた結果、「割引がある/ない」という判定がどうなるかを指します。
*1:なし/なしを省略する作戦はありうる
*2:ブロッコリーさんから、『ASTERセミナー標準テキスト』に近いことが書かれている、とコメントいただきました。確かに演習問題の方のファイルP.23に、以下の説明がありました。
それぞれの条件に対して同値分割法・境界値分析を適用する。