web-dev-qa-db-ja.com

コードが自動的にカバーされていることをどのように確認しますか?

CI/CDワークフローでTDDにプッシュするためのいくつかの新しいプロジェクト用にBambooサーバーをセットアップしているところです。確かに、単体テストは素晴らしいですが、そこにあるのと同じくらいログだけです。

これは、特定のブランチ(つまり、開発ブランチとメインリリースブランチ)のGIT事前受信フックで改善することができますが、コードカバレッジを実施する場合は、どのように実施する必要がありますか。私はコミッターを信頼してコードがカバーされていることを確認できてうれしいですが、勤勉さと一貫性を除けば、これらの事柄はどのように維持されていますか?

要するに、コミット段階またはビルド段階のいずれかで、他の人がどのようにテストカバレッジを自動プロセスとして実施するかを確認したいと思います。

9
Daniel Park

コードカバレッジを自動的に適用しないでください。

これは、メソッドごとにコードの最大行数を強制するのに似ています。同意します。ほとんどのメソッドは、たとえば20 LOC未満である必要がありますが、メソッドがそれよりも長い場合もあります。

同様に、クラスごとに特定の割合のコードカバレッジをターゲットにすると、望ましくない結果が生じる可能性があります。例えば:

  • ボイラープレートコードクラスまたはコードジェネレーターによって作成されたクラスは、まったくテストされない場合があります。開発者にそれらをテストするように強いることは何の利益もありません、そしてそれをするのに費やされた時間の面でかなりのコストがかかります。

  • アプリケーションの重要でない部分を処理する単純なコードは、必ずしもテストする必要はありません。

  • 一部の言語では、一部のコードをテストできません。私は、C#でこのメソッドを使用して、ライブラリで匿名メソッドを使用しましたが、実際にはwantedで100%のコードカバレッジが必要です。これらのケースは、開発者にとって意気消沈する可能性があります。

さらに重要なことに、コードカバレッジは、コードの2つの側面に比例する必要があります。どれほど重要で、どれだけ複雑か

  • アプリケーションの主要な機能の一部である複雑なロジックを含むコードは、失敗や回帰が重要な結果をもたらす可能性があるため、慎重にテストすることをお勧めします。

  • 誰も使用しない機能を処理する単純なコードには、基本的なケースのみをカバーする基本的なテストがある場合があります。

もちろん、測定値としてコードカバレッジを使用することもできます。特に、異なるチームがどのようにコードカバレッジを達成するかを比較することができます。テストに関しては、より消極的です。このような場合は、バグの数、バグの解決に費やした時間、コードレビュー中のコメントの数など、他の指標とこの指標を組み合わせることができます。

少なくともsomeコードカバレッジ、たとえば60%¹を個々のプロジェクトに適用することもできます意味がある場合(プロトタイプ、生成されたコード、CRUDを除外するように注意してください)など)開発者が特定のクラスをコードカバレッジから除外することを可能にすることも、Nice²です。この場合、コードカバレッジが必要な最小値を下回っている場合、ビルドが失敗するチェックの形式でこれを行うことができます。 コミット中に単体テストを実行することは想定されていない であるため、私はコミット段階ではなくビルド段階でそれを行います


code私のコードベースでは、60%を妥当な最小値と見なします。コードカバレッジが60%未満のほぼすべてのプロジェクトまたはクラスは、実際にはnestedです。これは、言語や会社によって大きく異なります(一部の会社では、0%が標準です)。 normalとは何か、too highとは何かについてチームと話し合うようにしてください。多分彼らは絶えず95%に達していて99%を簡単にターゲットにすることができます、あるいは多分彼らはコードカバレッジを70%から75%に増やすのに苦労しています。

²最終的な悪用はコードレビュー中に検出されるため、開発者にこの可能性を与えることを恐れないでください。これは、リンターまたはスタイルチェッカーによるチェックからコードの一部を除外する可能性に似ています。 JSLint、StyleCop、およびコード分析は、除外がサポートされている3つの例であり、乱用を助長することなく実際に役立ちます。

17

次のコードを検討してください。

_rsq = a*a + b*b;
if (rsq >= 0.0) {
    r = sqrt(rsq);
}
else {
    handle_this_impossible_event();
}
_

Elseブランチに到達するテストケースを作成する方法はありません。しかし、これが安全上重要な飛行ソフトウェアである場合、sqrtに負の値を送信することに対する保護がなければ、人々は著者の訴訟を全面的に覆います。通常、_rsq = a*a + b*b_の計算と平方根の抽出は、複数のコード行で区切られます。その間、宇宙線はrsqの符号ビットを反転できます。

実際、フライトソフトウェアはhandle_this_impossible_event()に相当するものを複数回呼び出しています。通常、これには、制御を冗長コンピューターに切り替えること、疑わしいコンピューターを正常にシャットダウンすること、疑わしいコンピューターを再起動すること、最後に疑わしいコンピューターがバックアップの役割を担うことが含まれます。これは、主な飛行コンピュータがワッコを使用するよりもはるかに優れています。

飛行中のソフトウェアであっても、100%のコードカバレッジを達成することは不可能です。これを達成したと主張する人々は、些細なコードを持っているか、これらの不可能なイベントに対する十分なテストを持っていません。

4
David Hammen

テストカバレッジは、プロジェクトの全体的な状態の有用な指標です。高いテストカバレッジにより、ソフトウェアが展開時に期待どおりに機能するかどうかについて、情報に基づいた決定を行うことができます。テストカバレッジが低い場合は、単に推測しているだけです。カバレッジを自動的に測定するツールが存在します。これらは通常、デバッグコンテキストでプログラムを実行するか、実行されたコードに簿記操作を挿入することで機能します。

テストにはさまざまな種類があり、カバレッジメトリックにはさまざまな種類があります。一般的なカバレッジメトリックには、関数カバレッジ、ステートメントカバレッジ、分岐カバレッジ、および条件カバレッジが含まれますが、 more があります。

  • ユニットテストは、1つの概念的なユニット(モジュール、クラス、メソッドなど)の実装がその仕様に準拠しているかどうかをチェックします(TDDでは、テストは仕様です )。独自の単体テストのないユニットは危険フラグですが、統合スタイルのテストでカバーされる可能性があります。

    ユニットテストは、ほぼ完全な関数カバレッジを意味する必要があります。ユニットテストはそのユニットのパブリックインターフェイス全体を実行するため、これらのテストに影響されない機能はありません。既存のコードベースに単体テストを導入する場合、関数カバレッジは大まかな進捗インジケーターです。

    単体テストでは、ステートメントのカバレッジ(75%〜100%)が十分にカバーされるようにする必要があります。ステートメントカバレッジは、単体テストの品質指標です。総カバレッジは常に可能であるとは限らず、95%を超えてカバレッジを改善するよりも、時間をより有効に活用することができます。

    分岐と条件のカバレッジはよりトリッキーです。 1つのコードが複雑または重要になるほど、これらのメトリックは高くなります。しかし、目立たないコードの場合は、ステートメントのカバレッジが十分である傾向があります(すでにブランチカバレッジが少なくとも50%であることを意味します)。 1つのユニットの状態カバレッジレポートを確認すると、より適切なテストケースを構築するのに役立ちます。

  • 統合テストでは、複数のユニットが互いに正しく動作するかどうかを確認します。統合テストは、カバレッジメトリックを高く評価しなくても非常に便利です。統合テストは通常​​、ユニットのインターフェースの大部分を実行します(つまり、高い機能カバレッジを持ちます)が、これらのユニットの内部はすでにユニットテストでカバーされています。

コードがメインブランチにマージされる前にテストを実行することは良い考えです。ただし、プログラム全体のテストカバレッジメトリックの計算には時間がかかる傾向があります。これは、夜間のビルドに最適なジョブです。これを行う方法を理解できる場合は、Gitフック内の変更されたユニットでのみ変更されたテストまたはユニットテストを実行することをお勧めします。テストの失敗は、「作業中」のコミット以外では受け入れられません。選択したカバレッジメトリックがしきい値を下回った場合(たとえば、ステートメントカバレッジが80%を下回った場合、または対応するテストがない新しいメソッドが導入された場合)、これらの問題は警告として扱い、開発者がこれらの潜在的な問題を修正する機会を得ます。ただし、これらの警告を無視する十分な理由がある場合もあり、開発者もそうできるはずです。

テストは適切ですが、テストが多すぎると煩わしくなります。迅速で適切なフィードバックは品質への注意を促すのに役立ちますが、価値を生み出すのに邪魔をしたくありません。私は個人的に、手動でテストを実行することを好みます。これにより、作業している部分に関するフィードバックを迅速に得ることができます。リリース前に、静的分析、プロファイラー、コードカバレッジツールを使用して問題のあるゾーンを見つけるという品質重視の取り組みを行います(これらの手順の一部はリリース前のテストスイートの一部です)。

4
amon

変異テスト については誰も言及していません。それらの背後にあるアイデアは非常に実用的で直感的です。

それらは、ソースコードをランダムに変更して(例: ">"を "<"に切り替えて)、したがって突然変異を起こし、これらの無計画な変更によってテストが失敗するかどうかを確認します。

そうでない場合は、a)問題のコードは不要であるか、b)(可能性が高い)このコードの一部はテストでカバーされていません。

3
Konrad Morawski

もちろん、コードカバレッジデータは自動的に取得できますが、他の人がすでに説明している理由により、それらに基づいて自動決定を行うことはできません。 (あいまいすぎて、エラーの余地が多すぎます。)

ただし、次善の策は、コードカバレッジに関するプロジェクトの現在の状態が人間によって定期的にチェックされる確立されたプロセスを持っていることです。

エンタープライズ環境では、これは継続的インテグレーション Hudson、Jenkinsなどのツールで実現されます。これらのツールは、ソースコードリポジトリからプロジェクト全体を定期的にチェックアウトし、ビルドして、テストを実行し、レポートを生成します。もちろん、コードカバレッジモードでテストを実行し、これらのレポートに結果を含めるように構成できます。

JetbrainsによってTeamCityも作成されます。これは、私には少し軽量で、小規模なソフトウェアショップに適しているようです。

そのため、プロジェクトマネージャーは定期的にコードカバレッジレポートを受け取り、適切な判断を下し、必要に応じてエンフォーサーとして機能します。

1
Mike Nakis

このためのツールを作成しました

https://github.com/exussum12/coverageChecker

使用する

bin/diffFilter --phpunit diff.txt clover.xml 70

ユニットテストの対象となる差分の70%未満の場合、失敗します。

差分を取得します。

git diff Origin/master... > diff.txt

あなたがマスターから分岐し、マスターに再びマージすると仮定します

コードのphpunitフラグを無視してください。これは実際には単なるクローバーチェックなので、クローバーを出力できるものなら何でも使用できます。

他の回答がこれを100%にすることを提案したので、良い考えではありません

0
exussum

一般的な意見にもかかわらず、RationalのPurifyツールスイートにはコードカバレッジ機能が含まれていますが、コードカバレッジは自動的にチェックできます。それはすべての関数の計測に依存しました(バイナリで機能し、各関数を更新するか、追加のコードで呼び出します)。それにより、ユーザーに表示されるデータを書き出すことができます。特に当時はかなりクールなテクノロジー。

しかし、100%のカバレッジを得るために本当に一生懸命試みたとしても、70%程度しか管理できませんでした。したがって、それは少し無意味な練習です。

ただし、単体テストを作成する状況では、100%の単体テストカバレッジはさらに無意味だと思います。すべてのゲッターやセッターではなく、ユニットテストを必要とするメソッドをユニットテストしてください!ユニットテストは、トリッキーな関数(またはクラスTBH)を検証することであり、ニースの緑色のティックを示すプロセスまたはツールでボックスにチェックを入れないようにする必要があります。

0
gbjbaanb