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

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

DDP(欠陥検出率)とは何か。

Jenga

 秋山浩一さんがTwitterで、DDP(Defect Detection Percentage、欠陥検出率)の良さについて言及されていました。

 わたしがDDPについて初めて知ったのは、『システムテスト自動化標準ガイド』の翻訳をしているときです。おっと、ついアフィリエイトリンクが・・・。

システムテスト自動化 標準ガイド (CodeZine BOOKS)

システムテスト自動化 標準ガイド (CodeZine BOOKS)

 DDPについては、メトリクスとしては知っていても実際に使ったことがないので、少し調べ直してみました。

DDPの定義

 こちらは秋山さんのツイートの中で説明されている定義です。

DDP値=検出バグ数÷当初保有バグ数×100

 『標準ガイド』の著者の一人であるDorothyさんは、JaSST'13 Tokyoでの講演の中でDDPに言及していますので、聴講レポートから引用してみましょう。

www.kumikomi.net

欠陥検出率は,テスト・フェ-ズで摘出した欠陥の数を,テスト・フェ-ズおよびリリース以降の別のフェ-ズで見つけた欠陥の総数で割った値のパーセンテージで示される.

 分母になる数字として、「当初保有バグ数」も「テスト・フェーズおよびリリース以降の別のフェーズで見つけた欠陥の総数」も、すんなり読むと間違えると思います!
 これらの意味は、そのテストフェーズが始まった時点で残存しているバグの数、ということです。裏を返すと、そのフェーズより前に見つかったバグの数は、式には現れません

具体的な値で計算してみる

 テスト開始から現在までで、バグの全数が535件だったとしましょう。
 で、各テストフェーズで以下のようにバグを検出したとします。

f:id:kz_suzuki:20200208123410p:plain

 CT(コンポーネントテスト)では、405件見つけています。535件のうち405件を検出したので、DDPは 405 / 535 = 75.7% ということになります。

 33件を検出したIT(統合テスト)ではどうでしょう。
 計算式は、33 / 535 ではありません。33 / 130 で、74.6% です。
 33というのは、535 - 405、つまりCTを経てITまで流れ込んできたバグの数、ですね。名前を付けるなら「当該フェーズ開始時潜在バグ数」などとなりますが、長すぎる・・・。ここでは「当初保有バグ数」をこのまま使います。
 最終的なバグ数に対して各フェーズで検出した割合、ではないので注意が必要です。

 上表からは、以下のようなグラフが得られます。

f:id:kz_suzuki:20200208123617p:plain
バグ検出とDDP

 帯グラフの高さが、当初保有バグ数です。薄いグレーはそのフェーズで検出したバグ数。濃いグレーはそのフェーズでの残存バグ数であり、次のフェーズにとっての「当初保有バグ数」になります。

 当初保有バグ数(分母)は、後ろのフェーズになるほど小さくなるので、検出されたバグの数(分子)に敏感になり、DDPを高く保つのが難しくなりそうです。

 なお「リリース後」のDDPは意味ないですね。常に100%になります。

全数とは・・・

 さて、この時点でだいぶ大きな違和感があるでしょう。
 そう、「バグの全数って何だよ」という点。

 それは未知の数なので、「現時点の累積」で代替するしかなさそうです。そのため、あるテストフェーズ完了時点では、DDPは100%になります。次のフェーズが始まって新しいバグが検出され始めると、「当初保有バグ数」が増加方向に修正されるので、DDPは下がっていくことになります。

 先ほどのフェーズ別の検出数を日々の検出数に開いたのを以下の表として、

f:id:kz_suzuki:20200208123927p:plain
日々の検出バグ数

 DDPの推移をグラフにしてみました。

f:id:kz_suzuki:20200208124016p:plain
各テストのDDP推移

 CTが終わる1月12日まではDDPは驚異の100%を誇っていますが、13日からのITでバグが検出されると分母が増え(そして分子が変えられず)、DDPが低下していきます。IT、ST(システムテスト)、AT(受け入れテスト)も同様ですね。
 特にATは、完了時点で分母が6だったものの、リリース後に4件バグが出てしまったため、DDPは60%に低下してしまいました。時間経過は加味されないので、このバグがリリース直後に出ても、リリース1年後に出ても、結果は同じです。

欠陥密度と似ているところ、違うところ

 「欠陥密度」は、検出バグ数を開発規模で割ることで得られるメトリクスです。「毎回の開発において、欠陥密度は同じような数字に収束するだろう」という仮定に基づき、開発前に定めた目標値の実際の値を比較して、テストの十分性の一助に使います。

 欠陥密度とDDPは、分子が検出バグ数であるという点は同じです。
 分母について、欠陥密度の分母は開発規模であり、定義が決まれば一意に求められる値で、わかりやすい。
 ただし、「開発規模とバグ数はおおむね比例する」という仮定や、プログラミング言語、開発スキル、プロダクトの性質といった条件が同一であることも(暗黙の)前提になるため、場合によっては納得感の低いメトリクスとなります。

 DDPは当初保有バグ数を分母として「見つけたバグの割合」を求めることになるので、欠陥密度で前提したようなことはそれほど加味しなくてよく、さまざまな開発で横断的に使える可能性があります(すみません、実践していないのではっきり言えない・・・)。
 しかし上述の通り、分母の「真の値はわからない」という本質的な問題をはらんでいます。テスト完了時点では DDP = 100% になりますので、リリース後「一定期間」待ったうえで、DDPを再度確認することになります。「期間」はプロダクトに依存しますし、待ったところでやっぱり真の値はわからないのですが。

 一方、テスト完了時点で、各テストフェーズのDDPが(暫定的とはいえ)見えているので、各フェーズが健全に行われたかの判断に使うことはできそうです。ITフェーズに入って、その前フェーズであるCTのDDPが急激に下がっていくようであれば、

  • CTフェーズでのテストが足りていない
  • ITフェーズに対応する設計や実装に問題がある

といった可能性を疑うことができます。

 二つのメトリクスの共通点として、「高ければいい、低ければいい、と単純にいえない」というものもあります。
 欠陥密度が低いのは、プロダクトの品質がもともとよかったのか、テストが足りていないのか。
 DDPが高いのは、後フェーズでのテストが不十分で、分母が増えていないだけではないのか。
 これは、1つのメトリクスから判断すべきものではありません。メトリクスはあくまでもキッカケでしょう。

DDPの良い効能

 DDPの効能として秋山さんは、「分母を減らそうとするモチベーションが働く」旨を書かれています。

 単純に数字だけを扱うと殺伐としがちですが、メトリクスの改善のためにできることは何かを考え、具体的な施策に落とし込むような文化では、楽しく取り組めそうです。

 また別の観点でちょっと面白いなと思ったのは、あるテストフェーズでしっかりテストしておかないと、以降のフェーズのバグ検出により、そのフェーズのDDPをガンガン下げられてしまうという点です。
 フェーズでチームが分かれていれば、チーム間のゲームのような感じもありますし、チームが同一でもたとえばITでのがんばりがCTのDDPを下げてしまうジレンマを解消するためにCTからしっかりやる、というモチベーションになります。なかなか興味深い性質だと感じます。

アジャイルでは使えるのか

 Dorothyさんの講演によると、テストフェーズをスプリントに読み替えて、DDPを使っているとのこと。
 検出したバグが、どのスプリントで「検出すべき」バグかを調べて記録しているような組織であれば、簡単に使えそうですね。

 以上です。念のためもう一度貼っておきます。

システムテスト自動化 標準ガイド (CodeZine BOOKS)

システムテスト自動化 標準ガイド (CodeZine BOOKS)