使用assertTrue而不是assertNull时缺少分支 [英] Missing branches when using assertTrue instead of assertNull

查看:235
本文介绍了使用assertTrue而不是assertNull时缺少分支的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Java/Junit中,我需要使用某些对象测试null.我可以通过多种方式测试条件,但是大多数测试都使用assertTrue.当我在assertTrue中检查null时,EclEmma指出它仅测试一个分支.

In Java/Junit, I need to test for null with some object. There are a variety of ways I can test a condition but I have been using assertTrue for most of my tests. When I check for nulls in an assertTrue, EclEmma states that it is only testing one branch.

当我手动将语句解析为变量时(例如将结果设置为布尔值并将其传递到assertTrue中),代码覆盖被视为在assert上完成,而不在变量初始化行上完成.

When I resolve the statement into a variable manually (like setting the result to a boolean and passing it into assertTrue) the code coverage is deemed complete on the assert but not on the variable initializing line.

为什么会这样?这是否与Java显然添加的额外字节代码有关,如 http://sourceforge所述. net/apps/trac/eclemma/wiki/FilteringOptions ?任何解决方案(除了使用其他assert语句之外).

Why is this happening? Is this related to the extra byte code that Java apparently adds as mentioned on http://sourceforge.net/apps/trac/eclemma/wiki/FilteringOptions? Any solutions (besides using other assert statements).

assertTrue:

assertTrue( myObject == null ); //1 of 2 branches

assertTrue:

boolean test = (myObject == null); //1 of 2 branches missing
assertTrue(test); // complete

assertNull:

assertNull( myObject ) //complete;

推荐答案

对于大多数布尔表达式,Java编译器会在字节码中生成额外的分支. JaCoCo根据生成的字节码(而不是原始Java代码)生成分支覆盖率",因此会显示几乎所有您将使用的布尔表达式的附加分支覆盖率信息.

For most Boolean expressions, the Java compiler generates extra branches in the byte code. JaCoCo produces "branch coverage" based on the generated byte code, not based on the original Java code, and hence shows additional branch coverage information for almost any Boolean expression you would use.

在您的代码中,您使用的布尔表达式为myObject == null.

In your code, the Boolean expression you use is myObject == null.

为计算该值,Java编译器生成代码,将代码推入堆栈中的两个参数,然后进行条件跳转,以将1(真)或0(假)推入堆栈. JaCoCo报告了此条件跳转的分支覆盖范围.

To compute this value, the Java compiler generates code pushing the two arguments on the stack, and then doing a conditional jump in order to push 1 (true) or 0 (false) on the stack. JaCoCo reports the branch coverage of this conditional jump.

因此,您使用myObject == null的事实会触发您描述的行为.

Thus, the fact that you use myObject == null triggers the behavior you describe.

作为其他示例,请尝试以下操作:

As some other examples, try this:

boolean t = true;
boolean f = false;
boolean result1 = (t && f) || f; // 3 out of 6 missed.
boolean result2 = !t;            // 1 out of 2 missed.

例如,如果布尔表达式由某个函数返回,则该函数将很有用,该函数在其他地方的if-then-else语句中用作条件.尽管这主要是Java编译器工作方式的结果,但它有助于评估原始Java代码的 condition 覆盖率(而不是单纯的 branch 覆盖率).

This can be useful if the Boolean expression is, for example, returned by a function, which is used as condition in an if-then-else statement somewhere else. While mostly a consequence of the way the Java compiler works, it helps to assess condition coverage (instead of mere branch coverage) of the original Java code.

此功能的文档记录不多,但是这里有一些提示:

This feature isn't too well documented, but here are some pointers:

  • The JaCoCo test cases for Boolean Expressions
  • A JaCoCo forum discussion on branches generated for the statement a = !a
  • does anyone have a pointer to more documentation?

实际上,这与生成额外的字节代码有关,但与旨在过滤选项的合成字节编译器结构的特定示例无关.

So it is, indeed, related to the extra byte code is generated, but not to the specific examples of synthetic byte compiler constructs for which the filtering options are intended.

注意:自最初的回答以来,是否进行过重大编辑,这是一个很大的猜测.感谢@ ira-baxter的出色表现& ;;批判性讨论.

NOTE: Did major EDIT since initial answer was too much of a guess. Thanks to @ira-baxter for good & critical discussion.

这篇关于使用assertTrue而不是assertNull时缺少分支的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆