Finally JUnit 5 has native support in Gradle

Finally JUnit 5 has native support in Gradle

As promised, this time I am taking a look at the support that is offered for JUnit 5 now that we are more than 6 months past the official release of JUnit 5. If you have read through the process of developing this test suite, you will be aware that I had to use JUnit’s own JUnitPlatform Gradle plugin to run my test suite. This works just fine, but it is clunky, requires a LOT of code and most frustratingly for me, does not support running multiple tests in parallel. With something as slow as Selenium testing, this is a real pain as parallelism allows you to complete your test runs in a significantly reduced time.

Native support for JUnit 5 in Gradle 4.6

I was excited to notice that the latest release of Gradle, version 4.6, has native support for JUnit 5 tests within the standard Java plugin.

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'org.junit.platform:junit-platform-gradle-plugin:1.0.3'
    }
}

apply plugin: 'org.junit.platform.gradle.plugin'

junitPlatform {
    platformVersion '1.0.3'
    reportsDir file('build/test-results/junit-platform')
    enableStandardTestTask true
    //show results summary even on success.
    details details.SUMMARY
    filters {
        tags {
            // Framework tests need to be run only when required to verify that this framework is still working.
            exclude "Framework"
        }
        includeClassNamePatterns '.*Test', '.*Tests'
    }
}

This can be replaced by just configuring the test task as here.

test {
    useJUnitPlatform()
    // use the syntax below to exclude based on filepath
    // exclude(["**/webdriver/*", "**/pagefactory/*"] as List)
    // The syntax below works for Tags - either String names or Tag objects work
    options {
        setExcludeTags(["Framework", "Blocking", "Navigation"] as Set)
    }
    // Finally we have access to parallel running for junit 5 tests!
    maxParallelForks 4
}

A possibly better alternative is to configure this for ALL test tasks using tasks.withType(Test) { .. } instead.

That gives us the full build.gradle:

group 'tech.alexontest'
version '1.0-SNAPSHOT'

apply plugin: 'java'
sourceCompatibility = 1.8
tasks.withType(JavaCompile) {
    options.encoding = "UTF-8"
}

apply plugin: 'checkstyle'
checkstyle {
    final config_loc = 'config/checkstyle'
    // Adding the line below will cause builds to fail on warning as well as error severity violations
    // maxWarnings = 0
    // Removing the line below will not fail the build on violations, only report results.
    ignoreFailures = false
    configFile = rootProject.file("${config_loc}/checkstyle.xml")
    toolVersion = '8.5'
}

repositories {
    mavenCentral()
}

dependencies {
    def final junitVersion = "5.1.0"
    compile group: 'com.google.inject', name: 'guice', version: '4.1.0'
    compile group: 'com.google.code.gson', name: 'gson', version: '2.8.2'
    compile group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: junitVersion
    compile group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '3.11.0'
    compile group: 'org.assertj', name: 'assertj-core', version: '3.9.0'
    compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.7'

    testCompile group: 'org.junit.jupiter', name: 'junit-jupiter-params', version: junitVersion
    testCompile group: 'org.mockito', name: 'mockito-core', version: '2.7.22'

    testRuntime group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: junitVersion
}

test {
    useJUnitPlatform()
    // use the syntax below to exclude based on filepath
    // exclude(["**/webdriver/*", "**/pagefactory/*"] as List)
    // The syntax below works for Tags - either String names or Tag objects work
    options {
        setExcludeTags(["Framework", "Blocking", "Navigation"] as Set)
    }
    // Finally we have access to parallel running for junit 5 tests!
    maxParallelForks 4
}

And there you have it. Much easier to read and more concise. Most importantly it opens up the ability to run test classes in parallel to speed up your testing. Important for something as slow as Selenium UI testing. One other really nice feature is that the tests are also reported in the IDE test window so I have easy visualisation of the results.

Parallel running
Multiple tests at once and displayed in the IDE

Apologies that this post has been so long in the making. Since my last post I have been through the recruitment process from both ends; Interviewing and being interviewed for two companies. I had forgotten how stressful it is, but successfully completely coding tests written for developers has really increased my confidence. Add the fact that I start in my new position next month and it was well worth the effort.

I will be switching from Java to C# .net in my new company, so I think a quick look at using the C# WebDriver bindings might be just what I need to get my head around the language switch. Time to take a deep dive into Jim Evans C# Selenium code and learn from an expert.

Progress made:

  • Upgraded Gradle to version 4.6 with its native support for JUnit 5.
  • Tweaked my Page Block code and added unit tests (a discussion for another post I think.)

Lessons learnt:

  • I’m loving the native support, I’d forgotten how much I missed maxParallelForks from JUnit 4.
  • You get the bonus of a visual report and progress in the IDE even during a Gradle test run.
  • Having a code clean out and update is always a joy for me.
  • Job applications are tiring and stressful, but new opportunities to learn are always welcome for me.
Comments are closed.