简体   繁体   English

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

[英]Jacoco code coverage: non-existent Static block shows only 75% coverage

I have two static methods in the class BrickSortParallel.我在 BrickSortParallel 类中有两个静态方法。 They are fully covered by unit tests.它们被单元测试完全覆盖。 But I have a static block static {...} listed with only 75% code coverage by Jacoco.但是我有一个静态块static {...}列出了 Jacoco 只有 75% 的代码覆盖率。 What does that signify?这意味着什么?

覆盖范围截图


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;
  }

Following are test cases to ensure full code coverage for above methods:以下是确保上述方法的完整代码覆盖率的测试用例:

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);
    }
  }

Am I missing anything in the above test class?我在上面的测试课中遗漏了什么吗?

The full classes are available at:完整课程可在以下位置获得:

https://raw.githubusercontent.com/Fernal73/DSAlgos/master/src/test/java/ds/tests/BrickSortParallelTest.java 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 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 version: 0.85 Jacoco 版本:0.85

From the report, the static block has a cyclomatic complexity of 2 and with only one branch covered, that implies there's a test case missing to cover that eventuality .从报告中可以看出,静态块的圈复杂度为 2,并且只覆盖了一个分支,这意味着缺少一个测试用例来覆盖该事件

To quote Marc R Hoffman on Jacoco Github : 在 Jacoco Github 上引用Marc R Hoffman 的话

"Your code uses the assert keyword which results in a static initializer: “您的代码使用 assert 关键字,这会导致静态初始化程序:

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 ]

This is a know limitation.这是一个已知限制。 The workaround is to not use assert."解决方法是不使用断言。”

The following code snippet resolves the conundrum:下面的代码片段解决了这个难题:


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

It throws AssertionError and yet code coverage requirements are satisfied by the @Generated annotation.它抛出 AssertionError 并且@Generated注释满足代码覆盖率要求。 It is, however, a workaround.但是,这是一种解决方法。 The solution is to wait for Jacoco to provide the needed filtering of assertions in the byte code.解决方案是等待 Jacoco 在字节码中提供所需的断言过滤。

Filtering assertions is a work in progress .过滤断言是一项正在进行的工作

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM