JUnit 5 Tutorial: Running Unit Tests With Gradle

This blog post describes how we can create a Gradle project that can compile and run unit tests which use JUnit 5. After we have finished this blog post, we:

  • Can get the required dependencies with Gradle
  • Understand how we can use the Gradle's native JUnit 5 support.
  • Can run our unit tests with Gradle.

Let’s start by creating a Java project.

Creating a Java Project

We can create a Java project by applying the Java plugin. After we have applied this plugin, the source code of our build.gradle file looks as follows:

plugins {
    id  'java'
}

Next, we will find out how we can get the required dependencies with Gradle.

Getting the Required Dependencies

We can get the required dependencies by following these steps:

First, ensure that Gradle uses the Maven central repository when it resolves the dependencies of our Gradle build. After we have configured the used Maven repository, our build.gradle file looks as follows:

apply plugin: 'java'

repositories {
    mavenCentral()
}

Second, add the junit-jupiter (version 5.8.2) dependency to the testImplementation dependency configuration. This is an aggregator artifact which simplifies the dependency management because it has the following transitive dependencies:

  • The junit-jupiter-api dependency (testImplementation dependency configuration) provides the public API for writing tests and extensions.
  • The junit-jupiter-params dependency (testImplementation dependency configuration) provides support for writing parameterized tests.
  • The junit-jupiter-engine dependency (testRuntimeClasspath dependency configuration) contains the implementation of the JUnit Jupiter test engine that runs our unit tests. If we add this dependency to our classpath, we can run our tests by leveraging the Gradle's native JUnit 5 support if we are using Gradle 4.6 or newer.

After we have declared the required dependencies, our build.gradle file looks as follows:

apply plugin: 'java'

repositories {
    mavenCentral()
}

dependencies {
    testImplementation('org.junit.jupiter:junit-jupiter:5.8.2')
}
The testImplementation dependency configuration is a new dependency configuration that replaced the testCompile dependency configuration. If you want to get more information about this dependency configuration, you should take a look at this StackOverflow answer.

Let's move on and find out how we can enable the Gradle's native JUnit 5 support.

Enabling the Gradle's Native JUnit 5 Support

Even though Gradle (version 4.6 or newer) has a native support for JUnit 5, this support isn't enabled by default. If we want to enable it, we have to ensure that the test task uses JUnit 5 instead of JUnit 4.

After we have enabled the Gradle's native JUnit 5 support, the source code of our build.gradle file looks as follows:

plugins {
    id  'java'
}

repositories {
    mavenCentral()
}

dependencies {
    testImplementation('org.junit.jupiter:junit-jupiter:5.8.2')
}

test {
    useJUnitPlatform()
}

We have now created a Gradle project that can run unit tests which use JUnit 5. Next, we will write a simple unit test with JUnit 5.

Writing a Simple Test Class

Before we can write unit tests which use JUnit 5, we have to know these two things:

  • The src/test/java directory contains the source code of our unit tests.
  • The src/test/resources directory contains the resources of our unit tests.

Let's create a new test class and add one test method to the created class. This test method simply writes a message to System.out. The source code of our test class looks as follows:

import org.junit.jupiter.api.Test;

class JUnit5ExampleTest {

    @Test
    void justAnExample() {
        System.out.println("This test method should be run");
    }
}
If you want to get more information about JUnit 5 test classes, you should read this blog post. Also, we shouldn't write tests which write messages to System.out. I use this technique here only because it's an easy way to verify that our test method is run.

Let's move on and find out how we can run our unit tests.

Running Unit Tests With Gradle

We can run our unit tests with Gradle by using the following command: gradle clean test. When we run this command at command prompt, we see that Gradle runs our unit tests:

$ gradle clean test

> Task :test

net.petrikainulainen.junit5.JUnit5ExampleTest > justAnExample() STANDARD_OUT
This test method should be run
By default, the test task doesn't show the information written to System.out or System.err. If we want to show this information, we can make the required changes to the configuration of the test task by following the instructions given in the blog post: Show Standard Out or Error Output from Tests.

We can now create a Gradle project that compiles and runs unit tests which use JUnit 5. Also, we know how we can run our unit tests with Gradle. Let's summarize what we learned from this blog post.

Summary

This blog post has taught us five things:

  • The junit-jupiter-api dependency provides the public API that allows us to write tests and extensions which use JUnit 5.
  • The junit-jupiter-engine dependency allows us to run tests which use JUnit 5 with Gradle.
  • The junit-jupiter dependency is an aggregator artifact which simplifies the dependency management because it ensures that the required dependencies are found from the classpath.
  • Gradle has a native support for JUnit 5, but this support isn't enabled by default.
  • We can run our unit tests by using the command: gradle clean test.

P.S. You can get the example application of this blog post from Github.

17 comments… add one
  • Stefan Nov 21, 2017 @ 15:39

    Hi Petri,

    thanks for this great article. I just try to get different test source sets used by the junit5-gradle-plugin, but unforunately tests in a new source set integration-tests won't get executed.
    Do you plan to provide an update of the setup for Gradle using JUnit 5? Maybe as an update of your article "getting-started-with-gradle-integration-testing"?
    Thanks in advance
    Stefan

    • Stefan Nov 21, 2017 @ 16:06

      This Stack Overflow article seems to go in the right direction, but I didn't get it running ...
      https://stackoverflow.com/questions/45297339/junit-5-under-gradle-with-multiple-source-sets
      Stefan

      • Stefan Nov 21, 2017 @ 18:11

        No it works:

        task integrationTest(
        type: JavaExec,
        description: 'Runs the integration tests.',
        group: 'Verification'
        ) {
        dependsOn testClasses
        mustRunAfter junitPlatformTest

        classpath = sourceSets.integrationTest.runtimeClasspath
        main = 'org.junit.platform.console.ConsoleLauncher'
        args = ['--scan-class-path',
        sourceSets.integrationTest.output.getClassesDirs().asPath,
        '--reports-dir', "${buildDir}/test-results/junit-e2e"]
        }
        check.dependsOn integrationTest

        With dependency

        testRuntime("org.junit.platform:junit-platform-console:$junitPlatformVersion")

        Stefan

        • Petri Nov 21, 2017 @ 20:35

          Hi Stefan,

          First, it's good to hear that you were able to solve your problem while I was working. Also, thank you for posting your solution here. I am going to write a blog post about this in the future. This post will probably be a part of my JUnit 5 tutorial, but I have to also admit that I will probably wait until Gradle releases the official JUnit 5 support because I think that it will make things a bit easier.

  • Amin Jan 27, 2018 @ 16:28

    That was very helpful. thank you :)

    • Petri Jan 27, 2018 @ 23:59

      You are welcome!

  • dwette Mar 20, 2018 @ 22:51

    This is no longer needed. Gradle 4.6 supports JUnit5 natively, with:

    
    test { useJunitPlatform() }
    
    
    • Petri Mar 21, 2018 @ 9:13

      Good catch! I will add a note about this to the beginning of this blog post. I will update this blog post eventually, but I hope that the note will help people to avoid any extra work. By the way, thank you for reminding me about this.

  • Mikhail Nov 8, 2018 @ 20:33

    Thanks for very great article. It helped me a lot!

    • Petri Nov 14, 2018 @ 21:12

      You are welcome. I am happy to hear that this blog post was useful to you.

  • Leandro Apr 26, 2019 @ 17:01

    Thanks!! Finally I got my configuration to work!

    • Petri Dec 6, 2019 @ 21:38

      You are welcome.

  • Shri Ram Dec 5, 2019 @ 7:30

    Thank you so much. It works for me.

    • Petri Dec 6, 2019 @ 21:38

      You are welcome!

  • John Apr 23, 2020 @ 11:22

    Thanks, it works! Congratulations.

Leave a Reply to Shri RamCancel reply