简体   繁体   English

为什么 Intellij 代码覆盖率和 jacoco 代码覆盖率显示不同的百分比?

[英]Why do Intellij code coverage and jacoco code coverage show different percentages?

I have a gradle project(java) in intellij.我在 intellij 中有一个 gradle 项目(java)。 I right clicked the project in intellij and ran Run Tests in projectName with coverage which created some test report on right hand side.我右键单击 intellij 中的项目并Run Tests in projectName with coverage在右侧创建了一些测试报告。 In that right hand side I have numbers like在右手边,我有类似的数字

| Class, %   | Method, %   | Line, %
--------------------------------------
80%(80/100)  50%(100/200)  30%(30/100)

Note: The above numbers are just for example.注:以上数字仅为示例。 These are not real.这些都不是真的。

Now I went to command line and ran gradlew jacocoTestReport which gave a different set of numbers for Method and Line, but Class numbers were same .现在我转到命令行并运行gradlew jacocoTestReport ,它为 Method 和 Line 提供了一different set of numbers ,但Class numbers were same Why is there a discrepancy in this case?为什么在这种情况下会出现差异?

Is there a way to run intellij's code coverage from command line instead of right clicking?有没有办法从命令行运行intellij的代码覆盖而不是右键单击?

I just want to know if Intellij uses a different way to calculate these numbers as opposed to jacoco.我只想知道 Intellij 是否使用与 jacoco 不同的方法来计算这些数字。 But even in that case my assumption is that there is only one way to calculate stuff right?但即使在那种情况下,我的假设是只有一种计算方法,对吗? Or does intellij or jacoco doesn't count classes that has Lombok annotations etc thereby reducing the number of methods(getters and setters) in the final count?还是 intellij 或 jacoco 不计算具有 Lombok 注释等的类,从而减少最终计数中的方法(getter 和 setter)数量?

I stumbled over this question on a related mission and although it's old, I figure it may still be interesting to someone.我在一个相关任务中偶然发现了这个问题,虽然它很旧,但我认为它可能对某些人来说仍然很有趣。

Method numbers方法编号

The main question is if the intellij coverage and jacoco calculate the numbers differently, and which way is correct.主要问题是intellij覆盖率和jacoco计算数字是否不同,哪种方式是正确的。 Brief answer: The intellij coverage summary uses the methods directly supplied by the developer, while jacoco operates on bytecode level and displays the number of methods found there.简要回答:intellij 覆盖摘要使用开发人员直接提供的方法,而 jacoco 在字节码级别上运行并显示在那里找到的方法的数量。 To demonstrate this, I created a simple class with four methods:为了证明这一点,我用四种方法创建了一个简单的 class:

public class Exp {

    private final LinkedList<Integer> vals = new LinkedList<>();

    public void addVal(int v) {
        vals.add(v);
    }

    public List<Integer> doubled() {
        return vals.stream().map(x -> x*2).collect(Collectors.toList());
    }

    public List<Integer> evens() {
        return vals.stream().filter(x -> x%2 == 0).collect(Collectors.toList());
    }

    public static void main(String[] args) {
        Exp t = new Exp();

        t.addVal(1);
        t.addVal(2);
        t.addVal(3);

        System.out.println(t.doubled());
        System.out.println(t.evens());
    }
}

In the intellij summary displays the following values on the right:在 intellij 摘要中,右侧显示以下值:

intellij 覆盖摘要

So the number of methods equals the number of methods in the example code.所以方法的数量等于示例代码中的方法数量。 Jacoco reports seven methods, as can be seen in the report (same as in the Emma plugin in eclipse 2020-09): Jacoco 报告了七种方法,在报告中可以看到(与 eclipse 2020-09 中的 Emma 插件相同): 雅可可测试报告

This is the number of methods we can find in the bytecode, eg by using the javap disassembler command.这是我们可以在字节码中找到的方法的数量,例如通过使用 javap 反汇编命令。 Here we see that the two lambda expressions are implemented as methods of the class, and also a standard constructor is inserted.这里我们看到两个 lambda 表达式被实现为 class 的方法,并且还插入了一个标准构造函数。

C:\_workspace\intellij\Tests\out\production\mod>javap -p Exp.class
Compiled from "Exp.java"
public class Exp {
  private final java.util.LinkedList<java.lang.Integer> vals;
  public Exp();
  public void addVal(int);
  public java.util.List<java.lang.Integer> doubled();
  public java.util.List<java.lang.Integer> evens();
  public static void main(java.lang.String[]);
  private static boolean lambda$evens$1(java.lang.Integer);
  private static java.lang.Integer lambda$doubled$0(java.lang.Integer);
}

What puzzles me a little is that the intellij coverage report (Run->Generate Corevage Report) displays five methods:让我有点疑惑的是,intellij 覆盖率报告(Run->Generate Corevage Report)显示了五种方法:

Intellij 覆盖率报告

Adding a standard constructor to the code and re-generating the report reveals that the report included the generated standard constructor, but not the lambda expressions.将标准构造函数添加到代码并重新生成报告显示报告包含生成的标准构造函数,但不包含 lambda 表达式。 There seems to be an intermediate counting method.似乎有一种中间计数方法。

As for the question if intellij or jacoco is right I would say that they both are, it's just a question of definition.至于intellij或jacoco是否正确的问题,我想说他们都是,这只是一个定义问题。

Line numbers行号

In my tests all reports displayed consistent line numbers.在我的测试中,所有报告都显示一致的行号。 In the example above 13 lines containing executable code were reported.在上面的示例中,报告了包含可执行代码的 13 行。 My impression of the intellij line count in the coverage summary is that it does not refresh properly all the time.我对覆盖摘要中的 intellij 行数的印象是它不会一直正确刷新。 A clean rebuild may have been necessary.可能需要进行干净的重建。

I noticed that the @Test annotation I was using came from org.junit.jupiter.api.Test which wasnt being picked up by Jacoco.我注意到我使用的 @Test 注释来自org.junit.jupiter.api.Test没有被 Jacoco 接收。 Changing the import to import org.junit.Test fixed my coverage issue.将导入更改为import org.junit.Test修复了我的覆盖问题。

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

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