はじめに
私(Zono。写真は本人。木刀はオフィスに落ちていたもの)の自己紹介(リンク)で書いたように、与えられた仕事をこなすだけでは、はるばるベトナムまで来た甲斐がないので、私の興味と会社の利益の両方を満たすこと、具体的にはソフトウェアテストに関する知識・ノウハウを皆様に共有する、という活動をしていこうと思う。本記事はその記念すべき第一弾で、のっけから小難しい話題で恐縮だが、決定表と組み合わせテストという二つのテスト技法を紹介したい。この記事であらゆることを知って頂く、というよりは、皆様がこの手法を学ぶキッカケになるよう、ポイントを絞ってお伝えする。静かな所で、気を落ち着けて読み進めて頂ければと思う。
決定表とは、テストにだけ使う技法というわけではなく、主に設計で用いられる仕様表現方法のひとつである。複数の条件が絡み合うような、複雑な仕様を整理し、共有する目的で用いられる。テストを設計するにあたり、そもそも仕様が正しく表現されていなければ正しいも何もないわけで、テスト設計をする人間が最初に身に着けるべきは決定表を含めた仕様の表現方法であろう。
そして組み合わせテストだが、こちらは名前の通りテスト技法にカテゴライズされる。名前からすると組み合わせを生み出す、というイメージで捉えがちだが、実は逆で、その技法自体は組み合わせを減らしていくためのものである(当然、組み合わせテストを知ることで、組み合わせを生み出す力が身につくという側面はある。また組み合わせテストを広く捉えるか狭く捉えるかによっても変わってくる)。
普段はバラバラに語られることの多い二つの技法だが、それでは記事として面白くない。今回は、二つの技法を一連のテスト設計の中で一度に活用する、というシナリオに沿って、その概要と学習することのメリットを説明していく。
決定表
デシジョンテーブル、日本語では決定表という。これは以下(図1)のような形をしている。
(図1)
この決定表は、入力文字列がパスワードポリシーに沿った形式か否かを判断する、という仕様を表現している。パスワード登録ボタンを押した際、パスワードポリシーに沿った形式であれば成功、そうでなければ失敗するという画面を想像してほしい。なお、今回で言うと大事なのは#8の列で、それ以外はある程度まとめて書いたりできるのだが、分かりやすさのため、あえて全ての組み合わせをそのまま載せている。
表の読み方を説明する。条件部(上半分)の各因子(変数のようなもの)がどの水準(変数に対する値のようなもの。必ずどれか一つに決まる)のとき、動作部(下半分)の各因子がどの水準になるか、が右半分の1~12の列に記載されている。今回は三水準の因子がひとつ、二水準の因子がふたつなので「3×2×2=12」の組み合わせが存在する。
さて、ゼロから表を作ろうとなった場合、まず最初に因子と水準を洗い出す必要がある。洗い出し方についても色々なフレームワークがあるが、ここでは必ず守って頂きたい原則を3つだけお伝えする。
①「因子は同時に二つ以上の水準をとらない」
②「因子は必ずいずれかの水準をとる」
③「因子同士は互いに独立して水準を決められる」
この因子、水準というやつは自由言語で表現される分、自由度が高く、慣れないとなかなかうまく決められない。例えば以下のようなルール違反を犯しがちだ。
①「因子は同時に二つ以上の水準をとらない」
②「因子は必ずいずれかの水準をとる」
「含む文字の種類」という因子に対して「数字」「アルファベット」という水準を設定すると、同時に二つの水準を取ったり、逆に一つも水準をとらないことがありうる。こうなると、後述するツールを使って組み合わせを生成したい、となった場合に不都合が出てくる。
③「因子同士は互いに独立して水準を決められる」
「文字数が5文字未満」を因子にして、水準を「満たす」「満たさない」とすると、同時に二つ以上の水準をとることはないので、一見問題なさそうだ。しかし「文字数が15文字以上」という因子も必要だな、となると、この二つの因子の両方が「満たす」という水準を取ることはなくなってしまう。このままでも表は作れるのだが、作業が複雑化するため、基本的にはルールを守って頂く方が良いだろう。
(図1 再掲)
話を元に戻そう。仕様書に上の表(図1)が載っているか、なければ文書を基に設計者にもヒアリングを行いつつ、先ほどご紹介したルールを守ったうえで決定表をまとめたら、さぁテストを設計していける……のだが、その前に改めて決定表自体に考慮漏れがないかをチェックした方が良い。例えば「記号は入っててもいいの?」「全角文字は入力できないようになってるよね?」「1文字を入れた場合と0文字を入れた場合の失敗は同じ扱いで大丈夫?」など。
今指摘した何点かは全て、「因子が漏れなく洗い出されているか」「水準の切り方は適切か」という二点に着目したものである。記号という因子は必要か、パスワード登録という因子に対する水準は成功、失敗の二つで良いか、といった具合。チェックすべきポイントが分かって頂けただろうか。
今回は「0文字でも1文字でも15文字でも同じく”失敗”としか出ない」「英数字と記号以外は入力できない」「ただし記号はパスワードに含めなければならない」として(図2)、話を次に進めていく。
(図2)
決定表が完成したら、まず、そのルール全てをテストすることを考える。今回は24通り。手でやる場合でも何とかなるだろう。しかしこれが240通りあったら?2400通りあったら?それだけあっても成功は今回と同じく1パターンのみで、その他は全て失敗なのだとしたら、そのすべてを頑張ってテストすべきだろうか?
組み合わせテスト
いくつかの因子に対して、互いにどの水準を選んで組み合わせても同じ結果になるグループがあるとする。先ほど紹介した決定表の、#16以外の列を思い浮かべると、どう組み合わせても結果は「失敗」になるはずだ。ここをターゲットとして、テストケース数を減らすことを考えたい。23通りはやりたくない、できない、としよう。
#16は成功するパターンなので除外するとして、残りじゃあ6通りくらいやっておくか・・・と以下(図3)のように#1、#5、#9、#13、#17、#21を選んだとする。これは削り方としてマズイのだが、何がマズイか指摘できるだろうか。
(図3)
例えば数字と記号がどちらも「含まない」のパターンしか含まれていないので、偏りがありそうだ。
そこで、すべての水準が一度以上は登場するように選んでみよう。
(図4)
これ(図4)だとどうだろう?先ほどよりはマシだが、実はまだ少し怖い(怖いが、このように作成されたテストケースは世の中に山ほどあるだろう。私も作ったことがある)。本件では例えば判定ロジックにバグがあり、そもそも文字数と記号の有無しか見ていなかった!と言われた際、そのバグが発見できないことになる。
(図5 赤く示した箇所にバグがあり、#10、#12、#14が失敗ではなく成功してしまう)
では全パターンやればいいか?というと、いや23通りもやりたくない、と最初の話に戻ってしまう。何とかうまくケース数を削減できないものだろうか。
先述したバグ「文字数と記号の組み合わせだけでパスワード登録の成功・失敗が決まってしまう」を少し科学的に表現しよう。このバグは二つの因子「文字数」「記号」の特定の水準の組み合わせによって発生すると考えることができる(注)。つまり、ほかの因子は何でもよい。実はソフトウェアに潜むバグというのは、ありとあらゆる因子が特定の条件を満たしたときに発生するものよりも、ごく少数の因子の組み合わせによって発生するものの方が、バグ全体に占める割合は大きい。
つまり、そういうものから狙っていきましょう、ということだ。その方が効率的に、すなわち少ないテストケース数で、多くのバグを見つけられるはずである。
(注)厳密には「文字数が5文字以上15文字未満」+「記号を含む」を満たした上で、「アルファベットを含まない」または「数字を含まない」を満たす必要があるが、今回の入力空間からは#16を除いているため、先述の二因子が条件を満たせばよい。
狙い方については簡単に述べるに留めるが、ペアワイズテストや直行表、という言葉を聞いたことがあるかもしれない。これらは「任意の二因子について、すべての組み合わせが網羅される」という条件を満たすようにテストケースを作成するためのテクニックである。もう少し砕いて言うと、「どの二因子を選んでも、その二因子にだけ着目すると全ての水準の組み合わせが網羅されている」ようなテストケースをツールや表を使って作成するのである。先ほどの例で言えば、「文字数」と「記号」という二因子に着目したときに、すべての組み合わせが網羅されているのであれば、「文字数が5文字以上15文字未満で、記号を含む入力を行った場合にのみ発生するバグ」を取り逃すことはない。
PICTというツールを使って、ペアワイズテストを生成した結果が以下(図6)。ばっちり、今回のバグを発見できていることが分かる。しかも、ケース数は6のまま、増えていない。科学的アプローチによる効率的なテスト設計が行えた、と格好いいことを言っても間違いはないだろう。
(図6)
先ほどの「任意の二因子~」の部分は、3でも4でも構わないし、その方が複雑な発生条件のバグを見つけられる。当然、数字を増やせばケース数が増えるので、どこまでやるかは工数とのトレードオフとなる。PICTも引数に3や4と入れてあげれば、「任意の三因子」や「任意の四因子」に対してすべての組み合わせを網羅するテストケースを生成してくれる。この基準を Combinatorial Coverage と呼び、日本ではN因子間網羅(N=2なら二因子間網羅)、というと通じるはずだ。
まとめ
今回のテストを報告書に簡単にまとめるとすると、こんな感じになるだろう。
・仕様から決定表を作成した。因子は四つ、ルール数は24。
・パスワード登録が成功する1パターンをテストした。
・パスワード登録が成功する1パターンを除いた23パターンについては、工数と期間の関係で全ては実施せず、ペアワイズカバレッジ(二因子間網羅)を満たす6パターンに対してテストを行った。
どうだろう、「テスト設計をしました。24ケースはできないので、7ケース選んで実施しました」よりも、説得力があり、次のテストも任せられる感じがしないだろうか。レビューも突破できそうだ。
テストというのは、本来なら無限の時間を使って全てのパターンをテストするのが一番良いのであって、それを現実的な工数の中で終わらせるためには何らかの妥協が必要となる。そんなことは耳にタコで、ではどう妥協すればいいんだ、というところが悩みどころだと思う。そこで、その妥協に説得力を持たせるためのツールとして組み合わせテストというのが使えますよ、という話をさせて頂いた。少し不純だが、私はそれで良いと思う。テスト技法が直接自分に利益をもたらす便利なものだと思えれば、それが学びのモチベーションとしては一番良い。「品質を上げるための手法なので覚えましょう、使いこなしましょう」と言われても気が乗らないだろうし、研修だったら眠気に襲われることだろう。
今回紹介したもののほかにも、テスト技法はたくさんある。それぞれの使い方を学ぶのはもちろん大切だが、それを使うことで自分の目の前の仕事がどう上手く運ぶようになるのか、という具体的なところにまで想像を働かせてみて欲しい。すると、学びがだんだん敵を倒すための武器集めに思えてくる。素手よりも武器があった方がボス戦は楽だ。ただしいつも同じ武器だと相性の問題が出てくる。だからいろんな武器を集めておこう……。こんな風に、学びを楽しめるようになれれば、今後のあなたの戦いがずいぶんと楽になることと思う。