βGrading test coverage with JaCoCo
Writing good unit tests is a skill students need to develop, which means you need a way to grade the tests they write β not just whether they pass, but how thoroughly they exercise the code. JaCoCo is a Java code coverage library that measures what percentage of a reference implementation is exercised by a set of unit tests. The higher the coverage, the more of the reference code the student's tests are touching.
This guide walks through uploading a reference implementation alongside the JaCoCo jars, running the student's tests under the JaCoCo agent, and converting the resulting coverage data into a numeric grade.
This guide covers a scenario where students write the tests and you grade them against a reference implementation you provide. For the opposite scenario β instructor-written tests grading student code β see JUnit5 guide.
Before you start
You will need the following files ready to upload:
jacocoagent.jarβ the JaCoCo Java agent. Attached to the JVM with-javaagent, it instruments classes at runtime and records which lines are executed.jacococli.jarβ the JaCoCo command-line tool. It converts the raw coverage data into an XML report that can be graded.cov_grade.shβ a shell script that reads the XML report and prints a numeric grade for the rubric. See the Appendix for the full script.Your reference implementation (e.g.
Calculator.java).
Both JaCoCo jars can be downloaded from the official JaCoCo release page.
Step 1: Install the JUnit console launcher
JaCoCo instruments the JVM directly, so the standard cg junit5 helpers cannot be used here. Instead, download the JUnit5 platform console launcher jar from Maven Central during Setup.
Navigate to the Setup tab under the AutoTest settings and install JUnit5.

Navigate to the Test tab and add an Allow Internet block.
Add a Script block inside the Allow Internet block and paste the following:
The Allow Internet block is required in Test because curl needs to reach Maven Central. Renaming the jar drops the version number so the rest of your scripts can reference a stable path.
Step 2: Compile the student's tests against a reference implementation
In Tests tab, add an Upload Files block and attach
jacocoagent.jar,jacococli.jar,cov_grade.sh, and your reference implementation (e.g.Calculator.java).Add a Connect Rubric block and select the appropriate rubric category from the drop-down menu.
Add a Script block nested inside the Connect Rubric block and paste the following:
Moving the uploaded files into the working directory first ensures that the compiler and the JaCoCo jars can all find each other on the classpath.
Step 3: Run the tests under JaCoCo and grade the coverage
This step uses two Custom Test blocks nested inside the same Connect Rubric block from Step 2.
Custom Test 1 β Run student unit tests
Add a Custom Test block and paste the following:
The -javaagent flag attaches the JaCoCo agent to the JVM, which instruments the reference implementation's classes at runtime and writes the raw coverage data to jacoco.exec. cg unit-tests parses the JUnit XML output so pass/fail information appears in the submission view.
Custom Test 2 β Grade code coverage
Add a second Custom Test block immediately after and paste the following:
The directory structure (src, tests, compiled) is required by JaCoCo's report command. Skipping or renaming these folders will cause the report step to fail.
Conclusion
You have set up an automatically graded assignment that measures how thoroughly students test a reference implementation. For background on standard instructor-written JUnit 5 tests, or for adding Checkstyle to your Java assignments, see the guides below. For questions about custom grading scripts or coverage thresholds, reach out to our support team at [email protected].
Appendix: cov_grade.sh
The script below parses the JaCoCo XML report and outputs a line coverage grade as a fraction (e.g. 3/4). CodeGrade uses this fraction to award rubric points proportionally. If LINE coverage data is not present in the report, the script falls back to INSTRUCTION coverage. If the XML cannot be parsed at all, it returns a grade of 0/1.
The script expresses the grade as an exact fraction (e.g. 7/10) rather than a percentage. CodeGrade reads this fraction directly to calculate rubric points, so the output format must not be changed.
When LINE coverage data is absent from the report β which can happen with certain JVM configurations β the script automatically falls back to INSTRUCTION coverage. Both metrics are present in every standard JaCoCo XML report.
If the XML file cannot be parsed (for example because the JaCoCo agent failed to write jacoco.exec), the script returns 0/1 rather than exiting with an error, so the AutoTest run completes and the student receives a zero for the coverage category instead of a broken result.
Last updated