見出し画像

93号:デシジョンテーブル(前編)

≡ はじめに

ASTERセミナー標準テキスト」の102ページについてです。

前回は、境界値分析(後編)として、「3ポイント境界値分析」の話を中心に書きました。今回はデシジョンテーブルテストの基礎について書きたいと思います。なおJSTQBでは、デシジョンテーブルを用いたテストをデシジョンテーブルテストと呼びます。

似た名称で、「デシジョンテスト」がありますので、JSTQBの試験を受けられる方はご注意ください。
デシジョンテストは、「ホワイトボックステスト技法の一つ。判定を実行するテストケースを設計する。」(ISTQB用語集より)です。
制御フローテストで、デシジョンカバレッジ基準(いわゆるC1基準)で処理の流れを網羅するテストがデシジョンテストです。
デシジョンテーブルテストの方は、ソフトウェアの論理をルール(条件の組合せに応じた動作の規則)ごとに評価するブラックボックステスト技法のひとつです。

デシジョンテーブルは英語で“decision table”と書きます。簡単に言えば、「ソフトウェアが持つ(複雑な)論理判定を正確に表現した表」のことです。論理とは“if”とか“and”とか“or”のことです。日本語では「決定表」と呼びます。

“decision table”は、“-sion”なので、“ジョン” /ʒən/と発音します。televisionがテレビジョンであるのと同じです。
一方、“action”や“station”は、“-tion”なので、“ション” /ʃən/と濁らず発音(清音)します。
日本語では、“ジョン”とか“ション”と強く発音しますが、/ʒən/や/ʃən/です。
「ə」、すなわち、曖昧母音ですから、正しい発音をされると、弱く軽い「エ」のような音で、私にはほとんど聞き取れません。
“station”の発音記号は、「stéɪʃən」です。聞いたそのものをカタカナで書くなら「スティシ」くらいのイメージで最後に「ン」があるかな? って程度です。、、、テストの話じゃなくてすみません。
それから(まだ続けるか! 笑)、たまに、discussionのように“-sion”なのに、“ジョン”とは濁らずに“ション”と発音する単語もあります(少数派です)。この仲間はdiscussionの他に、extension、expressionあたりを押さえておけばいいかな、思いつく範囲では。そのうち、考えなくても自然に発音できるようになる日が来ると英語の先生が言っていました。(私には、その日はやってこない気がします)
ところで、“decision table”の“decision”は、 “decide”(決定する)という動詞を名詞化した単語です。-sionや-tionという接尾辞には、動詞を抽象名詞化する効果があります。(なお、単語数としては、-tionの方が圧倒的に多いです)

英語のうんちくは忘れていただいてよいのですが、“decision table”を日本語で「決定表」と呼ぶ(大昔は「判定表」とも言いましたが、今の主流は決定表と呼ぶ)ことは覚えておいて損はありません。JISでもJIS X 0125:1986 決定表として規格化しているからです。そしてJISは「JIS検索」のサイトから、無料で閲覧できます(閲覧できるのは、検索元のアドレスが日本限定ですので、例えば、海外出張中に現地のプロバイダーに接続していたら読めません)。

ということで、決定表の用語やフォーマットについては、「JIS X 0125:1986 決定表」を参照してください。私は、
 ・ 条件の指定はY/N
 ・ 動作の指定はX
 ・ 「条件と動作のセット=列」のことをルール(規則)と呼ぶ
の3つだけ覚えています。

本当は、3つだけでなくもう少し覚えているのですが、使うようにしているのは上記の3つです。
例えば、記入漏れがないことを明確にするため、JIS X 0125では空白のセルは許されていません。空白のセルは必ず、「-」で埋める(検討した記録を表に残す)のがルールです。
でも、かえって見づらくなるので、私は空欄を基本とし、YとNどちらでも良いときにのみ「-」を使っています。実務では、正しく規格に則って書くことが目的ではありませんから。
なお、規格では、「3.2 条件指定」のところで、「Y及びNについては、別の2値表現を用いてもよい」と書いてあります。したがってY/Nの代わりに、T/Fや真/偽、なんなら○/×を使用しても構いません。色を変えて区別してもよいです。
ただし、T/Fや真/偽よりもY/Nの方がパッと見、識別しやすいので、私はY/Nを使うことが多いです。例外として、原因結果グラフから作ったデシジョンテーブルには真と偽しか現れないので、T/Fの方がしっくりきます。(あくまでも個人の感想です)

以降は、デシジョンテーブルを使う上の基本について説明します。
※ 松尾谷徹さんが書かれた「ソフトウェア論理の設計/検証における決定表の応用」を参考に書いた個所が多いので併読ください。(といいますか、松尾谷さんのデシジョンテーブルの解説だけ読めばよいといううわさも……)


≡ デシジョンテーブルの歴史と用途

ソフトウェアの設計にデシジョンテーブルが使われ出したのは、1958-59年だそうです。そして、1960年から、デシジョンテーブルからソースコードを自動生成する試みが行われています。

※ 上記について「1960年代」を「1958-59年」に、「1970年代になりますと」を「1960年から」へ、それぞれ書き直しました。辰巳さん、ありがとうございました。

自動生成するためにはデシジョンテーブルの表記方法を決める必要があります。そこで、1984年にISO 5806 Specification of single-hit decision tableが制定されました。翌年の1985年には、日本語に翻訳され、JIS X 0125決定表として発行されました。(JIS X 0125の最初の方に対応国際規格としてISO 5806と書いてあるのはそのためです)
この規格は、ISO 5806のタイトルから分かる通り、単適合決定表(single-hit decision table)と呼ばれる強い制約を持ったデシジョンテーブルを取り扱っています。次の節で紹介する(応用範囲の広い)多重適合決定表(multiple-hit decision table)についての規格化は行われていません(2020年時点の話ですが、今後も行われないと思います)。

ところで、セミナー等でデシジョンテーブルについて説明すると受講者から「デシジョンテーブルは、設計の手法ですよね? 開発者が作ってテストエンジニアはそれを使ってテストケースを作るほうが良いですか?」というご質問をよく受けます。(2~3回に1回くらい受けます)

近頃は、「デシジョンテーブルは、設計にもテストにもリリース後の障害切り分け時にも役に立ちます。ですから、デシジョンテーブルを作るスキルを持った関係者が集まって一緒に作るのが良いです」と曖昧な答えをしています。(設計の手法かどうかに答えていませんし、テストエンジニアが作ることの是非についても答えていません)

曖昧な答えとなっているのは、開発者が作るデシジョンテーブルには通常は、“補集合”についての条件は書かれないからです。テストエンジニアはテスト用にデシジョンテーブルを書き換えるか、テストケースを作る時にその配慮をする必要があります。

でもデシジョンテーブルを習いたての人にそういう細かい話をしても混乱するか、面倒で難しそうだから使うの止めようと敬遠されてしまうと思うから。

“補集合”についての補足です。
例えば、性別について、開発者が作るデシジョンテーブルには、普通は、「男性」と「女性」しか書かれません。
ところが、テスト用のデシジョンテーブルには、「男性」と「女性」に加え、「それ以外」(=補集合)の条件を書きます。
“補集合”という意図しない条件の時にどうなるかのテストも必要だからです。
例えば、性別不明な人が割引券を持ってきたときに、テスターとしては、割引券分割り引くか、それとも、性別チェックでエラーとなって終わるか、それとも、有利な性別(例えば女性割引があるなら女性)とみなすか、といったソフトウェアの振る舞いが気になるからです。
※ 要求仕様書にも“補集合”についての記載は、ないことが多いものです。


≡ デシジョン(decision)とコンディション(condition)

デシジョンテーブルの中身に入る前に、知っておく必要がある用語があります。それは、見出しに書いた「デシジョン(decision)とコンディション(condition)」です。

次々回の状態遷移テストの話では、さらに状態(state)とモード(mode)も出てきますが、今回はデシジョン(decision)とコンディション(condition)の違いを理解してください。
「なんとなくわかっているけど、『違いを教えてください』と質問されるとちょっと答えにくい」、そんな似た用語だと思います。

デシジョン(decision)は、「決定」とか「判定」と訳されます。上のほうに、「decide(決定する)」の名詞形と書いた通りです。

コンディション(condition)の方は、そのまま「コンディション」で通じます。スポーツ選手に「コンディションはどう?」って聞いたらそれは、体調の仕上がり、についての質問です。

中畑清なら「絶好調」と答えます。(笑)

conditionは、「-tion」で終わっていますが、動詞を名詞化したものではありません。私の辞書には「con(共に)+dition(話すこと)」とありましたが、他にも、「con(共に)+dicere(話す)」などいくつかの説があるようです。
とはいえ、細かな違いに目をつぶれば、「話し合って合意した条件」というような契約条件のような、ちょっと固い言葉のようです。requirementが近いそうです。(環境)状態とも訳されることがありますが、自然の状態ではなく、労働条件といったそういった意味で使われます。

テストエンジニアとして知っておく必要があるのは、例えば、

if ((a > 3) & (b < 4)) { xxx } else { yyy }

 といった(疑似)コードがあったときに、「a > 3」と「b < 4」を条件(condition)と言って、(if文で)分岐するために、真・偽を明らかにすることを判定(decision)と呼ぶということです。これは、ホワイトボックステスト技法のところで説明する制御フローテストの網羅基準でも出てきますので覚えておいてください。


≡ 単適合決定表と多重適合決定表

既述した通り、デシジョンテーブルには、単適合決定表(single-hit decision table)と多重適合決定表(multiple-hit decision table)の2種類があります。ただし、ソフトウェアテスト関係の書籍やソフトウェアテストのシンポジウム等の発表で見かけるデシジョンテーブルは、単適合決定表のみと考えていただいて、9割9分構いません。ソフトウェアテストでは、単適合決定表しか使わないからです。(その全ての列をテストするという意味では、多重適合決定表のような使い方ですが……)
なお、開発者も今はもう、多重適合決定表を書く人はほとんどいないように思います。少なくとも私は見たことがありません。組み合わせたときに特別な振る舞いがあまり多く発生しない要求を素直に表現するには、多重適合決定表の方がコンパクトに書けるので適していると思うのですが。

「そんなマイナーな技術なら、多重適合決定表は無視したい」という人がいらっしゃるかもしれません。
はい。知らなくても問題ありませんので、次の見出し「≡」まで、読み飛ばしてください。

以下を読む前に、キャッチイメージをざっと読んでデシジョンテーブルがどんな表なのか把握してください。この先の記載で、分からないところが出たらキャッチイメージを見直すとわかると思います。
簡単には、

デシジョンテーブルは、着目しているルール(列)の条件が成立したら動く動作の行に「X」を書き、そのルール列にある条件の組合せが満たされた時に、Xが付いた動作を実行すると読みます。

と覚えておけばOKです。

上の定義で「動作を実行する」が気になる人がいらっしゃるかもしれません。「条件に対する結果」では? と。
歴史のところに「1960年から、デシジョンテーブルからソースコードを自動生成する試みが行われています」と書いてあったことを思い出してください。実行する動作(サブルーチン)に「X」マークがついているイメージで捉えてください。
任意のルールにおける条件行と条件行の関係は、どのデシジョンテーブルも「AND」です。これは、例えばキャッチイメージの左側のデシジョンテーブルのルール2なら、
 if((A<B+C == Y) AND (B<A+C == N))
   {三角形ではない}
という意味のANDです。
※ 「-」はY/Nどちらでも良いという意味で、DC(Don't Care)と書く人もいます。
※ 私は表が読みにくくなりますので上述のように最小限の「-」にしています。最小限を意識はしていないので気分的につけたり、つけなかったりと言うのが正直なところです。


■ 単適合決定表と多重適合決定表の違い

ルール(列)の1番から順に条件の組合せがマッチするかチェックして行き、最初に成立(ヒット)したルールに対応する動作のみを実行し、表のその後のルールはチェックせずに打ち切る読み方をするデシジョンテーブルを単適合決定表と呼びます。
一方、適合した列でチェックを打ち切らずに、最後までルールをチェックし条件とマッチしたルールに対応する動作をすべて実行するデシジョンテーブルを多重適合決定表と呼びます。

日本語よりも、単適合決定表(single-hit decision table)と多重適合決定表(multiple-hit decision table)の英語の「single-hitとmultiple-hit」の方が分かりやすいような気がします。

単適合か多重適合かの区別は、デシジョンテーブルを見ただけでは分かりません。設計段階で区別して書き、その違いをコーディングに反映する使い方です。デシジョンテーブルからテストケースを作るときには、常に多重適合決定表として取り扱い、全てのルールのテストケースを作ります。

ところで、松尾谷さんも書かれているのですが、私も、「プログラマーが、単適合と多重適合の使いどころを正しく理解しているか」については疑問があります。
近頃の設計教育では、「ソフトウェアは、オブジェクトに分解することで、複雑な論理を消す」と教えているからです。
それは、正しい設計教育と思うのですが、実装されたものには、複雑な論理を取り扱う機能があるわけですから、テストでは複雑な論理をテストしなければなりません

以上のことから、テストエンジニアがデシジョンテーブルを書く(実際には、原因結果グラフやCFD法を使いこなす)必要が生じているのですが、そのスキルを十分に身につけているテストエンジニアの数が足りないため、テスト漏れが生じている懸念があります。(みんなで、原因結果グラフやCFD法を学ぼう!)


■ 単適合決定表

単適合決定表は、どれか一つのルールが選ばれるタイプの、みなさんが見慣れたデシジョンテーブルです。
疑似的なソースコードでいえば、

if (条件1) {
動作1
}
else if (条件2) {動作2}
else if (条件3) {動作3}
else if (条件4) {動作4}
・・・・・
else{補完動作}

のように条件が「else if(条件)」でつながれ、マッチしたどれか一つの条件の{動作}だけを実行する制御構造です。
最後の行の「補完動作」は、規格では、補完規則(ELSE-rule)といいます。
普通は、実施可能な全ての組合せをデシジョンテーブルに書きますから、補完動作は書く必要がありません。

補完動作は書き落とした条件の組合せに対して実行すべき動作となります。
デシジョンテーブルでの表記方法としては、単適合決定表の一番右の列に条件のセルをまとめて「ELSE」と書いておくことが多いですが、表記方法について規格には書いてありません。
繰り返しになりますが、補完規則は、それが不要な場合は書かなくてよいものです。


■ 多重適合決定表

多重適合決定表は、全てのルールを1から順にチェックし、マッチした場合、その動作を行うデシジョンテーブルです。
疑似的なソースコードでいえば、

if (条件1) {
動作1
}
if (条件2) {動作2}
if (条件3) {動作3}
if (条件4) {動作4}
{補完動作}

のように「if(条件)」が続き、マッチした条件の{動作}が全て実行される制御構造です。
最後の行の「補完動作」には、常に実行するものを書きます。


≡ 有則、無則、禁則

テストは、仕様書に書いてある条件(条件の組合せを含む)での動作確認だけでは足りません。
仕様書に書かれていない条件についてもテストする必要があります。上記の“補集合”もその一つです。

テストにおいて、“補集合”は大切な概念なのでもう少し説明します。
例えば、「65歳以上と学生に対して割引価格で入館可能」という仕様(美術館などにありそうな仕様です)があったときに、開発者は、65歳以上{Yes,No}、学生{Yes,No}という条件の組合せを考えて、
  65歳以上・学生{Y・Y⇒割引,Y・N⇒割引,N・Y⇒割引,N・N⇒通常料金}
のようなルールと考えて、デシジョンテーブルに整理して設計します。

ところが、テストでは、補集合について、詳しく考えます。
全体である「人」は、「65歳以上の学生,65歳以上(で学生では無い人),(65歳未満の)学生,その他}に同値分割できるはずです。“N・N”と“その他”は同じものとも言えますが、テストではこれを“補集合”と考えて、もう少し、詳しく分析します。
※ ベン図を描くと分かりやすいかもしれません。

テストのデシジョンテーブルには、「その他の人」という条件行としておき、テストケースを作る時に、その他の人の具体化を行います。例えば、「幼児」や「年齢確認ができない人」などです。「幼児」に対しては、無料にするという仕様が漏れているかもしれませんし、「年齢確認ができない人」に対しては、(見た目が65歳以上の可能性があれば)生年月日と干支が合っていることをもって年齢確認の代替とするという仕様が隠れているかもしれません。

“補集合”に加えて、有則と無則と禁則の理解が必要です。

有則と無則のテストにおける概念については、2008年2月15日に発行された、情報処理 49(2)の松尾谷徹氏の論文に書かれたのが始まりと思います。そこでは、

有則: 仕様で定義された条件とそれに対応する動作の集合
無則: 仕様では定義されていないが入力可能な条件とその条件における動作の集合。有則の補集合に相当する

とされています。
デシジョンテーブルテストでは、有則の組合せについてテストしますが、条件については“補集合”まで考えます。補集合まで考えるとY/Nの2値で足りなくなることがありますので、JISと違った形式のデシジョンテーブルを使用することがありますが、それについては次回書こうと思います。
無則の組合せについては、組合せテストで網羅的に無害であることのテストをします。

整理すると
 ・デシジョンテーブルテスト
   条件: 有則と無則
   条件の組合せ: 有則
 ・組合せテスト
   条件: 有則と無則
   条件の組合せ: 無則を中心とする
となります。

なお、有則の組合せテストでは、組合せがあり得ない制約条件(例えば、AとBとCはどれか一つしか選択できないなど)によって、全ての組合せからテスト可能な組合せに絞り込みます。
ついでにいうと、無則の場合は、“禁則”という仕様を作り、意図的に組合せることができないようにします。“無則”と“禁則”の組合せについては、『組み合わせテスト』のところで詳しく説明します。
※ 制約と禁則を同じ意味と考えている人もいます。私は使い分けています。


≡ 拡張指定

条件にY/Nではなく拡張指定を用いることがあります。例えば、学生の区分に対して、小学生{Yes,No}、中学生{Yes,No}、高校生{Yes,No}、大学生{Yes,No}として、デシジョンテーブルの4行を使って作っても良いですが、学生{小学生,中学生,高校生,大学生}として、1行にして、セルの中にY/Nではなく、小学生、中学生、高校生、大学生を書くこともできます。これを拡張指定と呼びます。
拡張指定を行うときには、排他ではない多値にならないように気をつける必要があります。

≪排他ではない多値とは≫
例えば、年齢{20歳未満,20歳~65歳未満,65歳以上,80歳以上}と拡張指定で作った場合、作った人の意図として、65歳以上は「65歳~79歳」だったとしても、そのまま素直に解釈すれば、90歳は、“65歳以上”と“80歳以上”の両方にあてはまります。つまり、年齢条件の要素は、排他になっていません。
Y/NやT/Fや○/×はそもそも排他なので、このような問題は表の中では起こりませんが、拡張指定ではうっかりしやすいので注意して作ります。


≡ 終わりに

今回は、デシジョンテーブルの基礎についてでした。
基礎に違いないと思うのですが、松尾谷さんが書かれた通り「伝承が途絶え衰退傾向にある」技術ですので、“初耳だったよ”という人もいらっしゃったかもしれません。

でも、難しいことは何もない話ですし、知っていた方が応用が利くようになると思って書きました。

次回は今回の基礎を踏まえた実践編ということで、「デシジョンテーブルの簡単化」と「デシジョンテーブルのルールとテストケースの関係」と「デシジョンテーブル2つの形式」の3つについて書きたいと思います。

この記事が気に入ったらサポートをしてみませんか?