Java Coverage
Framework Configuration
Key Requirements
- Coverage report must be in LCOV format
- Report must be saved as
coverage/lcov.info - Report must be uploaded as a GitHub Actions artifact named
coverage-report
JaCoCo is the most popular code coverage tool for Java projects. It integrates seamlessly with Maven and Gradle, generating coverage reports in XML format that can be converted to LCOV for GitAuto compatibility.
Maven Configuration
<project>
<!-- ... other configuration ... -->
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.15</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>Gradle Configuration
plugins {
id 'java'
id 'jacoco'
}
jacoco {
toolVersion = "0.8.15"
}
test {
finalizedBy jacocoTestReport
}
jacocoTestReport {
dependsOn test
reports {
xml.required = true
html.required = true
csv.required = false
}
}
// Configure JaCoCo to generate reports in the correct location
jacocoTestReport {
reports {
xml.enabled true
xml.destination file("${buildDir}/reports/jacoco/test/jacoco.xml")
}
}Setting Up GitHub Actions
Create a workflow file in .github/workflows/ directory. The filename can be anything you prefer (e.g. java-coverage.yml). Add the following content to your workflow file:
name: JaCoCo Coverage
# Run on target branch (probably default branch like main) to track coverage history
on:
push:
branches:
- main
# Optional: Only run when relevant files change (customize as needed)
paths:
- '**/*.java'
- pom.xml
- build.gradle
pull_request:
branches:
- main
paths:
- '**/*.java'
- pom.xml
- build.gradle
- '!.github/workflows/**'
workflow_dispatch:
# Auto-cancel outdated runs on the same branch
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
cancel-in-progress: true
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Set up JDK
uses: actions/setup-java@v5
with:
java-version: '21'
distribution: 'temurin'
- name: Cache Maven packages
uses: actions/cache@v5
with:
path: ~/.m2
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-m2
# PR: tests only, Push: tests with coverage
- name: Run tests
if: github.event_name == 'pull_request'
run: mvn clean test
- name: Run tests with coverage
if: github.event_name == 'push'
run: mvn clean test jacoco:report
- name: Convert JaCoCo XML to Cobertura format
if: github.event_name == 'push'
run: |
curl -o cover2cover.py https://raw.githubusercontent.com/rix0rrr/cover2cover/master/cover2cover.py
python3 cover2cover.py target/site/jacoco/jacoco.xml src/main/java/ > target/site/cobertura.xml
- name: Convert Cobertura to LCOV format
if: github.event_name == 'push'
run: |
pip install lcov_cobertura
mkdir -p coverage
python3 -m lcov_cobertura target/site/cobertura.xml --output coverage/lcov.info --demangle
- name: Upload coverage reports
if: github.event_name == 'push'
uses: actions/upload-artifact@v6
with:
name: coverage-report
path: coverage/lcov.infoKey Configuration Points
- Configure JaCoCo plugin in Maven or Gradle
- Generate XML coverage reports
- Convert JaCoCo XML to LCOV format using a conversion tool
- Upload the report as an artifact - name must be either
coverage-reportor end withlcov.info - Ensure the artifact contains
coverage/lcov.infofile
Why !.github/workflows/** on PRs Only?
On pull requests, we exclude workflow file changes to keep the setup PR minimal. When you're adding or editing a workflow file, pre-existing test failures in your codebase are irrelevant and shouldn't block the PR. On push(after merge to main), we don't exclude them so that the initial coverage report gets generated on your target branch.
Viewing Coverage Reports
After your workflow runs successfully, GitAuto automatically processes the coverage reports and displays them in the Coverage Dashboard. GitAuto only saves coverage data when the workflow runs on your target branch (configurable in your repository's Rules page, defaults to your repository's default branch, e.g., main or master). This typically happens when:
- You merge a pull request to your target branch
- You push directly to your target branch
- You manually trigger the workflow
About LCOV:LCOV (Linux Code Coverage) is a standard format for code coverage data. It's pronounced "el-cov" and is widely supported by various tools and services.
Using multiple languages? If your repository has multiple programming languages (the docs use PHP + JavaScript as an example, but any combination works), see our Multi-Language Coverage guide for setting up coverage across all languages.
JaCoCo Giving You Trouble?
Java coverage can be complex with build tool configurations, multi-module projects, and classpath issues. Whether JaCoCo reports are missing, Maven is acting up, or CI is failing, we've got your back!
Contact us and let's sort out your Java coverage!