当前位置: 首页 > 知识库问答 >
问题:

Jacoco代码覆盖率:不存在静态块显示只有75%的覆盖率

沈飞跃
2023-03-14

我在类BrickSortPar并行中有两个静态方法。它们完全由单元测试覆盖。但是我有一个静态块静态{...}列出了Jacoco仅75%的代码覆盖率。那意味着什么?


public static int computeOddTaskCount(int length) {
    if (length < 0) throw new IllegalArgumentException("Illegal argument value: " + length);
    return isOdd(length) ? length >> 1 : abs(length - 1) >> 1;
  }

  public static int computeEvenTaskCount(int length) {
    if (length < 0) throw new IllegalArgumentException("Illegal argument value: " + length);
    return length >> 1;
  }

以下是确保上述方法的完整代码覆盖率的测试用例:

class ComputeTaskCountTest {

private static final String ZERO_TASKS_EXPECTED = "Zero tasks expected.";
  private static final String ONE_TASK_EXPECTED = "One task expected.";
  private static final String HALF_TASKS_EXPECTED = "Half tasks expected.";
  private static final String ILLEGAL_LENGTH_EXPECTED = "Illegal length expected.";

    @Test
    @DisplayName("BrickSortParallelTest.ComputeTaskCountTest.testZeroLength")
    void testZeroLength() {
      assertEquals(0, computeOddTaskCount(0), ZERO_TASKS_EXPECTED);
      assertEquals(0, computeEvenTaskCount(0), ZERO_TASKS_EXPECTED);
    }

    @Test
    @DisplayName("BrickSortParallelTest.ComputeTaskCountTest.testMinusOneLength")
    void testMinusOneLength() {
      assertThrows(
          IllegalArgumentException.class, () -> computeOddTaskCount(-1), ILLEGAL_LENGTH_EXPECTED);
      assertThrows(
          IllegalArgumentException.class, () -> computeEvenTaskCount(-1), ILLEGAL_LENGTH_EXPECTED);
    }

    @Test
    @DisplayName("BrickSortParallelTest.ComputeTaskCountTest.testMinusTwoLength")
    void testMinusTwoLength() {
      assertThrows(
          IllegalArgumentException.class, () -> computeOddTaskCount(-2), ILLEGAL_LENGTH_EXPECTED);
      assertThrows(
          IllegalArgumentException.class, () -> computeEvenTaskCount(-2), ILLEGAL_LENGTH_EXPECTED);
    }

    @Test
    @DisplayName("BrickSortParallelTest.ComputeTaskCountTest.testMinValueLength")
    void testMinValueLength() {
      assertThrows(
          IllegalArgumentException.class,
          () -> computeOddTaskCount(Integer.MIN_VALUE),
          ILLEGAL_LENGTH_EXPECTED);
      assertThrows(
          IllegalArgumentException.class,
          () -> computeEvenTaskCount(Integer.MIN_VALUE),
          ILLEGAL_LENGTH_EXPECTED);
    }

    @Test
    @DisplayName("BrickSortParallelTest.ComputeTaskCountTest.testOneValueLength")
    void testOneValueLength() {
      assertEquals(0, computeOddTaskCount(1), ZERO_TASKS_EXPECTED);
      assertEquals(0, computeEvenTaskCount(1), ZERO_TASKS_EXPECTED);
    }

    @Test
    @DisplayName("BrickSortParallelTest.ComputeTaskCountTest.testTwoValueLength")
    void testTwoValueLength() {
      assertEquals(0, computeOddTaskCount(2), ZERO_TASKS_EXPECTED);
      assertEquals(1, computeEvenTaskCount(2), ONE_TASK_EXPECTED);
    }

    @Test
    @DisplayName("BrickSortParallelTest.ComputeTaskCountTest.testThreeValueLength")
    void testThreeValueLength() {
      assertEquals(1, computeOddTaskCount(3), ONE_TASK_EXPECTED);
      assertEquals(1, computeEvenTaskCount(3), ONE_TASK_EXPECTED);
    }

    @Test
    @DisplayName("BrickSortParallelTest.ComputeTaskCountTest.testFourValueLength")
    void testFourValueLength() {
      assertEquals(1, computeOddTaskCount(4), ONE_TASK_EXPECTED);
      assertEquals(2, computeEvenTaskCount(4), "Two tasks expected");
    }

    @Test
    @DisplayName("BrickSortParallelTest.ComputeTaskCountTest.testMaxValueLength")
    void testMaxValueLength() {
      assertEquals(
          Integer.MAX_VALUE / 2, computeOddTaskCount(Integer.MAX_VALUE), HALF_TASKS_EXPECTED);
      assertEquals(
          Integer.MAX_VALUE / 2, computeEvenTaskCount(Integer.MAX_VALUE), HALF_TASKS_EXPECTED);
    }

    @Test
    @DisplayName("BrickSortParallelTest.ComputeTaskCountTest.testMaxValueLengthEven")
    void testMaxValueLengthEven() {
      assertEquals(
          (Integer.MAX_VALUE - 2) / 2,
          computeOddTaskCount(Integer.MAX_VALUE - 1),
          HALF_TASKS_EXPECTED);
      assertEquals(
          (Integer.MAX_VALUE - 1) / 2,
          computeEvenTaskCount(Integer.MAX_VALUE - 1),
          HALF_TASKS_EXPECTED);
    }
  }

我在上面的测试课上遗漏了什么吗?

完整的课程可在:

https://raw.githubusercontent.com/Fernal73/DSAlgos/master/src/test/java/ds/tests/BrickSortParallelTest.java

https://raw.githubusercontent.com/Fernal73/DSAlgos/master/src/main/java/ds/BrickSortParallel.java

$ java --version
openjdk 11.0.8 2020-07-14
OpenJDK Runtime Environment (build 11.0.8+10)
OpenJDK 64-Bit Server VM (build 11.0.8+10, mixed mode)

Jacoco版本:0.85

从报告中可以看出,静态块的圈复杂度为2,并且只覆盖了一个分支,这意味着缺少一个测试用例来覆盖这种可能性。

共有1个答案

贺兴昌
2023-03-14

引用马克·霍夫曼在Jacoco Github上的话:

msgstr"您的代码使用断言关键字,这将导致静态初始化:

static {};
  descriptor: ()V
  flags: (0x0008) ACC_STATIC
  Code:
    stack=1, locals=0, args_size=0
       0: ldc           #72                 // class ds/BrickSortParallel
       2: invokevirtual #73                 // Method java/lang/Class.desiredAssertionStatus:()Z
       5: ifne          12
       8: iconst_1
       9: goto          13
      12: iconst_0
      13: putstatic     #31                 // Field $assertionsDisabled:Z
      16: return
    LineNumberTable:
      line 19: 0
    StackMapTable: number_of_entries = 2
      frame_type = 12 /* same */
      frame_type = 64 /* same_locals_1_stack_item */
        stack = [ int ]

这是一个已知的限制。解决方法是不使用断言。"

下面的代码片段解决了这个难题:


  @Generated
private void assertEquality(int  size, int count) {
if (size != count)
 throw new AssertionError("Size is not the same as count.");
    }

它抛出AssertionError,但生成的@注释满足了代码覆盖率要求。然而,这是一个解决办法。解决方案是等待Jacoco在字节码中提供所需的断言过滤。

筛选断言是一项正在进行的工作。

 类似资料:
  • Jacoco插件在jenkins报告中显示0%的覆盖率,但当我在本地系统中运行相同的命令时,Jacoco会正确生成报告。我正在使用以下命令: mvn-s xyz/settings.xml-f xyz/xyz/pom.xml清洁安装org.jacoco 所以当我在jenkins中运行这个命令时,它会生成错误的报告。我已经检查了它在工作区目录对应的项目在詹金斯。它显示每个项目的0%覆盖率。但是当我在本

  • 我看到詹金斯插件中的代码覆盖率为零。我在客户端服务器模式下使用 Jacoco 0.8.7。客户端是詹金斯,服务器(此处存在jaco代理jar)是一个VM。当我使用旧版本的jaco 0.7.4时,这并没有发生。 Jenkins CI日志- Jenkins CI插件配置是这样的。使用ant和maven组合来转储exec文件。

  • 我在声纳中的代码覆盖率显示为0%,这不是真的,因为我有单元测试。 格拉德尔 当我打开inside然后我可以看到成功的单元测试。 我在Jenkins环境中运行作为

  • 我的代码运行在具有单独JVM的单独虚拟机上。我想在此虚拟机上以tcpserver模式设置JaCoCo代理以收集覆盖率数据。然后,我将在我的maven项目中以tcpclient模式设置JaCoCo代理,以连接到上面提到的VM并获取覆盖率数据。 问题是代理不收集任何覆盖数据。在中创建了覆盖率数据文件,但该文件为空。 下面是代理选项:-Java agent:/usr/xx/plugins/org . j

  • 我正在尝试使用JaCoCo-javaagent传递VM参数来获得代码覆盖率 -Java agent:/test/jaco co/jaco agent . jar = dest file =/test/jaco co/jaco co . exec,includes=com。*,append=true 我能在jacoco中获得一些价值。执行文件,但无法获取覆盖率报告。我怎样才能把jacoco转化成。执

  • 我正在尝试生成Jacoco代码覆盖率报告。我已经将AndroidTestCase用于我的测试类。 在过去几天里,我已经关注了堆栈溢出的各种公认答案。结果是否定的。 我的分级文件: