見出し画像

第99回: 組み合わせテスト(基礎編)

≡ はじめに

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

前回は、ユースケース記述からテストを作る方法について書きました。今回は組み合わせテストの基礎について書きます。

ソフトウェアテストの現場をたくさんみてきましたが、組み合わせテストについては、
 1. 組み合わせテストをしていない
   ・ 単機能テストのみを実施している
   ・ 組合せがやばそうな箇所はデシジョンテーブルを作っている
   ・ 他の単機能を事前条件として実施後に、単機能テストをしている
 2. 職人技
   ・ 勘と経験で厳選した少数のパラメータと値を選び全組合せ
   ・ 厳選したパラメータを適当に組み合わせ
   ・ 根拠なく適当に作成した表
 3. 巨大マトリクス
   ・ 全てのパラメータ(見落としあり)と値の2元表のセルを適当に選択し、工数が尽きるまでテスト
 4. オールペア
   ・ PictMasterに仕様書にある全パラメータと値と制約を入力し、できた表を全件ひたすらテスト

が多いです。

1が7割、2が2割、3が1割くらいですが、(他の組織でも同じかと)安心しないでください。

アーキテクチャ設計とユニットテストの質が高ければ、組み合わせによる不具合はほとんど発生しません。また、前回のユースケーステストを十分に実施していれば、組み合わせによる不具合が発生したとしても業務が止まるということはありません。でも、この3つの前提、すなわち、

 ・ アーキテクチャ設計の質が高い
 ・ ユニットテストの質が高い
 ・ ユースケーステストを十分に実施している

の3点が揃っている組織は稀です。

むしろ、これらの前提が整っている組織の方が「それでも漏れるバグを見つけたい」と組み合わせテストを実施している印象です。

上記の3つの前提が揃っていなくても運が良ければ組み合わせによる不具合が発生しないこともあるでしょう。
また、高スキルを持つテストエンジニアが探索的テストを実施することで上手く行くプロジェクトもあると思います。
そのほかに、レジリエントな保守体制(不具合発生状況を監視し、発生時は短時間で対処する体制)を取ることができるなら、それもありです。
「組み合わせテスト」は品質保証の手段の一つですので、別の手段でカバーできるなら問題ありません。(発生した不具合について、その原因や対応コストの分析をしましょう

ただ、そもそも「品質の良いものを作りたい」というエンジニアとしてのプライドのようなものもありますよね? 矜持?
個人の趣味ではなく、ソフトウェア開発という仕事を請け負ったプロとしては、

  「評価コスト + 不具合対処コスト」の最小化

を狙った組み合わせテストをしたいものです。

私は、「その組合せは“想定外”でテストしていません」と謝罪するよりも「組み合わせても大丈夫な高品質な商品です」と太鼓判を押したいです。

ですから、私は、組み合わせテストをしっかりと行いたいです。組み合わせテスト技法に、技術的な魅力も感じますし。(まさか、有限射影幾何の知識が実生活に役立つ日が来るとは!)


≡ 組合せ爆発

画像1

こちらは、誰でも似たようなものを使ったことがあると思うのですが、「ダイヤル錠」と言います。0~9の10個の数字が書かれたリングが3つあり、000~999までの1,000通りの組合せのうちどれか一つだけが正解で、正解だと鍵が開くタイプのものです。

000~999までの数字を作れるので、1,000通りの組合せがあるというのは分かりやすいと思います。

分かりやすいと書きましたが、C言語を始めたころの私は、配列の添え字がゼロから始まるってことは、10個目のデータはなんだっけ??? って頭をひねっていたものです。アセ。

それでは問題です。次のダイヤルキーは何通りの組合せがありますか?

画像2

先ほどと、とてもよく似たダイヤル錠ですが、リングの数が4つです。したがって、0000~9999までの10,000通りの組合せです。

最初の3リングのダイヤル錠が429円だったのに対して、こちらの4リングのダイヤル錠は、609円とのことです。
どういう価格設定ロジックなんだろう??

どうやら、リングの数と、組合せの数は関係がありそうです。

リングの数 → 作れる数字 → 組合せの数
----------------------
1 → 0~9 → 10通り
2 → 00~99 → 100通り
3 → 000~999 → 1,000通り
4 → 0000~9999 → 10,000通り
5 → 00000~99999 → 100,000通り
・・・
10 → 0000000000~9999999999 → 100憶通り!

10のリングの数乗(リングの数がk個なら、10^k通り)ということです。

銀行の預金口座の暗証番号は4桁ですが、これも同じ考えで、“1万通りもあれば、万が一、カードを盗難されても、暗証番号が知られていなければお金を引き出すことはできない(だろう)”ということです。
暗証番号を3回間違えると、カードはATMに吸い込まれてしまいますので、全くの当てずっぽうでは、当たる確率は1/3333(= 0.03%)と低いものです。

宝くじで、1万円が当たる確率は1,000分の1だそうです。4桁の暗証番号を3回入力したときに偶然当たる確率はそれ以下です。暗証番号が4桁で実質破られないという感覚になりましたでしょうか?
ちなみに、私は宝くじは年に10枚買うかどうかなので、これまでの最高額は3,000円です。3千円が当たる確率は100分の1の確率だそうなので、ほぼ、期待値通りの結果です。
『年末ジャンボ、10億円、当たらないかなぁ』

別の例となりますが、計算に慣れるために、パスワードについて考えてみます。

PCのログイン時に使用しているパスワードが8桁でしたら、各桁に数字(0~9の10文字)とアルファベット(A~Zとa-zの合わせて52文字)の合わせて62文字もあるので、62^8=218,340,105,584,896(約218兆通り)となるので安心(だろう)と考えられます。

実際には、大文字と小文字を混在させる人は少なかったり、全組合せの218兆よりも英単語の数(100万強)、さらにいえば、ネイティブ・スピーカーの語彙数(約2万~3万5千語)の方がずっと少ないので、そういう隙を突いた攻撃をされるのですが。それは別の話です。

これで、“組合せの数は急激に増える”というイメージは伝わったかと思います。
え、まだピンときませんか??
そういう人は、「秀吉も降参した、曽呂利新左衛門への褒美」を読んでください。HAYST法の黄色い方の本で、にしさんも紹介されていました。

日本では、このように「米粒と畳」なのですが、海外(インド?)では「チェス盤と小麦」というのがあります。
基本的には曽呂利新左衛門と同じです。ところ変わればで、面白いですね。

なお、もっと爆発的に数が増える話として、YouTubeの「『フカシギの数え方』 おねえさんといっしょ! みんなで数えてみよう!」という動画がとても面白いので見てみてください。


≡ 組合せバグ

ソフトウェアのバグには「組み合わせたときにのみ現れる」ものが少なからず存在します。ゆえに、組合せを作ってテストする必要があり、その時に全てを組み合わせることは不可能なので、「組み合わせテスト技法」が誕生しました。

ところで、私は「組合せ」と「組み合わせ」を書き分けています。
「組合せ」は名詞で、「組み合わせ」は動詞の使い分けです。
例えば、「リングが3つのダイヤル錠は1,000通りの組合せ」とか、「数字とアルファベットを組み合わせてパスワードを作ります」といった具合です。
名詞と動詞を区別せずに「組み合わせ」と表記する人もいます。「組み合わせ」という送り仮名は内閣告示の本則で読みやすいですし、統一している方が引っかかりなく読めるかなとも思います。
テスト技法名は、JSTQBの“Combinatorial testing”の訳語に合わせ、「組み合わせテスト技法」としています。
詳しく知りたい人は、「送り仮名の付け方」(昭和48年6月18日内閣告示)あたりを読むと良いと思います。
JISのルールはもっとややこしいです。><。。

それと組み合わせテストの歴史については辰巳さんのページも参考にされてください。


≡ ソフトウェアテストと組合せ

以前デシジョンテーブルテストのところで、組合せの話を少し書きました。
条件を組み合わせると特別な結果になる規則がある場合、それを“有則”と呼び、“有則”の箇所に対しては、デシジョンテーブルテストをするという話です。
それでは、“無則”のときに、どんなテストをするかというと、それが、「組み合わせテスト」です。

テレビのリモコンを思い出してください。リモコンには、たくさんのボタンがあります。ボタンはテレビというシステムに対する入力です。
いくつかの例外はありますが、ほとんどのボタンは、他のボタンと独立した機能を動かすものです

例えば、数字の1が書かれたボタンを押せば、1チャンネルが映ります。音量の+ボタンを押せば音が大きくなります。このときに、NHKが表示されていてもTBSが表示されていても音は大きくなります。番組表ボタンを押せば、番組表が表示されます。
独立していない例は、「番組表ボタン」と「字幕表示ボタン」です。
[テレビを見ている状態]で、「番組表ボタン」と「字幕表示ボタン」、「番組表ボタン」を連続して押したときに、元の[テレビを見ている状態]に戻りますが、この画面で字幕は表示されていないテレビがほとんどと思います。機能独立なら「字幕を表示するモード」になりますが、字幕機能の組合せは、独立していないようです。

独立していて他と関係を持たないボタン(入力)同士の関係を“無則”と呼びます。

機能Aと機能Bが“無則”の関係にあるとき、“機能Aと機能Bは直交している”ともいいます。(直交とは、ベクトルが直角に交わるという意味です。このとき、内積は0になります。)

ところで、「直交」を「直行」と書く人が多いです。「外出先に直行する」という使い方や「生産の直行率」というように「直行」の方が多く使われるので仕方ありませんが、テストのプロの人が「直行表」と書いているのを見ると「もしもし、直交表ですよ」と指摘したくなります。

さて、テレビのリモコンのボタン同士の関係の多くが“無則”なのは特別なのでしょうか?

そんなことはありません。例えば、車について考えてみましょう。車はいつでも、窓の開閉ができますし、ヘッドライトを点けたり、ワイパーを動かすことも他の機能と独立してできます。

たまに、「速度がxxkm/h以下にならないとカーナビの操作ができない」とか、「ギアがバックに入っているときだけバックモニターが映る」といった“有則”の組合せもありますが、それらは少数派です。


≡ 組み合わせテストの考え方

画像3

こちらは、「ASTERセミナー標準テキスト」の132ページです。

スライドのタイトルは「【参考】バグに関係する要因数の割合」ですから参考情報です。こちらの論文は、出典情報をググれば、すぐに見つかります。4ページと短いものです。

どのようなことが書いてあるかというと、「複数のパラメータ(要因)を組み合わせたときに発生するバグについて分析したら、どうしてそうなるかの理屈は分からないけど、この表のように少ないパラメータ(バグ発生要因)の組合せがトリガーとなっていることが分かった」というものです。

2004年のこの論文の前に、田口玄一博士が、

1因子ずつの場合のバグの発見率がρなら(直交表を利用して2因子の組合せの評価をすれば)それに比較してほぼρの2乗に期待される。

と『ロバスト設計のための機能性評価』という本に書いています。こちらも、なぜ、2因子間のテストでバグの発見率が下がる(例えば、発見率が1週間(7日)に1回なら、その2乗で、49日に1回と下がる)のかについての言及(理屈)はありません。田口先生は現人神のようなカリスマでしたので、「田口先生が仰ったのならそれが正しい事」という雰囲気がありました。

実際の田口先生は、自説が間違っていると気が付いたら躊躇なく直すことが多い人でした。前回「XXXしなさい」と言ったことで、受講生がその通りやってきたとしても、その間にもっと良い方法が見つかったら、「それは良くない方法です」と指導される方でした。(田口先生は2012年にご逝去されました)

バグを「いくつの要因が重なって発生しているか」の切り口で分析すれば、良いだけなので、この論文の追試は色々な組織でされました。実は私も2度ほどやったことがあります。

1度目は、1997年のこと。会社のバグデータベースにたまっていたバグについて全部は大変なので直近1年分の分析しました。それは、全部で約8千件でした。(当時は1年間でソースコード200万行を作っていましたので、千行に4件のバグが登録されていました。ユニットテスト後の、統合テスト以降のバグしか登録していなかったのでそんなものでした。ちなみに、今はずっと少ないです)

そして、8000件のバグのほとんどは単機能バグでした。2つの要因の組合せで発生したバグが100件強あり、3つの要因で発生したバグが十数件、4つ以上はありませんでした。この時は、有則と無則の区別をしていませんでしたので、無則の要因の組合せに限って言えば、100件ではなくもっと少ないはずです。

この分析にかかった工数ですが、テスト自動化チームのリーダーが主業務で、その合間作業でしたので大体1日100件程度でした。トータルで3ヶ月以上かかりました。

もう一回は、論文に書いたもので、こちらのnoteで公開していますのでご興味があれば読んでみてください。17ページのところです。こちらは42件と少ないですが1つのシステムのリリース後のバグなので大変な問題でした。

経験上、少数の要因の組合せでバグになっていることが分かったので、テストも全組合せは不要で、「全ての要因から、任意の2つを取り出してペアを作ってテストすればよい」という考えがうまれ、そうしてテストすると市場でも問題が出ないので、「理屈は分からないけど、ま、いいか」となっているのが組み合わせテストの考え方です。割といい加減ですね。

このような論文と私の経験を根拠として説明しても「理屈がないと(お客様に説明できないので)困る」と仰る方も少なくありません。
「テストを減らす」ためには、"減らしてよい根拠"の説明が求められます。そして、根拠には、“経験よりも検証可能なロジック”が求めれます。
そういうときに私は「組合せ不具合が起こっているコードの実例」を見せて、説明しています。そうすると、4つ以上の無則の要因の組合せで偶然こういうコードになることはまず無いということを納得してもらえます。


≡ 終わりに

今回は、組み合わせテストの基礎についてでした。

「組合せの数は爆発的に増える」ことと、「全ての要因から、任意の2つを取り出してペアを作ってテストすればよい」ことについて腹落ちしてくださっていると良いのですが。

次回は「全ての要因から、任意の2つを取り出してペアを作る」方法の一つである直交表の話を書きます。

いいなと思ったら応援しよう!