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

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

原因結果グラフと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にある演習問題にチャレンジすることができる気がします。