ソフトウェアの品質を学びまくる2.0

ソフトウェアの品質、テストなどについて学んだことを記録するブログです。旧ブログからゆっくり移行中です。http://blog.livedoor.jp/prjmng/

ドメイン分析テスト周りの用語の整理メモ

 Twitter上で不定期に議論になる、ドメイン分析テストにおけるOn/Off、In/Outなどについての整理メモ*1です。
 同値分割、境界値分析、ドメイン分析についての概要を知っていることを前提としています。

用語の定義

 『ソフトウェアテスト技法ドリル』でも『はじめて学ぶソフトウェアテスト技法』でも、On/Off、In/Outはドメイン分析テストで導入される概念です。

ソフトウェアテスト技法ドリル―テスト設計の考え方と実際

ソフトウェアテスト技法ドリル―テスト設計の考え方と実際

 ドメイン分析テストでは、あるパラメタの境界値に対し、別のパラメタの「あたりさわりのない値」を組み合わせていきます。これをクリアに整理するために、境界値分析ではなくドメイン分析テストで説明しているのではないかと思います。

On/Off、In/Out

 ドリル本では以下のように定義しています。文章からの抜粋です。

  • On 注目している境界値
  • Off Onポイントに対して境界値分析をしたときに見つかる隣接したもう一つの境界値
  • In ドメインの内側(On/Off以外)
  • Out ドメインの外側(On/Off以外)

 ドメインの内側か外側かというのは排他であり、OnとOffも排他なので、この4つの概念はMECEです。

ドメイン開/閉の定義

 ドメインの開閉は以下のように区別されます。リー・コープランドさんの『はじめて学ぶソフトウェアテスト技法』を参考にしています。

はじめて学ぶソフトウェアのテスト技法

はじめて学ぶソフトウェアのテスト技法

  • ドメイン境界が「=」「≧」「≦」で表現される場合、そのドメインは「閉じて」いる。
  • ドメイン境界が「>」「<」で表現される場合、そのドメインは「開いて」いる。

 ではそれぞれ、絵と一緒に見ていきます。

ドメインが「自然数n≧10」である場合

 これ以降の絵の黒丸●と白丸〇は、有効同値・無効同値の意味ではなく、明示した数字を含む(●)か含まない(〇)かの意味です。

01

 ドメインの定義に使われている「10」がOnになります。境界の逆側すぐそばにある「9」がOffになります。
 ドメインの内側にあるもののうち、On/Offを除く11以上の自然数がInになります。
 ドメインの外側にあるもののうち、On/Offを除く8以下の自然数がOutになります。

ドメインが「自然数n>10」である場合

02

 ドメインの定義に使われている「10」がOnになります。On自体はドメインの内側にないことに注意が必要です。
 境界の逆側すぐそばにある「11」がOffになります。
 ドメインの内側にあるもののうち、On/Offを除く12以上の自然数がInになります。
 ドメインの外側にあるもののうち、On/Offを除く9以下の自然数がOutになります。

ドメインが「自然数n=10」である場合

03

 ドメインの定義に使われている「10」がOnになります。
 この場合、隣り合うドメインは、10の右と左の両側にあるので、境界の逆側すぐそばにある「9」と「11」がOffになります。
 ドメインの内側にある10がInになりそうですが、Onに該当する値はInから除かれるので、この場合Inはありません。
 ドメインの外側にあるもののうちOn/Offを除く、8以下の自然数と12以上の自然数がOutになります。

各要素の関係

 On/Off/In/Out、ドメインの開閉、ドメインの内外で、単純には組み合わせが16パターンありそうですが、以下の制約があるために実際には8パターンしか現れません。

  1. 開いている ∧ On ⇒ 当該ドメイン外*2
  2. 開いている ∧ Off ⇒ 当該ドメイン内
  3. 閉じている ∧ On ⇒ 当該ドメイン内
  4. 閉じている ∧ Off ⇒ 当該ドメイン外
  5. In ⇒ ドメイン内
  6. Out ⇒ ドメイン外

 Boris Beizerさんはこの2個目と4個目を、「COOOOI (Closed Off Outside, Open Off Inside)」と称しているそうです。

ドメインの内外と、クラスの有効無効

 さて、ここまで「有効同値クラス」「無効同値クラス」という言葉を使っていません。最初の例がもし、「10以上の自然数のみを受け入れる」というものであれば、9以下の自然数は無効クラスになります。よってドメイン内は有効同値クラスに相当し、ドメイン外は無効同値クラスに相当することになります。

 一方、「10歳以上は有料とする」という仕様を対象にするテストであれば、10以上も9以下も有効同値クラスです。この閉じた境界仕様で「9歳」はOffにあたりますが、無効同値クラスではありません。
 ドメインの内外と、クラス有効無効を混同しないというのも注意点の1つかなと思います。

コープランドさんの定義

 さて、コープランド本も確認しておきましょう。

はじめて学ぶソフトウェアのテスト技法

はじめて学ぶソフトウェアのテスト技法

 On/Off、In/Outは以下のように定義されています。

  • Onポイント 境界上の値
  • Offポイント 境界上になく境界に隣接する値
  • Inポイント すべての境界条件を満たすが境界上にはない値
  • Outポイント いずれの境界条件も満たさない値

 ドリル本と、Offの定義が違うように見えませんか?

  • Off Onポイントに対して境界値分析をしたときに見つかる隣接したもう一つの境界値

 ドリル本では、Offを「もう一つの境界値」としている。コープランド本では、Offを「境界上にない」としている。
 この違いはどこから生まれるのかいろいろ考えたのですが、「境界」に対するイメージの違いなのかなと解釈しています。

 ドリル本だと、境界はこの斜線部分の両端です。物理的なパーティションと同じように厚みがあり、その表面がそれぞれ「境界」です。

04

 コープランド本だと、境界はあくまで「10」上の、厚みのないものです。よってOffは境界上にないことになります。

05

 この例ではnを自然数としていますが、値が連続値の場合はどうなるでしょう。パーティションの厚さはどんどん薄くなり、最終的には、そして数学的にはゼロになりそうです。

 ソフトウェアの場合はどうでしょう。
 精度が無限に高いということはなく、どこかの桁で止まることになります。パーティションは有限の厚さ(ドリル本でいう「d」にあたる)を持つことになります。と考えると、イメージとしてはドリル本の定義の方がしっくりくるように思います。

 同値分割に関する湯本さんの記事に、以下のようなお話がありました。

境界値に仕切り板は1枚なはずですが、同値クラスの箱で考えると隣接する複数の仕切り板があるように考えられてしまいます。けど、そんなことテストケースの洗い出しで考えられないです。仕様からちゃんと境界値、つまりOnPointを分析しなければならないのはそう言う理由だと思います。

 この「複数の仕切り板」というのが、「有限の厚みをもつ壁の両端」に当たるのではないかなあと思います。

*1:この記事は、以下のスレッドなどで秋山さんや辰巳さん に教えていただいたことを自分なりに表現したものです。いつもありがとうございます。

*2:ドリル本では「隣接ドメイン内」と呼んでいます。

同値分割の「partition(ing)」という単語についてのメモ

 同値分割に関する湯本さんのnoteを読んでの、単なるメモです。

note.mu

 そもそも、part、partition、partitioning と、英単語の時点でややこしいんですよね。以下、Oxford Dictionaryからの引用ですが、適宜はしょっています。

part

An amount or section which, when combined with others, makes up the whole of something.

 日本語でいう「部分」ですね。他の「部分」と合わせることで、「全体」を為す。ちょっと哲学的な言い回しです。

partition

 こちらは、名詞と動詞の両方の意味があります。

(n.)1. the action or state of dividing or being divided into parts.
部分に[分割する|される][動作|状態]。

 4つの組み合わせがありますが、JSTQBの文脈では「分割された状態・結果」が近そうです。なぜなら、「equivalence partition」が以下のように説明されている*1ためです。  

Equivalence partition
A portion of the value domain of a data element related to the test object for which all values are expected to be treated the same based on the specification.

 名詞の方はもう一つあります。

(n.)2. A structure dividing a space into two parts, especially a light interior wall. 空間を2つの部分を分割する構造、特に軽量な室内用壁。

 これは日本語でいう「パーティション」に相当しますね。

 次に動詞。

(v.)1. Divide into parts.
部分に分割する。

 「分割する」という動詞ですね。
 「区画する」という言葉もぴったりするかもしれません。

 ただJSTQB的には、「partition」は(n.)1的な意味で使って、動詞っぽさを出す時には、後述する「partitioning」を使っているのかも。また、(n.)2的な意味で使うと混迷が深まりそうです。  

partitioning

 これは動名詞であり、「分割すること」と捉えていいでしょう。
 Equivalence Partitioning は「同値(クラスに)分割(すること)」と補うと自然ですね。

 以上、特にスルドイ考察、深い見解はありません・・・・・・。

*1:湯本さんの記事からの孫引き・・・

【読書メモ】世界の「かつて」と「今」を正しく捉えるための『FACTFULNESS』

FACTFULNESS(ファクトフルネス) 10の思い込みを乗り越え、データを基に世界を正しく見る習慣

FACTFULNESS(ファクトフルネス) 10の思い込みを乗り越え、データを基に世界を正しく見る習慣

  • 作者: ハンス・ロスリング,オーラ・ロスリング,アンナ・ロスリング・ロンランド,上杉周作,関美和
  • 出版社/メーカー: 日経BP社
  • 発売日: 2019/01/11
  • メディア: 単行本
  • この商品を含むブログ (1件) を見る

 『FACTFULNESS』は、「人間の正解率がランダム以下」になってしまう「チンパンジークイズ」でも話題になったようです。最近の『東洋経済』でも、「統計的な事実を知らない人々」という文脈で紹介されています。 factquiz.chibicode.com

 しかし『FACTFULNESS』を「統計に関する本」と分類してしまうと、大きく外してしまうことになります。

 確率や統計を面白く語った本は、これまでもたくさんありました。
 たとえば、人間の行動の不可思議さを、統計を使って説明するダン・アリエリー氏の著作。

ずる 嘘とごまかしの行動経済学

ずる 嘘とごまかしの行動経済学

 ここでいう統計は主にインタビューの結果であり、そこから得られるのは「設問に答えに対する真実」よりもむしろ、「人々がどう振る舞うかの真相」でした。たとえば、「祖母が亡くなる確率」は、中間試験の前は10倍、期末試験の前には19倍に跳ね上がる。成績が芳しくない学生は、そうでない学生に比べて、「祖母を亡くす」確率が50倍も高い、のだそうです・・・。

 あるいは、『リスク・リテラシーが身につく統計的思考法』。こちらは、統計から得られる結論が時に非常にミスリーディングなものになることを教えてくれます。

www.kzsuzuki.com

 『FACTFULNESS』は、このどちらとも違います。
 数字は容易に手に入るもの。そこから読み取れる「事実」も、シンプルなもの。しかし人々はそもそも、単純な統計から得られるそれらの事実を知らない。賢い人も含めて多くの人が、世界の現在を正しく把握できていない、というのです*1

 「過去と現在の世界のありよう」を正しく理解しするには、「正しい統計を正しく見る」必要があります。世界の状況についての「正しい統計」を手に入れることがそう困難ではない一方、「正しく見る」ためにはいくつかの注意が必要であることを、本書は教えてくれます。

 それでもなお、この本は「統計に関する本」ではないと言いたい。

 それぞれの物語に裏にある数字を見ようとすることは大切だ。でもそれと同じくらい、数字の裏にある物語を見ようとすることも大切だ。数字を見ないと、世界のことはわからない。しかし、数字だけ見ても、世界のことはわからない。(第5章 過大視本能 より引用)

 世界は決して最善ではないけれど、確実に善くなっている。「先進国」のわたしたちが「あの人たち」と分断しがちな国の人々の暮らしは、わたしたちがそう遠くない過去に克服してきた暮らしなのだ。統計と、その背後にある事実を正しく理解すれば、あるべき方向に向かうことができる。世界はこれからも善くなっていける

 それが本書のテーマなのだとわたしは受け取りました。

 400ページというそれなりの厚さ、扱っているのは「世界」と「統計」、にもかかわらず、著者(たち)の一貫した強いパッションが伝わってきてグイグイ読み進めてしまう、意欲的でとってもフェアな、素晴らしい本でした。
 そしてついでに、「お、このバブルチャートは仕事にも使えそうだな・・」と、「世界」とまったく関係ないことにも思いを巡らせたのでした・・・。

 ちなみにこの本を読んで、糸井重里さんの有名な以下のツイートを思い出しました*2。  

*1:その「誤解」の内容が本書の読みどころでもあるので、内容を書いてしまうと読む楽しみを損ねてしまうので、書けないのですが。

*2:このツイートのツリーにも、思った以上に悪意がぶら下がっていて驚いた・・・。

有則のテストは「組み合わせテスト」の技法に含まれるのか?

 Twitterで、「組み合わせテストに分類されるテスト技法はどれか」という話が流れていました。
 デシジョンテーブル、原因結果グラフ、原因流れ図といった、いわゆる「有則」のテスト技法でも命題の真偽の組み合わせを考えますが、これは組み合わせテストに含まれるかそうでないのか、というものです。

 わたし自身以前、(無則の)組み合わせテストを人に説明するときに少しモヤモヤしたので、自分の意見を整理しておきます。

TL;DR *1

  • 自分の中で整合性が取れていて、かつ世の中の一般的な理解から大きくハズレていなければいい*2

  • 用語が有名なのに指す範囲が人しだいというのは議論の妨げになるので、立場を明確にしておくのがベター。
  • combinatorial testing はテクニカルタームとして、無則の組み合わせテストを指すとすると都合がいい。
  • 有則のテストの中にも「組み合わせのテスト」はある、と補足しておくといい。

combinatorial とは

 とりあえずJSTQBの用語集で「組み合わせテスト」を検索すると、以下の結果が出ます*3

組み合わせテスト(combinatorial testing)
ブラックボックステスト設計技法の一つ。複数のパラメータの値を特定の組み合わせで実行するためのテストケースを設計する。

 そもそも、combinatorial というのがふだん見慣れない単語ではないでしょうか。combinational とどう違うのか

 こんなときにに役に立つのが「vs検索」ですね。
 たとえば、ともに「継続」のニュアンスがある continuous と continual の違いが知りたければ、「continuous vs continual」で検索して、信頼できそうなサイトを読んでみることでそれなりに理解できることが多い。下のサイトを見ると、continuousは「頻度は高いが断続的である」ようなニュアンスがあることがわかります。 en.oxforddictionaries.com

 という成功体験を胸に、調べてみましょう。

wikidiff.com

As adjectives the difference between combinatorial and combinational is that
combinatorial is of, pertaining to, or involving combinations
while
combinational is of or pertaining to (a) combination.

 明確な違いが、「combinations」なのか、「a combination」なのか、だけ・・・? なんかもっとこう・・・。

 以下は数学の文脈になってしまいますが、また名詞と形容詞の比較なので少し奇妙ですが、

wikidiff.com

In context|mathematics|lang=en terms the difference between combination and combinatorial is that combination is (mathematics) one or more elements selected from a set without regard to the order of selection while combinatorial is (mathematics) of or pertaining to the combination and arrangement of elements in sets.

 これもなかなか難しい。
 ただここで「数学」というキーワードから、「順列」「組み合わせ」と関係あるのでは?と思っていろいろググって見ると、「組み合わせ数学」(combinatorics)という分野があるのですね。組み合わせ最適化(combinatorial optimization)もこの分野に含まれていることがわかります。

ja.wikipedia.org

 組合せ数学(くみあわせすうがく、combinatorics)や組合せ論(くみあわせろん)とは、特定の条件を満たす(普通は有限の)対象からなる集まりを研究する数学の分野。特に問題とされることとして、集合に入っている対象を数えたり(数え上げ的組合せ論)、いつ条件が満たされるのかを判定し、その条件を満たしている対象を構成したり解析したり(組合せデザインやマトロイド理論)、「最大」「最小」「最適」な対象をみつけたり(極値組合せ論や組合せ最適化)、それらの対象が持ちうる代数的構造をみつけたり(代数的組合せ論)することが挙げられる。

 これで、最初の「combinations」「a combination」の意味が何となくみえてきます(個人の感想です)。
 a combination は、「組み合わせの行為・結果」です。たとえばA~Eまでのチームがあったとして、最初の試合が「チームA vs チームC」であれば、「AとC」というのは a combination。日本語の「組み合わせ」にほぼ合致しそうです。combinational はそれを形容詞にしたもの。
 combinatorial は、結果自体ではなく、a combination に至るまでの組み合わせの「基準」や「方法」を含意しているように感じます。たとえば先の5チームでリーグ戦を行うとき、「総当たり」などの組み合わせ導出のアルゴリズムを考えることが combinatorial な議論であり、その結果導出される複数の組み合わせ10試合が combinations になるわけです。

組み合わせテストに含まれる技法は?

 やっと話が戻ってきます。
 Twitterの議論のポイントは、「組み合わせテストは、無則の組み合わせのみを指すのか、有則の組み合わせも指すのか」というものでした。

ISTQBでの扱い

 用語集では以下のように定義されています。

 ブラックボックステスト設計技法の一つ。複数のパラメータの値を特定の組み合わせで実行するためのテストケースを設計する。

 これを読むと、無則に限るものではないと読めますね。
 またTechnical Analystシラバスでは以下のように記載されています。

Combinatorial testing is used when testing software with several parameters, each one with several values, which gives rise to more combinations than are feasible to test in the time allowed. The parameters must be independent and compatible in the sense that any option for any factor can be combined with any option for any other factor. Classification trees allow for some combinations to be excluded, if certain options are incompatible. This does not assume that the combined factors won’t affect each other; they very well might, but should affect each other in acceptable ways.

 組み合わせテストは、複数の値を持つ複数のパラメータを含むソフトウェアをテストする場合で、組み合わせ数が、許容される時間内にテスト可能な数よりも多く存在するときに使用する。どのようなパラメータのどのようなオプションでも、他のどのようなパラメータのどのようなオプションと組み合わせられるという意味で、パラメータ間に依存関係はなく、両立させるべきである。

 「パラメタは独立しており、各値が自由に組み合わせられる」という記述は、無則のテストを想起させますね。用語集より一歩踏み込んでいます。
 またそもそもTAのシラバスは、章構成としても、「3.2.3 デシジョンテーブル」「3.2.4 原因結果グラフ法」とは別に「3.2.6 組み合わせテスト技法」となっており、有則のテストを組み合わせテストの外に位置づけているようにも読めます。

 ところが。

 この辰巳さんのご指摘*4の箇所を引用すると、以下です。

Combinatorial test techniques are useful for testing the implementation of system requirements that specify how different combinations of conditions result in different outcomes. One approach to such testing is decision table testing.

 確かに combinatorial test techniques という言葉が出てきます。このシラバス内で、combinatorial という単語が出てくるのはこの箇所だけのようです。
 ISTQBの既存のシラバス・用語集での立ち位置を考えると、デシジョンテーブルを combinatorial testing の一つとして扱うのは確かに奇妙、と思います。

『ソフトウェアテスト技法ドリル』での扱い

 わたしのバイブルでもある『ソフトウェアテスト技法ドリル』を確認してみましょう。

ソフトウェアテスト技法ドリル―テスト設計の考え方と実際

ソフトウェアテスト技法ドリル―テスト設計の考え方と実際

 「本書の読み方」の表1によると、以下のように分類されています。

論理組合せテスト
ドメイン分析テスト
デシジョンテーブル
原因結果グラフ
CFD法

無則組合せテスト
HAYST法
スライド法
ペアワイズ

 前者はいわゆる「有則」に相当しますので、有則・無則の双方に、「組み合わせテスト」という言葉を当てたうえで、「論理の」「無則の」という言葉で区別しています。 

まとめ

 有則の組み合わせにせよ無則の組み合わせにせよ、「組み合わせの方法を与える」という意味では、combinatorial とはいえそうです。
 一方、コードカバレッジ基準、たとえばMC/DC(改良条件判定カバレッジ)だって真偽値の「組み合わせ方」ではあり、それらを全部 combinatorial testing と呼んでしまうと、名前をつける意味すらなくなってしまいます。

 ということで再掲ですが、以下のように考えます。

  • 自分の中で整合性が取れていて、かつ世の中の一般的な理解から大きくハズレていなければいい。
  • 用語が有名なのに指す範囲が人しだいというのは議論の妨げになるので、立場を明確にしておくのがベター。
  • combinatorial testing はテクニカルタームとして、無則の組み合わせテストを指すとすると都合がいい。
  • 有則のテストの中にも「組み合わせのテスト」はある、と補足しておくといい。

 次回は、「組み合わせ」と「組合せ」の違いについて検討していきたいと思います。より深刻だよ。

*1:1回書いてみたかっただけ。「too long; didn't read」の略なんですね。en.wikipedia.org

*2:居駒さんからのご指摘を踏まえて、4/6に書き直しました。

元の文章は以下です。

有則のテストも「組み合わせのテスト」ではあると補足しておくといい

*3:2019年4月3日時点。

*4:なお一連の辰巳さんのツイートは、一通り読んでおくべきですね・・・、。

ソフトウェアテスト技法の使い間違いって何? 彼氏はいるの? 性格が悪いって本当? 調べてみました!#テストアドカレ

 この記事は、ソフトウェアテストの小ネタ Advent Calendar 2018、17日目の記事です(先走り)。

qiita.com

 16日は、mktkさんの以下の記事でした。

panmania.hatenadiary.com

15216848023_d54c7e6344_o無意味な風景画像

0. テスト技法の「使い間違い」

 テスト技法にはそれぞれ使い所があり、また使う上での注意点があります。使い方を間違えると、良いテストを作るはずが、逆の効果をもたらしかねません。
 この記事では、テスト技法の使い間違いによってテストケースが漏れてしまう様子を、『ソフトウェアテスト技法ドリル』の例題を使って眺めてみましょう。

ソフトウェアテスト技法ドリル―テスト設計の考え方と実際

ソフトウェアテスト技法ドリル―テスト設計の考え方と実際

1. デシジョンテーブル: 実装を無視して圧縮する!

1-1. 圧縮とは?

 『ドリル』の第3章では、デシジョンテーブル(決定表)を扱っています。
 この章の例題の仕様は、ざっくり以下の通りです。

「商品カテゴリーが書籍である」 かつ 「価格が1,500円以上である」 かつ 「配送先が離島でない」 場合に「送料が無料」となる。

 3つの条件がそれぞれ「真」「偽」の2つの値を取るので、完全なデシジョンテーブルの列数は23=8になります。

テストケース12345678
条件書籍であるTTTTFFFF
1,500円以上であるTTFFTTFF
離島でないTFTFTFTF
動作送料無料TFFFFFFF

 ですが、場合によってはこれを「圧縮」することができます。『ドリル』から引用します(太字筆者、以下同様)。

圧縮とは、列をまとめて総規則数を減らすことです。その方法は同じ動作(結果)をもつテストケースのなかで、結果に影響を及ぼす行が1行しかなかった場合、その列をまとめて結果に影響を及ぼす行のセルを「Y」でも「N」でもどちらでもよいという意味で「ー」に変更するという方法です。

 圧縮したデシジョンテーブルは以下のように8列が4列になっており、半分のテストケースが削減できることになります。

テストケース1234
条件書籍であるTTTF
1,500円以上であるTTF
離島でないTF
動作送料無料TFFF

1-2. 圧縮の注意点と具体例

 デシジョンテーブルの圧縮には、重要な注意点があります。

このときに重要となるのは、条件が処理される順番です。どの規則も、品物、合計金額、配送先の順で処理されるから...圧縮できるのです。

 つまり、プログラムの実装を無視して圧縮すると、本来必要なテストケースが漏れることがあるということです。
 直感的には理解できるのですが、いざ「じゃあどんな場合?」と考えたときに、例がパッと出てこなかったため、考えてみました。
 以下のような仕様としましょう。

  • 仕様1: 書籍 かつ 1,500円以上 かつ 離島以外 なら、配送料無料
  • 仕様2: 書籍 かつ 1,500円以上 かつ 離島 なら、配送料300円
  • 仕様3: 書籍 かつ 1,500円以上でない なら、配送料400円
  • 仕様4: 書籍でない かつ 離島以外 なら、配送料500円
  • 仕様5: 書籍でない かつ 離島 なら、配送料1,000円

 この順番のまま素直にデシジョンテーブルを作ると、以下のようになります。

テストケース12345
条件書籍であるTTTFF
1,500円以上であるTTF
離島でないTFTF
動作送料無料無料300円400円500円1,000円

 ドリル本の圧縮テーブルとの違いは、#4と#5です。ドリル本では、書籍がF判定だった時点で結果は1つだったのですが、こちらはもう一度判定が必要になります。
 ハイフンは「TとF、どちらでもよい」ので、たとえばここではともに「T」を指定することにしましょう。

テストケース12345
条件書籍であるTTTFF
1,500円以上であるTTFTT
離島でないTFTTF
動作送料無料無料300円400円500円1,000円

 このまま実装すると、こんな感じでしょうか。

 一方「離島でないか否か」の方から判定を始めると、以下のようになるでしょうか。

 どちらにせよ、上のデシジョンテーブルに基づくテストケースはすべてパスします。

 しかし・・・
 ここで2つ目のプログラムの12行目を誤って「4,000」としてしまったとします。この場合、上の5つのテストケースでは検出が漏れます。テストケースT-F-Fのケースが、圧縮によって省略されたためです。
 配送料を代入する式が6つあるのにテストケースは5つしかないので、漏れるケースがあるのはある意味当たり前ですね。

2. オールペア法: 有則の組み合わせに用いる!

 無則の組み合わせテスト技法である「直交表」や「オールペア法」を学ぶと、「パラメタが多い場合の組み合わせは、組み合わせテスト技法で大幅削減できるんだ!」というところだけを記憶してしまうリスクがあります。

 上のデシジョンテーブルの例では、3つの条件に対し組み合わせが8つもあるし、圧縮するには実装を意識しないといけないから大変だなあ・・・そうだ! オールペア法を使おう!と突き進んでしまうと失敗します。
 ためしに、3つの「条件」をパラメタと考えて、PictMasterで組み合わせてみましょう。

pictmaster

 PICTMasterに入力して・・・ポン!

品物は書籍合計は1,500円以上配送先は離島以外
TFT
TTF
FFF
FTT

 よーし、組み合わせ数が半分に減ったぞ・・・って、えーーー!
 一番肝心な、「送料無料」になるケースが出てこない・・・。

 無則の組み合わせテスト技法は、組み合わせるパラメタ同士が影響しない(ことになっている)場合に利用するものであり、強度2では、3パラメタ間の特定の組み合わせの出現を保証しません。影響し合うパラメタの組み合わせに用いてはいけないことが確認できましたね。

3. 状態遷移テスト: 2スイッチカバレッジ100%で1スイッチカバレッジも網羅!

 最後に、状態遷移テストのスイッチカバレッジにおける使い間違いを見てみましょう。「nスイッチカバレッジ」というのは、状態遷移をn回行う遷移パターンの網羅率のことです。

 たとえば以下のような状態遷移図を考えてみましょう。

stateMachine

 これを状態遷移表で表現すると、以下のようになります。

SABE
Sa
Abc
Bd
E

 この各セルの状態遷移をすべて実行すれば、1スイッチカバレッジが100%ということになります。
 2スイッチカバレッジであれば、状態S→状態A→状態B のような、2回の状態遷移パターンの網羅率を指すということです。

 さて、ここで気になるのは、nスイッチカバレッジが100%の場合、n-1以下のスイッチカバレッジは自動的に100%になるのか、という点です。
 無則の組み合わせテストでは、強度nのカバレッジが100%なら、強度n-1以下のカバレッジも100%になります。コードカバレッジでも、判定網羅が100%なら命令網羅も100%になります。

 『ドリル』では以下のように説明されています。

ここで、注意しなければならないのは、2スイッチカバレッジを行うだけでは、状態遷移表や1スイッチカバレッジのテストをしたことにはならない場合があるという点です。状態遷移がループしていない場合に、1スイッチはできても2スイッチできないケースがあるからです。

 試しに、2スイッチカバレッジのパターンを見てみましょう*1
 まず、関係行列は以下の通り。

 この行列を掛け算すると・・・。このような行列になります。 

 たとえば右上に「ac」が出ていますね。これは、状態Sから始まって、遷移aによって状態Aへ。さらに遷移cによって状態Eへ。という2スイッチのパターンとなります。この中には、1スイッチの遷移a~dも含まれており、2スイッチカバレッジ100%は、1スイッチカバレッジ100%も満たしているようです。

 さらに掛け算して、3スイッチカバレッジを見てみましょう*2

 3スイッチの遷移パターンは、たった34つになってしまいました。2スイッチであったパターン5個のうち、状態Sから始まる「ac」と、状態Bから始まる「5cdc」が消えてしまっています
 行列計算上、acも5cdcも掛け算対象が0になっているため、消えてしまうのです。状態遷移図で見ると自明で、Eから遷移する先はないので、S→A→E、B→A→Eで止まってしまうのですね*3

 このように、nスイッチカバレッジを100%にしたからといって、n-1以下のスイッチカバレッジが100%になるとは限らないということがわかりました。

まとめ

 いかがでしたか?
 テスト技法の使い方を間違うと、重大なテストケース漏れが起こることを実感いただけたでしょうか。
 みなさんもぜひ、テスト技法の誤った使い方について調べてみてくださいね!

*1:2スイッチカバレッジのパターンの導出方法は『ドリル』で詳しく説明されています。ざっくり言うと、状態遷移表を行列(これを「関係行列」といいます)とみなして、行列を掛け算することで求められます。

*2:A→B→A→Aのパターンが抜けていたので訂正。秋山さん、ありがとうございました!

*3:SとEが同一の状態であるとすれば、EからさらにAに入っていくことが可能です