Blog Post

Setting up Codecov with Java and Gradle

January 26, 2023 Tom Hu

Codecov, Java, and Gradle

Java, developed in 1995, is one of the most popular programming languages in the world. This article will walk you through an example Java project with Gradle to get up and running with testing and code coverage. You can view the entire source code of this post at our example repository.

For our project, we will be using Java 18. You will need to create a new public repository in GitHub. You should also go ahead and create a Codecov account.

Getting started with Java

We will start with a simple calculator app that exposes two methods: add and subtract off of a Calculator class. Both functions accept two doubles and return a double. We can paste the code below into the file src/main/java/calculator/Calculator.java

package calculator;

public class Calculator {
  public static double add(double x, double y) {
    return x + y;
  }

  public static double subtract(double x, double y) {
    return x - y;
  }
}

Now, let’s add a test for our add function.

src/test/java/calculator/CalculatorTest.java

package calculator;

import static org.junit.Assert.assertEquals;

import org.junit.Test;

public class CalculatorTest {
  private static final double DELTA = 0.001;

  @Test
  public void testAdd() {
    assertEquals(Calculator.add(1, 2), 3.0, DELTA);
  }
}

To run our tests, we will be taking advantage of the junit package. We will also need to update our build.gradle file and build out the testing infrastructure to use junit

build.gradle

group 'io.codecov'
version '1.0'

apply plugin: 'java'

sourceCompatibility = 18
targetCompatibility = 18

repositories {
    mavenCentral()
}

dependencies {
    testImplementation "junit:junit:4.13"
}

Run your tests and get coverage

To run our test, in a terminal, call gradle build This should bring the following output.

--> gradle build
Starting a Gradle Daemon (subsequent builds will be faster)

BUILD SUCCESSFUL in 6s
4 actionable tasks: 4 executed

To get coverage results, we will need to add the jacoco plugin.

Update build.gradle to match below

group 'io.codecov'
version '1.0'

apply plugin: 'java'
apply plugin: 'jacoco'

sourceCompatibility = 18
targetCompatibility = 18

repositories {
    mavenCentral()
}

dependencies {
    testImplementation "junit:junit:4.13"
}

jacocoTestReport {
    reports {
        xml.enabled true
        html.enabled enabled
    }
}

check.dependsOn jacocoTestReport

Re-run gradle build to view coverage information.

--> bundle install && rake test
Fetching gem metadata from https://rubygems.org/..
…
--> gradle build

Deprecated Gradle features were used in this build, making it incompatible with Gradle 8.0.

You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.

See https://docs.gradle.org/7.5.1/userguide/command_line_interface.html#sec:command_line_warnings

BUILD SUCCESSFUL in 1s
5 actionable tasks: 5 executed

You will notice a new build directory which holds coverage information. For the human-readable html version, open build/reports/jacoco/test/html/index.html in a browser.

You can view the coverage for the individual file by clicking into it.

Although coverage says 36%, this is due to total missed instructions. Our true coverage is 33.3% as there is 1 covered line return x + y; for the 3 statements.

How to upload to Codecov

Now that we are able to collect coverage locally, let’s learn how to upload these reports to Codecov. Codecov is a code coverage tool that provides reports on how much of a project’s codebase is tested. It is often used in conjunction with continuous integration (CI) systems to ensure that new code changes are adequately covered by tests.

We will be using GitHub Actions as the Ci and the Codecov Action to upload coverage reports.

Create a file called .github/workflows/ci.yml.

name: Workflow for Codecov example-java-gradle
on: [push, pull_request]
jobs:
  run:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Set up JDK 18
        uses: actions/setup-java@v1
        with:
          java-version: 18
      - name: Install dependencies, run tests, and collect coverage
        run: gradle build
      - name: Upload coverage to Codecov
        uses: codecov/codecov-action@v3

It is recommended that you install the Codecov app for this repository to prevent rate-limiting issues. Save your code and push up to GitHub.

git checkout -b 'initial-commit'
git add .
git commit -m 'Initial commit and upload coverage to Codecov'
git push origin initial-commit

In GitHub, open the pull request and wait for CI and Codecov to finish running and analyzing. You should see the following pull request commit.

You should also see four status checks, two of which come from Codecov.

Our documentation contains more information on the meaning of each status check. When you are ready, merge the pull request.

Covering uncovered code

Now that we can get coverage data in our pull request. Let’s take a look at how to increase coverage.

Let’s take a look at the coverage report from Codecov. Navigate to your repository from the Codecov UI. You should see a dashboard like this.

Notice that there is only 1 covered line in the Code tree. If we click on src/main/java/calculator/Calculator.java,

From this view, we can tell that we haven’t written a test for our subtract function!

Create a new branch in your terminal

git checkout main
git pull
git checkout -b 'subtract-test'

and update the test file with the following code below the add test.

  @Test
  public void testSubtract() {
    assertEquals(Calculator.subtract(1, 2), -1.0, DELTA);
  }

Save the code and open a new pull request.

git add .
git commit -m 'fix: add tests for subtract fn'
git push origin subtract-test

Notice the Codecov comment shows the coverage increasing from 33.33% to 66.66%.

Advanced Codecov configurations

Now that you have uploaded your first Java coverage reports successfully to Codecov, you can check out some of our other features including

Before we redirect you to GitHub...
In order to use Codecov an admin must approve your org.