0
0
JUnittesting~15 mins

Coverage thresholds in JUnit - Build an Automation Script

Choose your learning style9 modes available
Verify code coverage meets minimum thresholds after running unit tests
Preconditions (2)
Step 1: Run all JUnit tests using the build tool (e.g., Maven or Gradle)
Step 2: Generate the code coverage report using JaCoCo
Step 3: Check the coverage report for line coverage percentage
Step 4: Check the coverage report for branch coverage percentage
Step 5: Verify that line coverage is at least 80%
Step 6: Verify that branch coverage is at least 70%
✅ Expected Result: The coverage report shows line coverage >= 80% and branch coverage >= 70%, indicating the code meets the minimum coverage thresholds.
Automation Requirements - JUnit 5 with JaCoCo
Assertions Needed:
Assert line coverage percentage is >= 80%
Assert branch coverage percentage is >= 70%
Best Practices:
Use JaCoCo API or parse coverage report XML programmatically
Fail the test if coverage thresholds are not met
Keep coverage thresholds configurable
Run coverage check as part of automated build
Automated Solution
JUnit
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.junit.jupiter.api.Test;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

public class CoverageThresholdTest {

    private static final double MIN_LINE_COVERAGE = 80.0;
    private static final double MIN_BRANCH_COVERAGE = 70.0;
    private static final String COVERAGE_REPORT_PATH = "target/site/jacoco/jacoco.xml";

    @Test
    public void testCoverageThresholds() throws Exception {
        File xmlFile = new File(COVERAGE_REPORT_PATH);
        assertTrue(xmlFile.exists(), "Coverage report file does not exist: " + COVERAGE_REPORT_PATH);

        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
        Document doc = dBuilder.parse(xmlFile);
        doc.getDocumentElement().normalize();

        // Extract line coverage percentage
        NodeList lineCoverageNodes = doc.getElementsByTagName("counter");
        double lineCoverage = -1;
        double branchCoverage = -1;

        for (int i = 0; i < lineCoverageNodes.getLength(); i++) {
            var node = lineCoverageNodes.item(i);
            var typeAttr = node.getAttributes().getNamedItem("type");
            if (typeAttr != null) {
                String type = typeAttr.getNodeValue();
                if ("LINE".equals(type)) {
                    int covered = Integer.parseInt(node.getAttributes().getNamedItem("covered").getNodeValue());
                    int missed = Integer.parseInt(node.getAttributes().getNamedItem("missed").getNodeValue());
                    int total = covered + missed;
                    lineCoverage = total == 0 ? 100.0 : (covered * 100.0) / total;
                } else if ("BRANCH".equals(type)) {
                    int covered = Integer.parseInt(node.getAttributes().getNamedItem("covered").getNodeValue());
                    int missed = Integer.parseInt(node.getAttributes().getNamedItem("missed").getNodeValue());
                    int total = covered + missed;
                    branchCoverage = total == 0 ? 100.0 : (covered * 100.0) / total;
                }
            }
        }

        assertTrue(lineCoverage >= MIN_LINE_COVERAGE, String.format("Line coverage %.2f%% is below minimum %.2f%%", lineCoverage, MIN_LINE_COVERAGE));
        assertTrue(branchCoverage >= MIN_BRANCH_COVERAGE, String.format("Branch coverage %.2f%% is below minimum %.2f%%", branchCoverage, MIN_BRANCH_COVERAGE));
    }
}

This test reads the JaCoCo XML coverage report generated after running JUnit tests.

It parses the XML to find the counter elements for LINE and BRANCH coverage.

It calculates the coverage percentages by dividing covered by total (covered + missed).

Then it asserts that line coverage is at least 80% and branch coverage is at least 70%.

If the coverage is below thresholds, the test fails with a clear message.

This approach automates coverage verification as part of the test suite, ensuring quality gates are enforced.

Common Mistakes - 4 Pitfalls
Hardcoding coverage percentages inside the test without configuration
Not checking if the coverage report file exists before parsing
Parsing coverage report with brittle XPath or string matching
Ignoring branch coverage and only checking line coverage
Bonus Challenge

Now add data-driven testing with 3 different coverage threshold sets (e.g., 80/70, 85/75, 90/80)

Show Hint