【问题标题】:How Cobertura identify the branches in the code?Cobertura 如何识别代码中的分支?
【发布时间】:2017-08-25 04:57:37
【问题描述】:

我正在用我的代码测试 cobertura 并生成了一份简单的报告。理解那里显示的数字有点问题。

只有一个类,内容如图所示。 我写的测试如下,

public class AppTest {
    @Before
    public void before() {

    }

    @Test
    public void addShouldReturnTheSumOfTwoIntegersWhenFirstIsLessThan100() {
        Assert.assertTrue(65 == App.add(20, 45));
    }

    @Test
    public void addShouldReturnMinusOneWhenFirstIsGreaterThan200() {
        Assert.assertTrue(-1 == App.add(250, 45));
    }
}

如图所示,有4 分支。有人能解释一下这个数字是4 吗?

更新:

当我只有以下测试用例时,

@Test
public void addShouldReturnMinusOneWhenFirstIsGreaterThan200() {
    Assert.assertTrue(-1 == App.add(250, 45));
}

输出,

当我完成所有 3 个测试时,

@Test
public void addShouldReturnTheSumOfTwoIntegersWhenFirstIsLessThan100() {
    Assert.assertTrue(65 == App.add(20, 45));
}

@Test
public void addShouldReturnMinusOneWhenFirstIsGreaterThan200() {
    Assert.assertTrue(-1 == App.add(250, 45));
}

@Test
public void addShouldReturn200WhenFirstIsGreaterThan100AndLessThan200() {
    Assert.assertTrue(200 == App.add(120, 45));
}

输出,

当我有 return 200 分支的以下测试用例时,

@Test
public void addShouldReturn200WhenFirstIsGreaterThan100AndLessThan200() {
    Assert.assertTrue(200 == App.add(120, 45));
}

输出,

更新 2:

如果我有一个测试用例来检查第一个if 子句,

@Test
public void addShouldReturnTheSumOfTwoIntegersWhenFirstIsLessThan100() {
    Assert.assertTrue(65 == App.add(20, 45));
}

输出,

我认为只有这个测试用例没有涵盖隐藏分支。但是下面的任何其他分支也将覆盖神秘分支。

更新 3:

使用javap -c App.class后,

Compiled from "App.java"
public class com.vnb.play_cobertura.play_cobertura.App {
public com.vnb.play_cobertura.play_cobertura.App();
Code:
   0: aload_0
   1: invokespecial #1                  // Method java/lang/Object."<init>":
()V
   4: return

  public static int add(int, int);
Code:
   0: iload_0
   1: bipush        100
   3: if_icmpge     10
   6: iload_0
   7: iload_1
   8: iadd
   9: ireturn
  10: iload_0
  11: sipush        200
  14: if_icmpge     21
  17: sipush        200
  20: ireturn
  21: iconst_m1
  22: ireturn
}

反编译输出,

package com.vnb.play_cobertura.play_cobertura;

public class App
{
  public App() {}

  public static int add(int a, int b)
  {
    if (a < 100)
      return a + b;
    if (a < 200) {
      return 200;
    }
    return -1;
  }
}

【问题讨论】:

  • 尝试使用预期的输出添加App.add(120, 45) 的测试。只是猜测,但我想你会得到6/6
  • @JimGarrison 我这样做了,然后就是 4/4。到目前为止,我可以识别 3 个分支。我为这些写了 3 个案例,问题是另一个是什么?无论如何,另一个通过了。
  • 显然您没有测试return 200 分支。如果您测试了所有三个,请显示实际代码和 Cobertura 输出。
  • @JimGarrison 完成,请检查更新后的问题。
  • 如果有 Cobertura 论坛和/或错误跟踪器,我会从那里开始。这可能是一个错误。您可以查看javap 的输出,看看生成的代码中是否存在隐藏分支。

标签: java cobertura


【解决方案1】:

基于javap 输出,指令3 和14 处有分支。每个分支都由cobertura 独立评估。由于每个分支可以有两种不同的结果,因此 cobertura 为您的方法总共计算了 4 条路径。

一般来说,cobertura 或任何其他工具无法找到分支之间的所有依赖关系。所以这就是为什么那些工具甚至不尝试这样做的原因。

编译器将您的代码转换为更像这样的代码(注意第二个 if 之前缺少的 else):

if (a < 100) {
    return a + b;
}
if (a < 200) {
    return 200;
}
return -1;

【讨论】:

  • 所以你的意思是 cobertura 不会考虑 return 声明?反编译后的代码看起来很相似。
  • @prime 是的,我就是这个意思。
猜你喜欢
  • 1970-01-01
  • 2012-11-21
  • 1970-01-01
  • 2014-06-22
  • 2010-10-08
  • 1970-01-01
  • 1970-01-01
  • 2010-12-07
  • 2023-03-16
相关资源
最近更新 更多