Skip to content

Managing Testing

Estimated time to read: 4 minutes

Overview

Most, if not all, projects will have tests assigned to them, these tests are typically parsed using JUnit 4 / 5.

By default, Gradle looks within src/test/java for Java tests, this can be modified if needed.

Test builds are output to build/classes/test.

Test reports are output to build/reports/test.

Adding JUnit to a project

Dependency

To set up testing, a dependency needs to be added to a project and the scope needs to be set to testImplementation. For example, for JUnit add the following;

build.gradle
testImplementation("junit:junit:4.12")

Test Block

The test block element can be used to specify any configuration for tests. The testLogging element is used to specify what is displayed when a test is run / its outcome.

build.gradle
test {
 testLogging {
  events TestLogEvent.FAILED,
      TestLogEvent.PASSSED,
      TestLogEvent.SKIPPED
 }
}

Testing with JUnit 4

Test for a project are stored in src/test/java/<tld>/<domain>/<package>/*

JUnit, or an alternative testing library, are added as dependencies to the testImplementation scope for the project.

build.gradle
dependencies {
 testImplementation("junit:junit:4.12")
}

Running Tests

To run tests, the gradle clean build command can be used. Breaking this command down, clean removes any current compiled class and other extraneous data, then build, as well as doing a compilation, also runs check which completes the test tasks.

Verbose test output

By default, testing is not output to the console. However, events can be configured to be written to the output of the gradle command.

  • Two classes need to be imported to enable logging
  • A test element with the testLogging sub-element are added to the build.gradle file

Example

Groovy
build.gradle
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import org.gradle.api.tasks.testing.logging.TestLogEvent

test {
 testLogging {
  events TestLogEvent.FAILED,
      TestLogEvent.PASSED,
      TestLogEvent.SKIPPED
 }
}
Kotlin
build.gradle.kts
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import org.gradle.api.tasks.testing.logging.TestLogEvent

tasks {
 test {
  testLogging.events = setOf(TestLogEvent.FAILED, TestLogEvent.PASSED, TestLogEvent.SKIPPED)
 }
}

Improved Logging

The testlogger plugin can be used to improve the output of tests that have been parsed by Gradle.

Groovy

build.gradle
plugins {
 id 'com.adarshr.test-logger' version '3.2.0' //test-logger is a community plugin
}

testlogger { //test-logger has its own element block for its configuration. The elements below are the DEFAULT values for the configuration if they are not specified. 
    theme 'standard'
    showExceptions true
    showStackTraces true
    showFullStackTraces false
    showCauses true
    slowThreshold 2000
    showSummary true
    showSimpleNames false
    showPassed true
    showSkipped true
    showFailed true
    showOnlySlow false
    showStandardStreams false
    showPassedStandardStreams true
    showSkippedStandardStreams true
    showFailedStandardStreams true
    logLevel 'lifecycle'
}

Kotlin

build.gradle.kts
plugins {
 id("com.adarshr.test-logger") version "3.2.0"
}

tasks {
 testlogger {
 // Configuration is as in the Groovy example
 }
}

Testing with JUnit 5

JUnit 5 interacts with Gradle differently to JUnit 4.

Configuration

Rather than adding a a testlogging task, we instead have to include useJUnitPlatform().

build.gradle.kts
tasks {
 test {
  useJUnitPlatform()
  testLogging.events = setOf(TestLogEvent.FAILED, TestLogEvent.PASSED, TestLogEvent.SKIPPED)
 }
}

Dependencies

JUnit 5 has two dependencies that are required to be added to the project.

Note

These dependencies are applicable to separate scopes.

Groovy

build.gradle
dependencies {
 testImplementation "org.junit.jupiter:junit-jupiter-api:$junit_version" //Double quotes due to reference to a variable
 testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$junit_version"
}

Kotlin

build.gradle.kts
dependencies { 
 testImplementation("org.junit.jupiter:junit-jupiter-api:$junit_version")
 testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:$junit_version")
}

Filtering Tests

Tests can be filtered so that only specific tests are acted upon. This is done by adding a filter element to the test element within the build file. This applies to both JUnit 4 and 5.

Groovy

build.gradle
test {
 filter {
  includeTestsMatching "com.foo.shouldCreateASession" //Tests can be referenced directly
  includeTestsMatching "*shouldCreateASession" //Or they can be referenced via a wildcard (*)
 }
}

Command Line Filtering

Tests can also be run from the command line using the following syntax:

gradle test --tests *shouldCreateASession

Test Tasks

Tests can also be added as tasks in the build file.

JUnit 4

Groovy
build.gradle
tasks.register<Test>("singleTest") {
 group = "Verification"
 description = "Runs a single test"

 dependsOn testClasses

 testLogging {
  events TestLogEvent.FAILED,
      TestLogEvent.PASSED,
      TestLogEvent.SKIPPED
 }

 filter {
  includeTestsMatching (
   "com.foo.package.test.testInputFileExists"
  )
 }
}
Kotlin
build.gradle.kts
tasks.register<Test>("singleTest") {
 group = "Verification"
 description = "Runs a single test"

 dependsOn("testClasses")

 testLogging.events = setOf(TestLogEvent.FAILED, TestLogEvent.PASSED, TestLogEvent.SKIPPED)

 filter {
  includeTestsMatching (
   "com.foo.package.test.testInputFileExists"
  )
 }
}

JUnit 5

Groovy
build.gradle
tasks.register<Test>("singleTest") {
 group = "Verification"
 description = "Runs a single test"

 dependsOn testClasses

 testLogging {
  events TestLogEvent.FAILED,
      TestLogEvent.PASSED,
      TestLogEvent.SKIPPED
 }

 useJUnitPlatform() // This is required for JUnit 5

 filter {
  includeTestsMatching (
   "com.foo.package.test.testInputFileExists"
  )
 }
}
Kotlin
build.gradle.kts
tasks.register<Test>("singleTest") {
 group = "Verification"
 description = "Runs a single test"

 dependsOn("testClasses")

 testLogging.events = setOf(TestLogEvent.FAILED, TestLogEvent.PASSED, TestLogEvent.SKIPPED)

 useJUnitPlatform() // This is required for JUnit 5

 filter {
  includeTestsMatching (
   "com.foo.package.test.testInputFileExists"
  )
 }
}