79108606

Date: 2024-10-21 05:08:25
Score: 2
Natty:
Report link

Not possible (as of now, and hopefully in future too). But I have an alternate way of doing this.

Jacoco has a goal to create an aggregated report for multi module projects, but it doesn't create a jacoco.exec file which is required for checking the coverage metrics.

One way is to create the aggregated report using report-aggregate goal, and separately generate jacoco.exec files for each module and then combine it using jacoco-merge goal.

However this method is not that great as it only cover the direct code coverage. e.g. -> Suppose your module A has some tests which covers some lines of code in module B, in this case merge will not consider this module level differences, it is because you are first generating module level exec file and then merging it into one.

I found a better approach for this check at an aggregate level. This doesn't require any exec files, you can do it using the report-aggregate goal only!! If you have noticed the report-aggregate goal do creates html, xml and csv files for the aggregated report, we can simple scrape data from these files and write our validations!

Here is what I have implemented using XML file

        <plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <version>${jacoco-maven-plugin.version}</version>
            <executions>
                <execution>
                    <id>prepare-agent</id>
                    <goals>
                        <goal>prepare-agent</goal>
                    </goals>
                </execution>
                <!--  Aggregate the report after tests run -->
                <execution>
                    <id>report-aggregate</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>report-aggregate</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>
                            ${project.basedir}/target/jacoco-reports
                        </outputDirectory>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>1.6.0</version>
            <executions>
                <execution>
                    <phase>verify</phase>
                    <goals>
                        <goal>exec</goal>
                    </goals>
                    <configuration>
                        <executable>python3</executable>
                        <arguments>
                            <argument>check_coverage.py</argument>
                            <argument>${code-coverage-percentage}</argument>
                        </arguments>
                    </configuration>
                </execution>
            </executions>
        </plugin>

check_coverage.py

import xml.etree.ElementTree as ET
import sys

# Path to the JaCoCo XML report file
jacoco_report_file = 'target/jacoco-reports/jacoco.xml'

# Get the required coverage from the command-line argument
try:
    required_coverage = float(sys.argv[1])  # Pass as first argument
except IndexError:
    print("Usage: python check_coverage.py <required_coverage>")
    sys.exit(1)
except ValueError:
    print("Invalid value for required coverage, please provide a numeric value.")
    sys.exit(1)


try:
    # Parse the XML file
    tree = ET.parse(jacoco_report_file)
    root = tree.getroot()

    # Find the line coverage data
    counter = root.findall(".//counter[@type='LINE']")
    if not counter:
        print("Could not find line coverage data in the JaCoCo report.")
        exit(1)

    # Pick the last occurrence
    last_counter = counter[-1]

    # Extract the 'missed' and 'covered' values from the XML
    missed = int(last_counter.get('missed', 0))
    covered = int(last_counter.get('covered', 0))
    print(missed)
    print(covered)

    # Calculate the total lines and the line coverage percentage
    total_lines = missed + covered
    if total_lines == 0:
        print("No lines were executed or missed, cannot calculate coverage.")
        exit(1)

    line_coverage = (covered / total_lines) * 100

    # Output the calculated coverage
    print(f"Line Coverage: {line_coverage:.2f}%")

    # Check if the coverage meets the required threshold (e.g., 80%)
    # required_coverage = 80.0  # Set your desired threshold here
    if line_coverage < required_coverage:
        print(f"Coverage is below the required threshold of {required_coverage}%.")
        exit(1)
    else:
        print("Coverage meets the required threshold.")
        exit(0)

except FileNotFoundError:
    print(f"JaCoCo aggregate report not found at {jacoco_report_file}.")
    exit(1)

except ET.ParseError as e:
    print(f"Error parsing the JaCoCo XML report: {e}")
    exit(1)

Simply adjust code-coverage-percentage according to your requirement.

VIOLA!

Reasons:
  • RegEx Blacklisted phrase (2.5): please provide
  • Long answer (-1):
  • Has code block (-0.5):
  • Low reputation (1):
Posted by: SAMEER KUMAR