Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JUnit5 tag-specific gradle task

Tags:

gradle

junit5

I use the following annotation to tag my integration tests:

@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Tag("integration-test")
public @interface IntegrationTest {
}

This is the filter I use in build.gradle to exclude these tests from gradle build:

junitPlatform {
    filters {
        tags {
            exclude 'integration-test'
        }
    }
}

So far, so good.

Now I would like to offer a Gradle task which specifically runs my integration tests – what's the recommended approach?

like image 806
Rahel Lüthy Avatar asked Nov 30 '16 15:11

Rahel Lüthy


People also ask

How do you use tags in JUnit?

Annotation Type Tag@Tag is a repeatable annotation that is used to declare a tag for the annotated test class or test method. Tags are used to filter which tests are executed for a given test plan. For example, a development team may tag tests with values such as "fast" , "slow" , "ci-server" , etc.

Is Jupiter a junit5?

JUnit Jupiter is the combination of the programming model and extension model for writing tests and extensions in JUnit 5.

What is useJUnitPlatform?

useJUnitPlatform() Specifies that JUnit Platform should be used to discover and execute the tests.


3 Answers

Based on https://github.com/gradle/gradle/issues/6172#issuecomment-409883128

Amended in 2020 to take lazy task configuration and Gradle 5 into account. See answer's history for older versions.

plugins {
    id "java"
}

def test = tasks.named("test") {
    useJUnitPlatform {
        excludeTags "integration"
    }
}

def integrationTest = tasks.register("integrationTest2", Test) {
    useJUnitPlatform {
        includeTags "integration"
    }
    shouldRunAfter test
}

tasks.named("check") {
    dependsOn integrationTest
}

Running

  • gradlew test will run tests without integration
  • gradlew integrationTest will run only integration test
  • gradlew check will run test followed by integrationTest
  • gradlew integrationTest test will run test followed by integrationTest
    note: order is swapped because of shouldRunAfter

History

  • Gradle 4.6+ supports JUnit 5 natively
  • JUnit 5 deprecated their plugin: https://github.com/junit-team/junit5/issues/1317
  • JUnit 5 deleted plugin: 'org.junit.platform.gradle.plugin'
  • JUnit 5 closed junit5#579 (same as OP's question) as won't-fix (due to decommissioning their plugin)
  • Gradle supports the above feature: https://github.com/gradle/gradle/issues/6172

Tip

Note: while the above works, IntelliJ IDEA has a hard time inferring stuff, so I suggest to use this more explicit version where everything is typed and code completion is fully supported:

... { Test task ->
    task.useJUnitPlatform { org.gradle.api.tasks.testing.junitplatform.JUnitPlatformOptions options ->
        options.includeTags 'integration'
    }
}

build.gradle.kts

Root project Kotlin DSL drop-in for configuring integration tests in all modules in Gradle 5.6.4

allprojects {
    plugins.withId("java") {
        @Suppress("UnstableApiUsage")
        [email protected] {
            val test = "test"(Test::class) {
                useJUnitPlatform {
                    excludeTags("integration")
                }
            }
            val integrationTest = register<Test>("integrationTest") {
                useJUnitPlatform {
                    includeTags("integration")
                }
                shouldRunAfter(test)
            }
            "check" {
                dependsOn(integrationTest)
            }
        }
    }
}
like image 138
TWiStErRob Avatar answered Sep 27 '22 00:09

TWiStErRob


I filed an issue: https://github.com/junit-team/junit5/issues/579 (as suggested by Sam Brannen).

Meanwhile, I am using a project property as a workaround:

junitPlatform {
    filters {
        tags {
            exclude project.hasProperty('runIntegrationTests') ? '' : 'integration-test'
        }
    }
}

Consequently, integrations tests will be skipped with:

gradle test

but will be included with:

gradle test -PrunIntegrationTests

like image 30
Rahel Lüthy Avatar answered Sep 25 '22 00:09

Rahel Lüthy


Gradle 6

I am not sure if it is because Gradle behavior has changed, but the highest voted answer did not work for me in Gradle. 6.8.3. I was seeing the integrationTests task run along with the main test task. This simplified version worked for me:

test {
    useJUnitPlatform {
        excludeTags "integration"
    }
}

tasks.register("integrationTests", Test) {
    useJUnitPlatform {
        includeTags "integration"
    }
    mustRunAfter check
}

Commands:

  • ./gradlew test or ./gradlew clean build - Runs tests without 'integration' tag.
  • ./gradlew integrationTests - Only runs test with 'integration' tag.
like image 23
etech Avatar answered Sep 27 '22 00:09

etech