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

旧ブログからゆっくり移行中です。http://blog.livedoor.jp/prjmng/

Ericssonの『ユニットカバレッジの神話』を読んでみる

 今年の4月に『Mythical Unit Test Coverage』(ユニットテストカバレッジの神話)という論文が出ました。ソースコードの品質指標として言及されることの多いコードカバレッジについて、先行研究を整理したうえで、商用の大規模ソフトウェアにおける追加検証をしたものです。IEEEのサイトでも全文公開されています。

Mythical Unit Test Coverage - IEEE Journals & Magazine

 長い論文ではないのですが、わたしには論理展開のわかりづらい部分があったので、整理してみました。

アブストのアブスト

  • 「リリース前にどれだけのテストをすべきか」というのはずっと問題。
  • テストの十分性の指針として、Ericssonで長年使ってきたユニットテストのカバレッジのクライテリアを検証した。
  • 結果として、ユニットテストカバレッジは、欠陥のないソフトウェアを作ることと明らかな関係はないようだ。

「1. テストカバレッジのメジャー」のアブスト

  • テストカバレッジ*1のメジャー*2としては、Statement Coverage(命令網羅)、Decision Coverage(判定網羅)、Function Coverage(機能網羅)の3つがポピュラー。
  • テストカバレッジが欠陥の傾向(defect-proneness)に与える影響はわかっていない。

「2. 既存の研究」のアブスト

  • カバレッジと欠陥の関係についての先行研究のうち、めぼしいものが8件。
  • 先行研究8件のうち、
    • 7件は「カバレッジと欠陥数の関連は弱い」と結論。
    • 1件は「中程度または強い関連がある」と結論。
  • 先行研究8件のうち、
    • (上とは別の)7件については、欠陥が故意に埋め込まれたもの(mutants)だったり、プログラムのサイズ・変更頻度・複雑度などの交絡因子*3がコントロールされていなかったり、プロダクトが小規模で欠陥数も少ないという課題がある。
    • 残りの1件は現実のケースに近いもので、「関連は弱い」と結論。
  • 人工的な条件を避け、交絡変数をできるだけコントロールして、実践者のための結論を出すことが必要。

「3. 調査対象の製品」のアブスト

  • Ericssonが開発した大規模(約2MLOC)なテレコム系プロダクト
  • 各年に製品のメジャーリリースを行うエンジニアは約150人。
  • アジャイル/リーン開発方法論を適用。

「4. 調査方法」のアブスト

  • 1年間におけるファイルごとの欠陥数(統合テスト、システムテスト、顧客環境)を収集。ユニットテストは対象外。
  • カバレッジは、ユニットテストにおけるものを測定。
  • 予想は、「ユニットテストでカバレッジが高ければ、以降で欠陥が現れる可能性が低下する。逆も同様」
    • カバレッジと欠陥の間に明確な負の相関(-0.4以下)があれば、テストの十分性としてカバレッジを利用できるだろう。
  • サイズ・複雑度・ファイルの変更回数について、カバレッジ・欠陥数・両者の関係にどのくらい影響するかを理解するために計測した。
  • プログラミングやテストのスキル、言語、利用ツールなどはランダム分布していると仮定。

「5. 結果」のアブスト

  • サイズ・複雑度・変更回数と、欠陥数・カバレッジの相関を一覧化。
    • カバレッジ同士は相関が強いので、他の要素との相関は statement coverage のみを見る。
  • カバレッジと欠陥数の相関係数は小さく、テストの十分性のクライテリアとして適切ではない。ただし、
    • 同じカバレッジ50%でも、1,000LOCと100LOCでは欠陥数にも違いがあるだろう。実際、サイズと欠陥数には強い相関がある。サイズをコントロールする必要がある。
    • 変更頻度についても同様。多くの変更があるファイルは集中的に開発されているということで、欠陥をはらむ可能性も高くなる
    • 「LOCあたりの平均カバレッジ」と、「バージョンあたりの平均カバレッジ」をいうメジャー*4を追加。
    • その結果、この「カバレッジ密度」と欠陥の数の相関は若干上がっているが、それでも弱いまま

「6. 複雑度の影響」のアブスト

  • 最大ブロック深度(Maximum Block Depth、ネストレベルの最大値)にはいくつか特徴がある。
    • コードメトリクスで唯一、サイズ・変更回数との相関がない。
    • カバレッジと明確な負の相関を持っている。ネストの深いコードは、テストを書くのが難しいと理解できる。
    • 欠陥数とも相関がある。シンプルなコードよりもネストの深いコードの方が、バグを作りやすいと理解できる。
  • 変更回数と欠陥数にも正の相関がある。開発が集中するところに欠陥が入り込みやすいと理解できる。
  • 欠陥数に影響与える要素「サイズ」「最大ブロック深度」「変更回数」のうち、開発において制御しやすいのは最大ブロック深度。プログラミングの技術によって抑制して、欠陥数やカバレッジに与える影響を小さくできる。

「7. むすび」のアブスト

  1. Ericssonにおけるユニットテストのカバレッジクライテリアは神話であった。
  2. 国際標準におけるこのメジャーの推奨は、見直しが必要。
  3. この問題がどれほど一般的なのかを理解するために、他のドメインでも同様のケーススタディを行う価値がある。
  4. コードの複雑さをコントロールすることで、欠陥混入の可能性を下げ、コードのテストのしやすさを向上させられる。

感想

 「Ericssonの特定の製品については」という点を慎重に述べている印象です。ただ先行研究の大半においても、「コードカバレッジと欠陥数の相関は小さい」としていることから、一般性にある結論かもしれません。

 この論文を読んで最初に思ったのは、「そもそもサンプルデータとして高カバレッジのコードしかなく、相関が低いというのはそのエリアの話なのではないか? つまり、カバレッジが一定以上になるとそれ以上のカバレッジ向上は品質への寄与が小さい、ということではないのか?」ということです。しかしこの論文に描かれた等高線図を見ると、カバレッジの範囲は0%~100%でプロットされており、そういうわけでもなさそうです。
 たとえばカバレッジが0%から50%に上がっても、欠陥数には影響しないということですね。にわかには信じがたいが・・・。

 後半の「最大深度」と欠陥数の相関は、直感的でわかりやすいですね。
 一方、ちょっと古い記事ですが、Googleはこのようなコードメトリクスではなく、変更回数も含めた変更履歴の情報から、欠陥予測のアルゴリズムを作っていました。 www.publickey1.jp

 こちらのポストでいうと、「コードチャーン (code churn)」*5というものですね。 www.kzsuzuki.com

*1:コードカバレッジについては、以下のポストもご覧いただければと思います。www.kzsuzuki.com

*2:SQuBOKガイドによると、「測定法」に対応する英単語は、2007年のISO/IEC 15939:2007から「measure」を採用しているとのこと。それ以前は「metric」だったようです。

*3:交絡因子の説明とコントロール方法について、それぞれ以下のサイトがわかりやすかったです。 www.nies.go.jp 研究デザインにおける交絡のコントロール

*4:追加された2つのメジャーの意味が理解できませんでした。カバレッジの平均とは・・・? とにかく、サイズと変更回数の影響を減らすための正規化のような操作だと解釈しています。

*5:Google日本語変換では「ちゃーん」の変換第一候補が「ちゃ~ん」でした。イクラなんでもそれは・・・。