6

私はソナーにクラスを持っています:

public class Foo {
..... much code ....
}

そして、ソナーは、その行でカバーされている 1/2 ブランチを報告していpublic class Fooます。これは何を意味するのでしょうか?クラスを宣言する行をどのようにテストしますか?

編集:重要な場合、これはSonar v3.5です。

編集 2: 私が何を意味するかを示すスクリーンショットです。9 行目の「パブリック クラス」の横にある 1/2 に注意してください。

http://img829.imageshack.us/img829/2626/screenshot20130607at120.png

編集#3:わかりました、もう少し調査して、これをトリガーすることができる最小のスニペットに絞り込みました:

public class Foo {

    Foo(final String s) {
        assert (s != null);
    }
}

そのアサートがコンストラクターに存在しない場合、「N/2 ブランチがカバーされています」フラグは Sonar で生成されません。アサートがなくなると、フラグも消えます。それで、コンストラクタ内のブランチに基づいていると思いますか? (このコードには、アサート行でカバーされる分岐が 0/4 あり、パブリック クラス行でカバーされる分岐が 0/2 あります)。

4

2 に答える 2

7

これは、Sonar の JaCoCo コード カバレッジ コンポーネントに関連する問題のようです。JaCoCo は、Java ソースではなく、コンパイルされたバイトコードで動作し、Java コンパイラは、基になるソースに直接関係しないコードを生成できます。

JaCoCoのドキュメントを見ると、次のようなセクションがあります (強調を追加)。

場合によっては、特定の行が強調表示されたり、特定の色になったりする理由が明らかでないことがあります。その理由は、基礎となるコード カバレッジ ライブラリ JaCoCo が Java クラス ファイルでのみ機能するためです。場合によっては、Java コンパイラがソース コードの特定の行に対して余分なバイト コードを作成します。このような状況は、JaCoCo/EclEmma の将来のバージョンでフィルタリングされる可能性があります。

パッセージのリンクをたどると、Jacoco の GH サイトのFilteringOptionsページに移動し、JDK がこれらの「偽の」コード カバレッジ警告をトリガーするコードを生成する可能性のある多くの方法について言及しています。

ただし、それはここで行われていることではありません (正確にはそうではありません)。

前述のように、JaCoCo は Java バイトコードで動作するため、ソースに直接起因しないコンパイラによって生成されたコードはすべてカバレッジにカウントされます。

私の特定のケースでassertは、ソースには、アサートが発生した時点でのブランチを表すだけでなく、「グローバル」レベルでもブランチがありました。Foo上で定義したクラスのバイトコードを見ると( を実行javap -c Foo)、次のように表示されます。

Compiled from "Foo.java"
public class Foo extends java.lang.Object{
static final boolean $assertionsDisabled;

Foo(java.lang.String);
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   getstatic   #2; //Field $assertionsDisabled:Z
   7:   ifne    22
   10:  aload_1
   11:  ifnonnull   22
   14:  new #3; //class java/lang/AssertionError
   17:  dup
   18:  invokespecial   #4; //Method java/lang/AssertionError."<init>":()V
   21:  athrow
   22:  return

static {};
  Code:
   0:   ldc_w   #5; //class Foo
   3:   invokevirtual   #6; //Method java/lang/Class.desiredAssertionStatus:()Z
   6:   ifne    13
   9:   iconst_1
   10:  goto    14
   13:  iconst_0
   14:  putstatic   #2; //Field $assertionsDisabled:Z
   17:  return

行 7 に注意してください。これは、アサーションが有効かどうかに依存する条件分岐です。したがって、プレーンな Java を含むクラスがある場合assert、バイトコードのどこかにこのブランチがあり、これがクラス宣言で「N/2 ブランチが実行されました」というカバレッジ警告を生成するものです。ここで、N は 0 またはクラスがテストによって実行されたことがあるか (1) ないか (0) に応じて 1。

編集:これはhttps://sourceforge.net/apps/trac/eclemma/wiki/FilteringOptionsにも記載されていることに注意してください:

AssertionErrors をスローするブロック - 条件の場合 (!assertion が新しい AssertionError をスローする場合)、ブロック全体を無視する必要があります。

于 2013-06-10T16:58:02.233 に答える