私はプロジェクトのテストスイートを作成している最中ですが、100%のカバレッジを取得することは、メトリックではないことに気づきました。に、コードカバレッジレポートに奇妙な部分がありますが、それについて説明したいと思います。
スクリーンショットを参照してください:
テストされているメソッドの最後の行はreturn
であるため、最後の行(単なる閉じ括弧)は実行されていないものとして表示され、その結果、メソッド全体が実行されていないというフラグが立てられます。概要。 (または、レポートを正しく読んでいません。)
完全な方法:
static public function &getDomain($domain = null) {
$domain = $domain ?: self::domain();
if (! array_key_exists($domain, self::$domains)) {
self::$domains[$domain] = new Config();
}
return self::$domains[$domain];
}
これには理由がありますか、それともグリッチですか?
(はい、読み通しました PHPUnitで100%のコードカバレッジを取得する方法 、似ていますが異なるケースです。)
編集:
レポートを調べてみると、コードの他の場所にあるswitch
ステートメントにも同じことが当てはまることがわかりました。したがって、この動作は少なくともある程度一貫していますが、それでも私には困惑します。
Edit2:
私が実行しているのは:PHPUnit 3.6.7、PHP 5.4.0RC5、XDebug 2.2.0-OSX上のdev
まず最初に:100%のコードカバレッジは、striveの優れた指標です。かなりの努力で常に達成できるとは限らず、そうすることが常に重要であるとは限りません:)
単純なケースでは、xDebugはその行に到達できないことを通知できるため、100%のコードカバレッジが得られます。
以下の簡単な例を参照してください。
この問題は修正されました xDebug bugtracker
したがって、xDebugの新しいバージョンをビルドするとこれらの問題が解決されます:)
PHP 5.4とxDebugのDEVバージョンを実行しているので、それらをインストールしてテストしました。コメントしたのと同じ出力で、同じ問題が発生します。
問題がxDebugのphp-code-coverage
(phpunitモジュール)に起因するかどうかは100%わかりません。 xDebugdevの問題でもある可能性があります。
php-code-coverage
でバグを報告しました。問題の原因を特定します。
より複雑なケースでは、これ[〜#〜] can [〜#〜]は失敗します。
あなたが示したコードについて、私が言えるのは「それは私のために働く」ということだけです(以下の複雑なサンプル)。
現在のバージョンでは失敗するのを見てきましたが、クラス全体がどのように見えるかによって異なります。
?:
演算子やその他の単一行のマルチステートメントを削除することも役立つ場合があります。
私の知る限り、これらのケースの多くを回避するために、xDebugには継続的なリファクタリングがあります。 xDebugはかつて「ステートメントカバレッジ」を提供できるようにしたいと考えていましたが、それで多くのケースが修正されるはずです。今のところ、ここでできることはあまりありません
//@codeCoverageIgnoreStart
と//@codeCoverageIgnoreEnd
はこの行を「カバー」しますが、それは本当に醜く見え、通常は良いよりも悪いことをしています。
これが発生する別のケースについては、以下の質問と回答を参照してください。
what-to-do-when-project-coding-standards-conflicts-with-unit-test-code-coverage
<?php
class FooTest extends PHPUnit_Framework_TestCase {
public function testBar() {
$x = new Foo();
$this->assertSame(1, $x->bar());
}
}
<?php
class Foo {
public function bar() {
return 1;
}
}
生成:
phpunit --coverage-text mep.php
PHPUnit 3.6.7 by Sebastian Bergmann.
.
Time: 0 seconds, Memory: 3.50Mb
OK (1 test, 1 assertion)
Generating textual code coverage report, this may take a moment.
Code Coverage Report
2012-01-10 15:54:56
Summary:
Classes: 100.00% (2/2)
Methods: 100.00% (1/1)
Lines: 100.00% (1/1)
Foo
Methods: 100.00% ( 1/ 1) Lines: 100.00% ( 1/ 1)
<?php
require __DIR__ . '/foo.php';
class FooTest extends PHPUnit_Framework_TestCase {
public function testBar() {
$this->assertSame('b', Foo::getDomain('a'));
$this->assertInstanceOf('Config', Foo::getDomain('foo'));
}
}
<?php
class Foo {
static $domains = array('a' => 'b');
static public function &getDomain($domain = null) {
$domain = $domain ?: self::domain();
if (! array_key_exists($domain, self::$domains)) {
self::$domains[$domain] = new Config();
}
return self::$domains[$domain];
}
}
class Config {}
生成:
PHPUnit 3.6.7 by Sebastian Bergmann.
.
Time: 0 seconds, Memory: 3.50Mb
OK (1 test, 2 assertions)
Generating textual code coverage report, this may take a moment.
Code Coverage Report
2012-01-10 15:55:55
Summary:
Classes: 100.00% (2/2)
Methods: 100.00% (1/1)
Lines: 100.00% (5/5)
Foo
Methods: 100.00% ( 1/ 1) Lines: 100.00% ( 5/ 5)
ここでの問題の多くは、「ライン」の100%の実行カバレッジを取得することへの主張です。 (マネージャーはこのアイデアが好きです。それは彼らが理解できる単純なモデルです)。多くの行は「実行可能」ではありません(空白、関数宣言間のギャップ、コメント、宣言、「純粋な構文」(スイッチまたはクラス宣言の終了「}」、複数のソース行に分割された複雑なステートメントなど)。
あなたが本当に知りたいのは、「すべての実行可能コードはカバーされていますか?」です。この区別はばかげているように見えますが、解決策につながります。 XDebugは、実行される内容を行番号で追跡するため、XDebugベースのスキームは実行された行の範囲を報告します。そして、このスレッドで説明されている問題が発生します。たとえば、コードに「カウントしないでください」というコメントを付けたり、最後の実行可能ステートメントと同じ行に「}」を付けたりするという厄介な解決策があります。それを維持することは言うまでもなく、それを喜んで行います。
実行可能コードを、条件付き(コンパイラーが「基本ブロック」と呼ぶもの)で呼び出すことができる、または制御するコードとして定義し、カバレッジトラッキングがそのように行われる場合、コードのレイアウトとばかげたケース単に消えます。このタイプのテストカバレッジツールは、いわゆる「ブランチカバレッジ」を収集し、すべての実行可能コードを実行することで、文字通り100%の「ブランチカバレッジ」を取得することも取得しないこともできます。さらに、行内に条件文がある場合( "x?y:z"を使用)、または行内に2つの従来のステートメントがある場合(例:
if (...) { if (...) stmt1; else stmt2; stmt3 }
XDebugは行ごとに追跡するため、これを1つのステートメントとして扱い、実際にテストする5つの部分がある場合でも、制御が行に到達した場合はカバレッジと見なします。
私たちの PHPテストカバレッジツール はこれらのアイデアを実装しています。特に、returnステートメントに続くコードは実行可能ではないことを理解し、空でない場合は実行していないことを通知します。これにより、OPの元の問題はなくなります。 「実際の」カバレッジ数を取得するためにゲームをプレイする必要はもうありません。
すべての選択肢と同様に、マイナス面がある場合もあります。私たちのツールには、Windowsでのみ実行されるコードインストルメントコンポーネントがあります。インストルメント化PHPコードはどこでも実行でき、処理/表示はプラットフォームに依存しないJavaプログラムによって実行されます。したがって、これはOPのOSXシステムにとって厄介かもしれません。インストルメンテーション担当者NFS対応のファイルシステム全体で正常に動作するため、彼は間違いなくPCでインストルメンテーションを実行し、OSXファイルをインストルメントすることができます。
この特定の問題は、カバレッジ数を押し上げようとしている誰かによって引き起こされました。問題は私見人工であり、人工を回避することで解決できます。テストを追加せずに数値をプッシュアップする別の方法があります。それは、重複するコードを見つけて削除することです。重複を削除すると、テストするコードが少なくなり、エフェクトテスト(現在は存在しない他のコピー)で1つの(非)コピーをテストするため、より多くの数を取得しやすくなります。あなたはできる これについてもっと読むここで。
Switchステートメントのコードカバレッジの問題に関しては、何もしない「デフォルト」のケースを追加するだけで、完全なカバレッジが得られます。
Switchステートメントを100%カバレッジにするために行うことは次のとおりです。
存在しないケースを送信するテストが少なくとも1つあることを確認してください。
だから、あなたが持っているなら:
switch ($name) {
case 'terry':
return 'blah';
case 'lucky':
return 'blahblah';
case 'gerard':
return 'blahblah';
}
テストの少なくとも1つが、terry
でもlucky
でもgerard
でもない名前を送信していることを確認してください。