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

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

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)