Search code examples
jacocojacoco-maven-plugin

What does JaCoCo rule elements mean and how to combine them


I'm trying to understand JaCoCo rules but there are not many great examples around. Every thread I see circulates the same examples from the docs.

I see 3 different metrics:

  • element types (BUNDLE, PACKAGE, CLASS, SOURCEFILE or METHOD)
  • limits (INSTRUCTION, LINE, BRANCH, COMPLEXITY, METHOD, CLASS)
  • values (TOTALCOUNT, COVEREDCOUNT, MISSEDCOUNT, COVEREDRATIO, MISSEDRATIO)

I understand that "element types" represent the scope of each rule, fair enough.

  • BUNDLE: That represents the project as a whole
  • PACKAGE: Each java package
  • CLASS: As name states, a single class
  • SOURCEFILE: How is this different than the CLASS? Does this have to do with inner classes?
  • METHOD: Scope is for each method

Now though, how limits and values come into scope? For example:

<limit>
    <counter>LINE</counter>
    <value>COVEREDRATIO</value>
    <minimum>80%</minimum>
</limit>

can I replace LINE with INSTRUCTION for example? And if yes, what does this mean?

Also from the docs:

If a limit refers to a ratio it must be in the range from 0.0 to 1.0 where the number of decimal places will also determine the precision in error messages.

RATIO vs COUNT is clear, but can I use them interchangeably? i.e:

<limit>
    <counter>LINE</counter>
    <value>TOTALCOUNT</value>
    <minimum>3</minimum>
</limit>

and if yes, what does the above rule mean? From a generated report, INSTRUCTION and BRANCH are always on ratio jacoco report


Solution

  • So, a part of this question regarding BUNDLE, SOURCEFILE, and CLASS just got answered here in the JaCoCo groups.

    Essentially,

    • BUNDLE - All classes in the Maven module combined together will be checked against the rule
    • SOURCEFILE - Each Java file will be checked against the rule
    • CLASS - Each Class file will be checked against the rule

    The confusion starts for SOURCEFILE and CLASS, but you need to understand that a Java file can have multiple classes. For example, here is Shape.java which has 2 classes - Shape and Triangle.

    public abstract class Shape {
    }
    
    class Triangle extends Shape {
    }
    

    SOURCEFILE will check the rules against Shape.java, while CLASS with check the rule against both Shape and Triangle.

    For instance, here is a rule configuration

    <rule>
        <element>SOURCEFILE</element><!-- Here I change it for SOURCEFILE and CLASS values -->
        <limits>
            <limit>
                <counter>INSTRUCTION</counter>
                <value>TOTALCOUNT</value>
                <maximum>1</maximum>
            </limit>
        </limits>
    </rule>
    

    Below is the output for SOURCEFILE config.

    [WARNING] Rule violated for source file io/codejournal/maven/jacocodemo/Shape.java: instructions total count is 6, but expected maximum is 1
    

    When you run the same thing with CLASS config, the output is for each class separately.

    [WARNING] Rule violated for class io.codejournal.maven.jacocodemo.Triangle: instructions total count is 3, but expected maximum is 1
    [WARNING] Rule violated for class io.codejournal.maven.jacocodemo.Shape: instructions total count is 3, but expected maximum is 1