Bird
Raised Fist0
JUnittesting~15 mins

Coverage thresholds in JUnit - Build an Automation Script

Choose your learning style10 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

Practice

(1/5)
1. What is the main purpose of setting coverage thresholds in JUnit testing?
easy
A. To automatically fix bugs in the code
B. To speed up test execution time
C. To ensure a minimum percentage of code is tested
D. To generate user interface reports

Solution

  1. Step 1: Understand coverage thresholds

    Coverage thresholds define the minimum amount of code that must be tested to pass.
  2. Step 2: Identify the main goal

    The goal is to keep tests thorough by enforcing minimum test coverage.
  3. Final Answer:

    To ensure a minimum percentage of code is tested -> Option C
  4. Quick Check:

    Coverage thresholds = minimum tested code [OK]
Hint: Coverage thresholds set minimum tested code percentage [OK]
Common Mistakes:
  • Thinking thresholds speed up tests
  • Believing thresholds fix bugs automatically
  • Confusing thresholds with report generation
2. Which of the following is the correct way to set a line coverage threshold of 80% using JaCoCo in a Maven pom.xml?
easy
A. <rule><limit><counter>LINE</counter><value>COVEREDRATIO</value><minimum>0.8</minimum></limit></rule>
B. <rule><limit><counter>LINE</counter><value>MISSEDCOUNT</value><maximum>0.8</maximum></limit></rule>
C. <rule><limit><counter>BRANCH</counter><value>COVEREDRATIO</value><minimum>80</minimum></limit></rule>
D. <rule><limit><counter>LINE</counter><value>COVEREDCOUNT</value><minimum>0.8</minimum></limit></rule>

Solution

  1. Step 1: Identify correct counter and value

    For line coverage, the counter is LINE and the value to check coverage ratio is COVEREDRATIO.
  2. Step 2: Check threshold value format

    Minimum coverage is set as a decimal ratio (0.8 for 80%).
  3. Final Answer:

    Rule with LINE counter, COVEREDRATIO value, and minimum 0.8 -> Option A
  4. Quick Check:

    Line coverage threshold = 0.8 COVEREDRATIO [OK]
Hint: Use LINE + COVEREDRATIO + minimum 0.8 for 80% threshold [OK]
Common Mistakes:
  • Using MISSEDCOUNT instead of COVEREDRATIO
  • Setting minimum as 80 instead of 0.8
  • Confusing BRANCH counter with LINE
3. Given the following JaCoCo coverage report snippet:
{"LINE": {"covered": 40, "missed": 10}}

What is the line coverage ratio, and does it meet a threshold of 85%?
medium
A. Coverage is 75%, which does not meet the 85% threshold
B. Coverage is 75%, which meets the 85% threshold
C. Coverage is 80%, which meets the 85% threshold
D. Coverage is 80%, which does not meet the 85% threshold

Solution

  1. Step 1: Calculate coverage ratio

    Total lines = covered + missed = 40 + 10 = 50. Coverage ratio = 40 / 50 = 0.8 or 80%.
  2. Step 2: Compare with threshold

    Threshold is 85%, coverage is 80%, so coverage does not meet threshold.
  3. Final Answer:

    Coverage is 80%, which does not meet the 85% threshold -> Option D
  4. Quick Check:

    40/50 = 0.8 < 0.85 [OK]
Hint: Divide covered by total lines, compare to threshold [OK]
Common Mistakes:
  • Adding covered and missed incorrectly
  • Confusing coverage percentage with missed percentage
  • Assuming 80% meets 85% threshold
4. You set a branch coverage threshold of 90% in your JaCoCo config, but the build passes even when coverage is 85%. What is the most likely cause?
medium
A. The JaCoCo plugin is not configured to fail the build on threshold violation
B. The threshold value is set as maximum instead of minimum
C. Branch coverage cannot be enforced with JaCoCo
D. The threshold is set on LINE coverage, not BRANCH coverage

Solution

  1. Step 1: Understand threshold enforcement

    Thresholds require configuration to fail the build if coverage is below minimum.
  2. Step 2: Identify common misconfiguration

    If the build passes despite low coverage, likely the fail-on-violation setting is missing or disabled.
  3. Final Answer:

    JaCoCo plugin not configured to fail build on threshold violation -> Option A
  4. Quick Check:

    Fail build setting missing = threshold ignored [OK]
Hint: Fail build must be enabled to enforce coverage thresholds [OK]
Common Mistakes:
  • Confusing LINE and BRANCH counters
  • Setting maximum instead of minimum threshold
  • Believing branch coverage can't be enforced
5. You want to enforce multiple coverage thresholds in your JUnit project using JaCoCo: 85% line coverage and 75% branch coverage. Which configuration snippet correctly enforces both thresholds?
hard
A. <rules> <rule><limit><counter>LINE</counter><value>COVEREDCOUNT</value><minimum>85</minimum></limit></rule> <rule><limit><counter>BRANCH</counter><value>COVEREDCOUNT</value><minimum>75</minimum></limit></rule> </rules>
B. <rules> <rule> <limits> <limit><counter>LINE</counter><value>COVEREDRATIO</value><minimum>0.85</minimum></limit> <limit><counter>BRANCH</counter><value>COVEREDRATIO</value><minimum>0.75</minimum></limit> </limits> </rule> </rules>
C. <rules> <rule><limit><counter>LINE</counter><value>MISSEDCOUNT</value><maximum>0.15</maximum></limit></rule> <rule><limit><counter>BRANCH</counter><value>MISSEDCOUNT</value><maximum>0.25</maximum></limit></rule> </rules>
D. <rules> <rule><limit><counter>LINE</counter><value>COVEREDRATIO</value><minimum>0.75</minimum></limit></rule> <rule><limit><counter>BRANCH</counter><value>COVEREDRATIO</value><minimum>0.85</minimum></limit></rule> </rules>

Solution

  1. Step 1: Check counters and values

    Use LINE and BRANCH counters with COVEREDRATIO values for coverage percentages.
  2. Step 2: Verify minimum thresholds and structure

    Minimum values must be decimals (0.85 and 0.75) inside a single rule with multiple limits.
  3. Final Answer:

    Rules with LINE and BRANCH counters, COVEREDRATIO values, minimum 0.85 and 0.75 -> Option B
  4. Quick Check:

    Multiple limits in one rule with correct decimals [OK]
Hint: Use multiple limits inside one rule with decimals for thresholds [OK]
Common Mistakes:
  • Using COVEREDCOUNT with integer minimums instead of decimals
  • Swapping threshold values between LINE and BRANCH
  • Splitting limits into separate rules incorrectly
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard