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

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

テストを進めることで品質に何が起きているのか(思考実験)

 この「ソフトウェアテスト Advent Calendar 2019」*1の、-34日目のエントリーです。
 単なる思い付きの思考実験ですが、アイデアいただけると嬉しいです。

テスト実行と品質をどのように描くか

 ソフトウェアテストを、「対象とするソフトウェアの品質レベルを推定し、不確実性を小さくしていく活動」と捉えてみます。
 テストを始める前は、どの程度の品質なのかについての手がかりがなく、「0から100のいずれかの範囲にある」*2ということしかわかりません。平均値である「50」が、「この辺かなあ」と思える品質ですが、不確実性が大きすぎてあまり意味がありません。

f:id:kz_suzuki:20191027064729p:plain

 テストケースが1つパスすると、下限が上昇します。これは2つのことを意味しています。

f:id:kz_suzuki:20191027064732p:plain

  1. 「品質についての不確実性が減った」ということ。
  2. 「一番確からしい品質のレベルが上がった」ということ。

 上の図では、1個のテストケースがpassすると、下限が5だけ上がっています。すると、実行前には0から100までのどこかだろうと考えていた品質の範囲が、5から100までのどこかだと絞られたことになります。これがa.です。
 またそれに伴い、平均は50から52.5に上がっており、期待していい品質が上がったことになります。これがb.です。

 逆にテストが1つfailすると、上限が下降します。

★図3f:id:kz_suzuki:20191027064704p:plain

 これも2つのことを意味しています。

  1. 「品質についての不確実性が減った」ということ。
  2. 「一番確からしい品質のレベルが下がった」ということ。

 このモデルのポイントは、次の2点です。

  1. 結果がpassであればfailであれ、テストを進めれば不確実性は減る
  2. テストを進めることで上がるのは「品質」それ自体ではなく、「期待できる品質」である。

 テストをすればするほど品質に対する確信度合いが深まっていくというのは、まあ直観に合うでしょう。また、テスト自体が品質を上げてくれるわけではないという事実も、モデルに反映されています。

モデルはどのような性質を持つべきか

 さて、このモデルはあまりに単純です。
 まず、最初のテストケース実行により下限を押し上げた「5」とは何なのでしょうか。この属性に仮に、「テストケースの重み」という名前を付けてみましょう。「重み」はいくつかの特徴を持ちます。

(1)テストケースによって重みが異なる

 いわゆる「ど真ん中」「ハッピーパス」「正常系」と呼ばれるような、テストの最初にとりあえずやってみるようなテストケース。このようなテストケースがfailすれば、上限は大きく下がるでしょう。一方、非常にレアな、あるいは極端な条件でのテストケースがfailしても、上限はそれほど下げなくてもいいでしょう。
 このように、テストケースごとに相対的な重みは異なると考えられます。

(2)passしたときとfailしたときで重みが異なる

 引き続き「ど真ん中」テストケースを考えてみます。
 このテストケースの実行結果がfailだと驚きですが、passは当たり前。なので、品質に対する確信をそれほど上げてはくれません。上限の下降は小さいでしょう。つまり、passとfailでは不確実性を狭めるのに寄与する度合いが違います

 下の図では、当たり前テストケースがfailしたため、期待が大きく下がり、「より確実に品質が悪い」と判断されうる状態になっています。

f:id:kz_suzuki:20191027064709p:plain

(3)テストケース実施のタイミングで重みが変わる

 たとえば境界値分析を行い、自然数の1~10が1つのクラスだったします。境界にある「1」と「10」のテストに加え、inの値として「5」をテストしたとします。 (1)で述べたように、「1」「10」のpassに比べて、「5」のpassの重みは小さいでしょう。

 では「6」はどうでしょうか。「5」がpassした後の「6」のpassには、品質に対する情報がさらに小さいといえます。ですが、「5」より先に「6」がpassしていたら? この場合は、「5」がpassするかは未知なのですから、重みは相対的に大きくなります。
 もちろん、「1」と「10」がpassした後に「5」や「6」がfailになった場合は、(2)により大きな重みが付けられます。境界を見誤っている可能性を考える必要があります。

 以上を考えていくと、この「重み」というのは、「そのタイミングでテストケースを実行した結果得られる情報量」であることがわかります。「エントロピー」というのかもしれません。

不確実性は常に下がっていくのか

 上述の(3)の例をもう少し考えてみましょう。

 あるテストケースがpassした後に、もう一度同じテストケースを実行してpassだった場合、情報量はゼロなのでしょうか。
 そうではないでしょう。完全に同じ条件を再現することができない以上、同じテストケースで同じ結果を得られることは保証されないからです。つまり「厳密には別のテストを実行した」ことになり、わずかながら情報は得られると考えられます。同じ理屈で、リグレッションテストのように繰り返し行うテストは、実行のたびに得られる情報が逓減していく*3ことになります。

 下の図では、5回連続「同じ」テストケースがpassしたことによる変化を表現しています。下限の上昇具合が緩やかになっています。

f:id:kz_suzuki:20191027064713p:plain

 一方、failするとどうなるでしょう。
 まず、間歇性の欠陥が潜在している可能性が出てきます。
 と同時に、過去のテスト実行が信頼できないものであった可能性も考慮する必要があります。正しい条件でテストできていなかったとか、結果を適切に判断していなかったというケースです。

 すると、テストを進めると小さくなっていくはずだった不確実性が大きくなってしまいます。
 モデル的には下の図のように、上限だけでなく下限も下げて表現することになるでしょうか。

f:id:kz_suzuki:20191027064719p:plain

テストが終わるとどうなるのか

 テストケースをすべて実行し、passだった場合、不確実性はゼロに、上下限はともに100になるのでしょうか。
 これは「完全な品質であることを100%確信できる状態」を意味します。そうはならないでしょう。これは「ソフトウェアテストの7原則」の2つ目、

全数テストは不可能

によるものです。

 100%の確信のためには、100%のテストケースが必要になります。考慮されていないテストケースもあれば、考慮したうえで実行を省いているテストケースもあるでしょう。よって、計画したすべてのテストケースを実行し終えても、有限の不確実性が残ります。

f:id:kz_suzuki:20191027064723p:plain

 つまり、考えられるテストをすべて行ったとしても不確実性は残り、期待できる品質も100点満点にはならない、というモデルになるでしょう。上限を100から始めている点も誤っているといえます。

 ソフトウェアの修正において、「影響範囲を見誤ってテストが漏れた」というのも、この例になるでしょう。
 当初必要だと考えていたテストが進むにつれ、期待できる品質は上がり、不確実性も減っているように見えます。しかし実際には、重要なテストケース、つまり「不確実性を減らすために大きな情報をもたらすテストケース」が漏れており、期待できる品質はもっと低く、不確実性も大きかったということです。

まとめ

 テスト実行の推移と品質の関係についてのシンプルなモデルの考察を行ってみました。
 ただ、今ふと思ったのですが、「新しい情報を得ることで確率が変動する」って、ベイズ推定で考えるべきテーマだったのか・・・? 今さら・・・?

 明日10/28(月)は、アドベントカレンダー -33日目です!

*1:なぜかリンクが見つかりません。

*2:この時点で、品質0とか品質100が何を意味するのかという問題がある。上と下を無限大にすることもできるかもしれないけれど、「無限大の品質」はさらに意味不明である。

*3:テスト対象が変化していない場合。