アーキテクトとしてアプリの方針などを考える仕事をしています。
単体試験の工程にて、jUnitをやることになると必ず問題になるのがカバレッジ計測率のお話。
多くの本やサイトではカバレッジ100%までやる必要がないと記載がありますし、個人的にもやりたくないのですが、提案の段階でカバレッジを100%を目指さない論理を持っていません。
100%までやらないと全てのパターンを網羅してると言えないのでテストとして不十分だ。と言われてしまうと反論ができません。
そこで、以下をご教示いただきたいです。
- カバレッジを100%にしなくてもいい理由
- お客さんを納得させるための論理・根拠
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答7件
0
多くの本やサイトに載ってると思いますが
データパターンや条件網羅を考えると
カバレッジを100%やっても全然十分ではない。
むしろ無駄が多い。
すべてを100%にするには比例的に工数が増えることを説明し、
お客さんと共に妥協できる着地点を探す。
例えば
- マネーパスや業務上クリティカルな処理などが絡む処理は100%を目指す。
- 利用係数の高い機能は重点的に複数のデータパターンで100%を目指す。
- 利用係数の低い機能は正常系といくつかの異常系のみ80%以上を目指す。
目指す
って書いておけば、98%だったときに
残りの2%は工数見合いで、他の機能を優先させました。
クリティカルパスのhogehogeに限っては100%です。
みたいな感じでしょうか。
人と金と納期の引き合いに出すと分かってくれる人もいる。
が、100%にこだわる人もいる。
投稿2017/05/25 03:54
総合スコア1400
0
こんにちは。
まず、C0/C1カバレッジ100%にしても十分なテストではありません。
本当にやりたいことは全ての条件分岐の全ての組合せについてテストすることです。C2カバレッジ100%ですね。しかし、これは組合せ爆発が発生するため事実上不可能です。
if文1つならパスは2通りです。if文が2つならパスは4通り、if文が8つならバスは256通り、...、if文が32個でパスは4,294,967,295通りです。
実際には合流するのでここまで極端には増えないですが、増え方のオーダーは大差ありません。
if文が32個しかないプログラムってかなり小規模ですね。通常のプログラムはif文は数百~数万と存在するでしょう。
その全てをテストしようとすると組合せ爆発が起きます。
組合せ爆発は↓が感動的です。
『フカシギの数え方』 おねえさんといっしょ! みんなで数えてみよう!
そこで、せめて全てのコードを最低一通り通してテストしましょうと言う考え方がC0カバレッジです。せめて条件分岐については全てtrueとfalseの両方を通しましょうというのがC1カバレッジです。
C1でさえ条件分岐の組合せを考慮しないため全く不十分です。(*1)
しかし、目安にはなるのでよく使われます。
問題は、maisumakunさんも指摘されていますが、適切にインストールされた本番環境では通らないバスが存在します。
そこをテストするためには、特殊な環境を構築してテストするしかありません。その環境構築にもバグは発生します。
通常の使用方法では発生しない不具合を検出するために、特殊な環境を構築し、そのデバッグ(場合によってはその環境自体のテスト)を行う工数を投入するより、通常の使い方でよく通るパスについて、全部は無理にしてもたった一通りではなく、よく通ると思われる組合せについて重点的にたくさんテストするべきと思います。
(*1)
例えば、C1カバレッジ・テストで、if文Aがfalseの時のみ、if文Bがtrueとfalseの両方の条件をテストしているかも知れません。
そのような時、if文Aがtureでif文Bがfalseの時のみ発生する不具合は検出できません。
実際、C1カバレッジは特定のif文については両方テストしますが、その時、他のif文がどうなっているか考慮しません。
きちんとプログラム全体を結合した状態でテストする場合は、他のif文はtrueかfalseのどちらか限定となります。
通常は、C1カバレッジの測定は単体テストで実施するため、あるモジュールが他のモジュールへ与える影響を考慮しません。仮にC1カバレッジを100%にしても、モジュール間I/Fに存在するバグを検出する能力がありません。
投稿2017/05/25 05:52
編集2017/05/25 06:00総合スコア23272
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/05/26 03:20
2017/05/26 03:55
2017/05/26 07:23
2017/05/26 08:49 編集
2017/05/29 04:13
0
最低でもC0は単体試験で100%にするでしょう。って思っているんですが、
そんなに甘くはないんですか?
書いたコードを通さないとかありえるんですか?
どんなにイレギュラーなケースでも、何とか擬似的に再現させてでも通しますよね。
C1は業務処理であれば、業務パターンそのものとも言えるので網羅すべきですが、
フレームワーク部分がしんどいかもしれませんね。。。
問題はC2ですね。
データパターンのマトリクスに◯✕付けまくって、
ありえないケースや無意味なケースはグレーアウトして、
残ったものを片っ端からやっていこうというあれですね。
あれに関しても、本来は必要だと僕は思っていますが、
でかいシステムになるとケース数が、「これほんとにやるの?」っていう数になることも
しばしばあるので、そこは頭使って取捨選択していくのが現実的でしょうね。
つまり、ここの100%は現実的でない時もあります。
そして一番つらいのは、全てをJUnitで再現させるってことじゃないでしょうか。
しかし何かしかの計測ツールを使わないと、パーセンテージに説得力がないし
っていうところですよね。。。
お客さんへの説明は費用対効果しかないんじゃないですかね。
98%から100%にするだけで、さらにこんだけ工数かかりますよ。
かと言って残り2%をやる価値としては、こんなもんですよ。
それでもやりますか?
金払うからやれと言われればやるしかないんでしょうね。。。
ただ、金もらっても間に合うかどうかは別問題なので、スケジュールの調整は必要ですね。
投稿2017/05/25 04:57
編集2017/05/25 05:12総合スコア4666
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/05/26 02:15
2017/05/26 02:57
2017/05/26 07:37
0
ベストアンサー
僕は受注開発してないので後者はわかりませんが、前者について。(私見です)
〇カバレッジを100%にしなくていい理由
機械的にC0/C1/C2のテストしようとしたらテストケースってコードで増減しますよね。
分岐を上手に減らせばテストケースは減ります。
逆に、下手なコーディングするとカバレッジ100%を達成するのに必要なコーディング量は倍々ゲームで増えていきます。
ここで、本来のTDDで言われるような単体テストの目的を考えてみてください。
最初に単体テストが提唱されているのは、目的に叶ったメソッドデザインを作成する、そしてその目的が達成できているかどうかをチェックすることです。
つまり、「外側から見た構造」をテストしていくんですよね。
機能設計が先か、実装が先かって話で、内部コードのカバーはデザイン時に決定されません。
ってことは、利用目的から内部コードのカバレッジ100%を目指すことはできません。
=カバーコスト(内部カバレッジ100%)は顧客要望から導き出すことができないということです。
事前にボリュームが分からないのに、合意は成立しません。
カバーコストは上手な人が作れば減るでしょうし、下手な人が作れば増えるでしょう。
要件がおかしいとか、経験的なボイラーテンプレートによるメトリクスの肥大化も考えられます。
一方で、要求仕様自体は当初から(拡張・変更こそあれ)一定のはずです。
カバレッジからスタートすると、要件とのミスマッチが発生してしまいます。
カバレッジ100%目的のユニットテストは設計とは逆の、パッチングに近いテストコードになってしまうでしょう。
インテグレーションテストは基本的にシナリオベースですし、単体テストもそうではないか、と考えています。
投稿2017/05/25 06:12
編集2017/05/25 07:34総合スコア1593
0
ソフトウェアによっては、プログラムやインストール状態にバグがあるときしか通らないパスが存在することもあります。たとえば、組版ソフトのTeXには、「This can't happen」というようなメッセージが用意してあって、出た場合には「使用中の TeX に間違いがある.TeX をインストールした人に厳しく文句を言おう」とのことです(情報元)。
Javaではあまりないでしょうが、環境によってコードを差し替えるような場合も、環境ごとに見ればカバレッジは100%に達しえません。
投稿2017/05/25 04:07
総合スコア145932
0
SLAを締結することが大事だと思います。
品質について補償することで、リスクを共有すれば工数として非合理だと言う説明を信じてもらえるとおもわれます。お客さんは品質はタダだと思うので過剰な要求をするのだと思います。
でなければ、ひとつづつわざわざ対応するべきでない事例を上げて許可を取っていくことくらいしか思いつきません。
投稿2017/05/26 15:05
総合スコア2883
0
ソフトウェアの作り方にもよると思うのですが・・・
たとえば、Webアプリを作っているとすると、
インメモリDBの該当するテーブルをわざと一旦Dropして接続させてみてエラーメッセージが吐かれるかどうかをUTのケースにするということがあると思います。
その際、
・そもそもこのテーブルなかったらその前から動かない
・独自のエラーメッセージの出力はしない
などの状況なのであればやる必要はないような気がします。
カバレッジとは何かをお客さんに説明する前提ですが、
お客さんへの説明も上記理由等で100%にする意味がない旨をお伝えすればよいのではないでしょうか。
投稿2017/05/25 03:48
総合スコア2021
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/05/26 02:12
2017/05/26 03:02
2017/05/29 04:22