Search code examples
springunit-testinggradletaskgradle-task

How to create a Gradle Task to run only a specific Tests in Spring


I have a Spring Project where I wrote some Unit and Integration Tests. Now I want to create custom tasks for running all unit tests, all integration tests and one task for running both. But how can I do this?


Solution

  • I would suggest separating integration tests into separate source set. By default you already have 2 source sets, one for production code and one for tests. To create a new source set (create new directory under src/integrationTest/java) and add a following configuration using Junit5:

    test {
      useJUnitPlatform()
    }
    
    sourceSets {
      integrationTest {
        java.srcDir file("src/integrationTest/java")
        resources.srcDir file("src/integrationTest/resources")
        compileClasspath += sourceSets.main.output + configurations.testRuntime
        runtimeClasspath += output + compileClasspath
      }
    }
    

    For separate task:

    task integrationTest(type: Test) {
      description = 'Runs the integration tests.'
      group = 'verification'
      testClassesDirs = sourceSets.integrationTest.output.classesDirs
      classpath = sourceSets.integrationTest.runtimeClasspath
    
      useJUnitPlatform()
    
      reports {
        html.enabled true
        junitXml.enabled = true
      }
    }
    

    Now you have 3 tasks available:

    1. gradlew test
    2. gradlew integrationTest
    3. gradlew check - runs both as it depends on Test task which both extend

    If you also are using jacoco and want to merge the test results then you can have following tasks:

    task coverageMerge(type: JacocoMerge) {
      destinationFile file("${rootProject.buildDir}/jacoco/test.exec")
      executionData fileTree(project.rootDir.absolutePath).include("**/build/jacoco/*.exec")
    }
    
    // aggregate all coverage data at root level
    if (tasks.findByName("test")) {
      tasks.findByName("test").finalizedBy coverageMerge
    }
    
    if (tasks.findByName("integrationTest")) {
      tasks.findByName("integrationTest").finalizedBy coverageMerge
    }
    
    task codeCoverageReport(type: JacocoReport) {
      executionData fileTree(project.rootDir.absolutePath).include("**/build/jacoco/*.exec")
      subprojects.each {
        if (!it.name.contains('generated')) {
          sourceSets it.sourceSets.main
        }
      }
      reports {
        xml.enabled true
        html.enabled true
        html.setDestination(new File("${buildDir}/reports/jacoco"))
        csv.enabled false
      }
    }
    

    To run coverage report just execute

    gradlew codeCoverageReport