Dal*_*ght 17 junit code-coverage bytecode emma jacoco
在Java/Junit中,我需要使用某个对象测试null.我可以通过多种方式测试条件,但我一直在使用assertTrue进行大多数测试.当我在assertTrue中检查空值时,EclEmma声明它只测试一个分支.
当我手动将语句解析为变量(比如将结果设置为布尔值并将其传递给assertTrue)时,代码覆盖率在断言上被认为是完整的,而不是在变量初始化行上.
为什么会这样?这是否与Java显然添加的额外字节代码相关,如http://sourceforge.net/apps/trac/eclemma/wiki/FilteringOptions所述?任何解决方案(除了使用其他断言语句).
assertTrue:
assertTrue( myObject == null ); //1 of 2 branches
Run Code Online (Sandbox Code Playgroud)
assertTrue:
boolean test = (myObject == null); //1 of 2 branches missing
assertTrue(test); // complete
Run Code Online (Sandbox Code Playgroud)
assertNull:
assertNull( myObject ) //complete;
Run Code Online (Sandbox Code Playgroud)
ava*_*sen 22
对于大多数布尔表达式,Java编译器在字节代码中生成额外的分支.JaCoCo基于生成的字节代码生成"分支覆盖",而不是基于原始Java代码,因此显示了您将使用的几乎任何布尔表达式的附加分支覆盖信息.
在您的代码中,您使用的布尔表达式是myObject == null.
要计算此值,Java编译器会生成代码,在堆栈上推送两个参数,然后执行条件跳转以便在堆栈上按1(true)或0(false).JaCoCo报告此条件跳转的分支覆盖范围.
因此,您使用的事实myObject == null会触发您描述的行为.
作为其他一些例子,试试这个:
boolean t = true;
boolean f = false;
boolean result1 = (t && f) || f; // 3 out of 6 missed.
boolean result2 = !t; // 1 out of 2 missed.
Run Code Online (Sandbox Code Playgroud)
如果布尔表达式例如由函数返回,则该函数很有用,该函数在其他地方的if-then-else语句中用作条件.虽然这主要是Java编译器工作方式的结果,但它有助于评估原始Java代码的条件覆盖范围(而不仅仅是分支覆盖范围).
这个功能没有太多记录,但这里有一些指示:
a = !a实际上,它与生成额外字节代码有关,但与过滤选项所针对的合成字节编译器结构的具体示例无关.
注意:自初始回答以来主要编辑是否过于猜测.感谢@ ira-baxter的良好和批判性讨论.