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

ソフトウェアの品質、ソフトウェアテストなどについて学んだことを記録するブログです。

原因結果グラフとCEGTestに関する考察 - その4

 その3に続き、鬼門の順序系制約・MASKについて((当初「第3回ソフトウェアテスト技法ドリル勉強会」という記事タイトルでしたが、どんどん内容が離れていくので改名いたしました。。。。

「順序系」制約その2:MASK

あるノードが真になると、Mask制約で指定された2つ目以降のノードは真偽が確認できない
というもの。スケジュール管理アプリケーションの予定入力において「終日」にチェックを入れると、開始と終了の時刻を入力するテキストボックスが消える(=MASKされる)という例が示されています。
 これをヒントに、MASKを使えそうな、簡単な例を考えてみました。

ラジオボタンAでは「はい」「いいえ」のどちらかを選ぶ。デフォルトは選択なし。ラジオボタンAで「いいえ」を選んだときのみ、テキストボックスBが活性になり、文字列を入力することができる。
Aは入力必須。Bも、活性のときは入力必須。
「登録」ボタン押下時に、この入力必須の条件が満たされているかを判定する。

4-1

REQで攻める

 まず、ジョージ1世のように、逆から考えます。「Effectから始めてもいいさ」と考えるんだ。Effectは「入力OK」とします。これが真になるには、「A入力」が真 かつ 「B入力」が真。
 「A入力」が真になるには、Aが「はい」か「いいえ」のどちらかが真。デフォルトが選択なしのラジオボタンであることから、この2つにはEXCL制約をかけます。
 また、「B入力」の真偽の判定には、Aが「いいえ」であることが先立つので、REQ制約をかけます。
 この結果、CEGは以下のようになります。
4-2
 カバレッジ表は以下です。
4-3

  論理式1~3は、「A入力」のOR条件に関する真偽パターン。

 論理式4~6は、「入力OK」のAND条件に関する真偽パターン。ただし論理式4・5では「B入力」が真のため、REQ制約が働いて「A:いいえ」が「T」になっています。なおかつ、「A:いいえ」が真で「A入力」が偽というのは矛盾する(論理式2にも反する)ので、グレー。
 デシジョンテーブルを見てみましょう。
4-4
 #2はいいでしょう。
 #3は、カバレッジ表を見ると該当真偽パターンが論理式3だけであり、論理式3で空欄になっている「B入力」と「入力OK」は、「A入力」が偽であることから自動的に偽(デシジョンテーブルでは「f」)になっています。
 #1はどうでしょう。Aで「はい」を選択、Bに入力がなかった場合、「入力OK」は偽になる。何か妙です。Aが「はい」になった時点で、Bは入力の有無がそもそも埒外になっているのだから、「入力がなかった場合」が出てくるのがおかしい

MASKで攻める

 ここで使うのは、REQではなく、MASKなのか?
 では、MASK制約をかけてみます。
4-5
 「A:いいえ」が真でなければ、「B入力」がマスクされます((「A:いいえ」のノードではなく、MASKのノードを2回クリックすることで、NOTにできます。なかなか気付かなかった・・・。
 カバレッジ表は以下です。
4-6

  論理式4~6はやはり、「入力OK」のAND条件に関する真偽パターン。論理式1~3もやはり、「A入力」のOR条件に関する真偽パターンですが、「A:いいえ」が偽になる論理式2・3では、「B入力」が「M」、つまりマスクされています

 デシジョンテーブルは以下。

4-7

 #1と#5は、きれいな形ですね。#3と#4では、カバレッジ表に該当する論理式がない部分を「f」で埋めています。#4であれば、「A入力」が偽なので、「A:はい」「A:いいえ」は必然的に偽。
 #2はどうでしょう。「入力OK」に「I」が出てきています。Iとは?CEGTestのヘルプを参照してみましょう。
 原因側のノードが真偽不明のため真偽が決定できない
 つまり、テストケースとして、「Aで『はい』を選択して、非活性のBについては何もできずに『登録』ボタン押下」するケースは、入力チェックOKなのかNGなのか、判定できないということになってしまいました。
 何か、間違っています。

REQもMASKもいったん忘れる

 心機一転、大元から考えなおしてみます。
 まず、「入力OK」が、「A入力」が真 かつ 「B入力」が真、という論理。Aが「はい」であれば、Bに入力しなくても「入力OK」なのだから、局所的にはこの論理が間違っていることに気づきます。その間違いをREQあるいはMASKで補正するものだと思っていたのですが、この2つの制約についてはいったん忘れ、局所的にも正しい、もっと愚直な論理に直してみます。それは、
「A入力」が真 かつ 「「A:いいえ」が真のとき「B入力」が真」が真 のとき 「入力OK」が真
です。。。ややこしすぎ。
 この「「A:いいえ」が真のとき「B入力」が真」を中間ノードにして、「A:いいえ」と「B入力」にバラしましょう。論理式X⇒Yは、¬X∨Yと同値なので、「A:いいえ」と、「B入力」の否定 の論理和で、「A:NO⇒B入力」と接続しました。その結果、CEGとデシジョンテーブルは以下の通り。
4-8

4-9

 おお!すべて妥当な内容になっています。
#1:Aが「はい」でそのまま入力OKになる
#2:Aが「いいえ」でBにも入力があり、入力OKになる
#3:Aで選択されていないので、そのまま入力NGになる
#4:Aが「いええ」だがBには入力がなく、入力NGになる
 しかし、さっきと同じ問題が。Aが「はい」になった時点で、「B入力」は真にも偽にもならないはず・・・。そう、ここでようやく、MASKを使うことにします。

4-10
4-11

 これが最終型ですね。「A:いいえ」が偽になるパターンすべてで、「B入力」の値は「M」になりました。それ以外の真偽パターンは一切変化しておらず、よさげです。

考察

 試行錯誤の末の、とりあえずの結論は、「MASKは最後に付与する」ということ。
 『ドリル』では、MASKは順序系の制約に分類されていますが、今回の結果だけを見るとむしろ、テストケースに情報を補足するような役割をもつように思えます。CEGTestでは各ノードに「観測可能」というオプションがありますが、それと近いような・・・。このオプション自体まともに使ったことがないので、何とも言えませんが。
 それにしても、入力項目がたった2つのこんなシンプルな問題に対して、CEGがこんなに複雑になるのは、妥当なのか。もっとサワヤカな解があるのかも知れません。
 とはいえ、ようやくひと通り、制約についても試行することができました。ここにきてようやく、加瀬さんのblogにある演習問題にチャレンジすることができる気がします。