コードカバレッジが高くても品質は高くない。バグ検出するテスト測定方法

上流での品質保証が不十分で後段に致命的な不具合(バグ)が流出してしまうと、手戻りが発生しコストが余計にかかる。

また、下流のブラックボックスなテストで不具合を検出すると、不具合箇所の特定が困難になりプロジェクトの遅延に繋がる。

だから上流で不具合の未然防止・混入防止をしよう。

 

これを品質保証上流化、上流品質(レフトシフト)という。

 

そして、そんな説明の時に必ず利用されるのがCapers jones の下記のグラフ。

 

[引用] capers jones applied software measurement global analysis of productivity and quality

 
 

終工程で不具合が見つかれば修正コストが非常に高くなる事が読み取れる。

 
 

実装に不具合が混入することは分かるけど、システムテストに不具合が混入するってどういう事だろう?

それって仕様書側に問題があるんじゃないの?

加えてユニットテストより機能性テストの方が不具合が少ないってどういう事?

……とセミナー講師に質問した事があったが明確な返答は未だ頂いてない。

「コードベースの単体テスト」とは「関数の網羅性を計測し、ロジックの確からしさを確認するホワイトボックステスト」を指す。

「コードベースの単体テスト」は、厳密なソフトウェア品質を求められる自動車や医療のソフトウェアでは確実に行わなければならないテストであり、ISOなどで行うことがルール化されている。

そこで出てくるルールに

 

コードカバレッジ(コード網羅率)

 

がある。

開発者で用語を知らない人はいないと思うけど、簡単にまとめておく。

網羅率 説明
C0: 命令網羅率(Statement Coverage) すべての命令コードを実行しているか
C1: 分岐網羅率(Branch Coverage) C0だけでなく、命令コードのない条件分岐(else が記述されていないコードの else になる条件)も実行しているか
C2: 条件網羅率(Condition Coverage) C1だけでなく、条件式に and/or 条件があり、それぞれの条件の真偽の組み合わせも実行しているか

「C0 カバレッジを80%以上を満たすこと」などのクライテリア(基準)が存在しているプロジェクトに参画した人も多いはずだ。

でも、そもそも「コードカバレッジ率」と「不具合流出防止」の相関ってあるの?

「コードカバレッジが高ければ、ソースコードの品質が高い」という誤解

「カバレッジを100%に近づければ近づけるほど、バグ検出の費用対効果は低下する」

という話もよく聞く。

 
 

でも、根拠となる証拠が全くない。

 

© 半沢直樹/TBSテレビ/写真:緋田康人

 

そもそも、コードカバレッジが高くてもテストケースの質が悪ければ不具合は検出されない。

例えばコードカバレッジ100%でASSERTが全く無いテストケースを実装した場合、実行しても不具合を検出する能力はほぼ無い。

 
 

コードカバレッジと不具合発見の相関に関する論文を二件発見した。

結論としては、

 

コードカバレッジと不具合流出数に相関はない(or 弱い)

 
 
 

ガーン。

ユニットテストカバレッジの神話

ユニットテストカバレッジの神話(Mythical Unit Test Coverage)」という2018年のIEEEの論文に記載があった。

先行研究を整理したうえで、商用の大規模ソフトウェアにおける追加検証をしたものだ。

 

論文 内容
A. Mockus, N. Nagappan, and T. T. Dinh-Trong, “Test coverage and post-verification
defects: A multiple case study,” 3rd International Symposium on Empirical Software
Engineering and Measurement, 2009, pp. 291-301.
The correlation between coverage and defects is none or very weak.
カバレッジと欠陥の相関は、全くないか、非常に弱い
M. R. Lyu, J. Horgan, and S. London, “A coverage analysis tool for the effectiveness
software testing,” IEEE Transactions on Reliability, vol. 43, pp. 527-535, 1994.
No association is found between the defects and coverage by qualitative analysis
欠陥とカバレッジの間に関連は見つからなかった
P. S. Kochhar, F. Thung, and D. Lo, “Code coverage and test suite effectiveness:
Empirical study with real bugs in large systems,” IEEE 22nd International Conference on
Software Analysis, Evolution, and Reengineering (SANER), 2015, pp. 560-564.
Moderate to strong correlation is found between coverage and defectiveness.
カバレッジと欠陥の間には、中程度から強い相関関係が見られた

要約すると、

カバレッジと欠陥の関係についての先行研究のうち、めぼしいものが8件あり、

  • 7件は「カバレッジと欠陥数の関連は弱い」と結論
  • 1件は「中程度または強い関連がある」と結論

となっている。

日本語で要約してくれている人も見つけたのでリンクを貼っておく。

 

論文の中では「カバレッジと欠陥数の相関係数は小さく、テストの十分性のクライテリアとして適切ではない」として、C0 カバレッジと不具合数がPlotされている。

 

そして文献の中で

 

国際標準におけるこのメジャーの推奨は、見直しが必要。

 

とまで言い切っている。

コードカバレッジとリリース後の欠陥

コードカバレッジとリリース後の欠陥:オープンソースプロジェクトに関する大規模な調査(Code Coverage and Postrelease Defects: A Large-Scale Study on Open Source Projects)」という論文も見つけた。

この論文では、100の大規模なオープンソースJavaプロジェクトを分析し、ソフトウェアのリリース後に問題追跡システムに記録された実際のバグを収集し、コードカバレッジとこれらのバグとの相関関係を分析している。

 
 

 

カバレッジがプロジェクトレベルでソフトウェアのリリース後に発見されたバグの数とわずかな相関関係があり、ファイルレベルではそのような相関関係がないことが示されている。

コードカバレッジの網羅は なぜ必要なのか?

結論として「カバレッジ率が高いからコード品質が高い(バグが少ない)」なんて言えない。

 
 

カバレッジを高めれば、バグが少なくなりソースコードの品質の上昇が期待できます。
逆にカバレッジテストが十分で無い場合、ソースコードの品質は低くなりバグが多発する危険性があります。

 

 

こういう証拠も何も無いコンサルタントの言葉や、アフィリエイトサイトにはうんざりだ。

 

カバレッジテストの目的とは?バグを潜伏させてしまうテストケースもあわせて紹介 | .NETコラム
カバレッジテストとは、プログラムのソースコードを網羅するテストのことであり、行えばソフトウェア等の品質を大幅に改善させられます。しかし適切に行わなければバグを潜伏させてしまうケースもあります。カバレッジテストの目的と注意点について、解説します。

 
 

浅いんだよ!テメェらの言葉は!

 
 

そんな甘い言葉で誰もが「はいはい」と動く世界じゃねーんだよ!

 
 

アジャイルコーチであり経営コンサルタントの「Christian Gruber」氏の記事にも次のように書いてある。

  1. カバレッジはしっかりとしたテストが書かれている状況でのみ意味を持つ。役に立たないくだらないテストが書かれることを防ぐことはできない。
  2. カバレッジはテストが通過した行/分岐を測定しているだけに過ぎない。
  3. カバレッジはテストが不十分かどうかを示唆するが、十分であることを保証するものではない
  4. テスト駆動で書かれたコードは十分なカバレッジを示しやすい。
  5. テスト駆動で書かれたコードは十分なテストがされていることが多い。作成者はコードの要求/仕様のすべてを形作るテストを書いているからだ。
  6. 完全なカバレッジは十分なテストに必要なものではない
コードカバレッジには要注意
Christian Gruber氏はコードのカバレッジをメトリクスとして使うことに対するTDDのスタンスを、時間をかけて明確にしようとしている。

要するに

 
カバレッジ率が高いことは、欠陥を含む可能性が「より低い」

 

というだけであって、必ずしも欠陥が無いことを意味するわけでは無い(必要十分条件は成り立たない)。

カバレッジを計測する目的(目標値に設定する理由)

何のためにコードカバレッジを上げる必要があるの?

 

ネットや文献で調査してみたが、品質貢献観点で納得できる結論を発見できなかった。

 

  • テストが十分に網羅されていないコードが検出できる
  • コードレベルの単純な不具合は、ある程度は無いといえる
  • (テストコードがあるので)自信をもってリファクタリングをすることができる
  • そのコードがどれだけテストされているのかを把握できる(可視化)
  • テストを実行したときに、実装コードのどの部分が実行されたかを調べることができる

 

調べると調べるほど、カバレッジを上げる目的は「品質を上げるため」じゃ無さそうだ。

だったら上記の目的のために、開発者は設計・実装・品質保証と超多忙にも関わらず闇雲にコードカバレッジを上げることを課す必要があるのか?

そして品質貢献しないのに「品質達成クライテリア」に入れてるプロジェクトは全て間違っているんじゃないの?

テストケースの欠陥検出能力をどうやって測定するのか?

開発者テストの主たる目的は「ソフトウェアに潜む欠陥を発見」することだ。

だったら、開発者の用意したテストが十分にバグを検出する能力があることはどうやって測定すればよいのか?

知っている限り3つ。

ミューテーション解析(ミューテーション法)

ミューテーションテストは、テスト対象のプログラムにわざと意図的に不具合を埋め込む(ミュータントを生成する)事で、テストケースの欠陥検出能力を測るテスト。

書籍でも紹介されている。

 

また2018年に公開された論文「State of Mutation Testing at Google」では「Mutation Test(ミューテーション・テスト)」を使ってテスト基準としている事が書かれている。

 

Googleでは、コードの修正に伴うレビュープロセスにMutation Testを組み込むという方法を用いています。まず、開発者が既存のコードを修正した場合、その修正部分についてのレビューが行われますが、この際、レビュー対象となる修正部分についてのみMutationを行うことで、開発者(あるいは、レビュアー)の興味の対象となる部分にポイントを絞って、Mutation Testを行います。

コラム - グーグルのクラウドを支えるテクノロジー | 第86回 GoogleにおけるMutation Testの実践(パート1)|CTC教育サービス 研修/トレーニング
はじめに  今回からは、2018年に公開された論&#...

 

この測定方法の存在は知っていたが、動作しているコードにバグを仕込むというのは狂気の沙汰に感じて非常に抵抗がある。

またランダムにバグを仕込んだところで、デッドロックや画乱れ発生のような不具合を検出できるテストケースなのか判断できるのかな?

複数の基準から総合的に判断する方法

芝浦工業大学の中島教授が「ソフトウェア工学1 第12回 品質とその評価」として記載している。

テスト妥当性 (adequacy) とはプログラムの信頼性の指標

 

 

信頼度は一つの基準だけを信用するのではなく、複数の基準から総合的に判断すべきとのこと。

テスト妥当性評価基準 説明 指標
運用的基準 運用状態でどれだけ長く正しく機能できるか ランダムテスト+運用信頼性指標(MTBF)
欠陥除去基準 テストによって「どれだけ欠陥が除去が残っているか」 欠陥発見効率・信頼性成長曲線モデル
網羅性基準 テストケースがテスト空間をどれだけ検査できたか 仕様カバレッジ・コードカバレッジ

前述したが「カバレッジはしっかりとしたテストが書かれている状況でのみ意味を持つ」と書いてあった。

つまり「不具合が流出してないか?」を測定することで「しっかりしたテスト」であるかを確認し、カバレッジを測定することで「網羅率」を確認することで初めて「テスの質」が証明されるという考え方。

ただし流出不具合から計測するので、開発者がテスト作成・実行した時点で「テストの質」を知ることができる方法ではない。

ゾーン分析を用いる方法

日本では

データを取得して、バグ密度・テストケース密度を計算して、ゾーン分析をする。

というのが比較的ポジティブに受け入れられている。

が海外では全く知られていないので、以前 英語で紹介したことがある。

Zone analysis for validating the number of test cases and bug detections
When developing and running tests, you may have the following questions:Is this amount of test cases appropria...

ただしこれも流出不具合から計測するので、開発者がテスト作成・実行した時点で「テストの質」を知ることができる方法ではない。

【付録】コードカバレッジの目標値は幾つが良いのか?

品質に役立たないと分かってしまったコードカバレッジだが品質関係チームから「数値目標を定義しろ」と要求を受ける事がある。

 

 

「じゃあ、いくつを目標値にすれば良いのか?」

と聞くと、

「それは君たちのプロジェクトの特性に合わせて……ゴニョゴニョ」

と、教えてもらえない。

 

日本で唯一、開発者テストに言及しコードカバレッジに関して言及している高橋寿一氏の書籍に次のように書いてある。

因みに氏は、大学の先輩であり会社の関連上司だ。

筆者は、数十年にわたるテスト関連の論文は目を通しています。しかし、まっとうな論文には、その網羅性のゴールは書いてありません。もちろん、ISOやIEEEの規格にも書いてありません。なぜなら、それを書いて致命的なバグが出ると責任を取らなければならないからです。

 

理解した……。

 

さらに次のように書いてある。

自動車などのミッションクリティカルなソフトウェアの場合は、100%と自信を持って答えます。
しかし、ミッションクリティカル以外のソフトウェアでも、十分なコードベースの単体テストを行うことは、後半工程のバグを減らし、ソフトウェア品質の向上に十分に役に立ちます。その場合、筆者は自身をもって80%と言い切ってしまいます。実際には言い切れないのですがw。

 

これぐらい現場に即して定義してくれる方がありがたい。因みに、このコードカバレッジは「C1」だ。

まとめ

「コードカバレッジを測定しろ」と言うのに数値を定義しないとか、品質関係者って誠意ある態度を取らない気がする……。

だから、品質プロセスのセミナーとか部署とか退職前後の年寄りが綺麗事だけ語ってて嫌いなんだよ……。

そもそもソースコードも読めない人が多すぎる。

 

この辺りの話って多くの企業のプロジェクトで困っている話題だと思うんだけどね。

アドバイス・コメントを頂ける方は大歓迎!

タイトルとURLをコピーしました