anlar
anlar

Reputation: 607

Execute gradle task after test

After executing test task in Gradle build I want to always execute additional task which should have access to test result. Something like:

task('afterTest') {
    doLast {
        if (testSuccessful) {
            //
        } else {
            //
        }
    }
}

Upvotes: 5

Views: 8928

Answers (3)

hertzsprung
hertzsprung

Reputation: 9893

Building on the existing answers, use org.gradle.api.tasks.testing.Test.afterSuite to save the test result to a file:

test {
  afterSuite { descriptor, result ->
    if (descriptor.parent == null) {
      file("$buildDir/test.result").text = result.resultType
    }
  }
}

afterTest.onlyIf {
  file("$buildDir/test.result").text == 'SUCCESS'
}

where the afterTest task is executed only when the test suite succeeds.

Upvotes: 0

lance-java
lance-java

Reputation: 27984

As I said in the other thread, it's best to use the file system to pass values from one task to another. This way the value will be available even if the test task was up to date and skipped. Eg:

test {
    outputs.file "$buildDir/test.properties"
    ext.errorCount = 0
    afterTest {  desc ,  result  ->
        if (result.resultType.name() == "FAILURE") {
            errorCount++
        }
    }
    doLast {
        file("$buildDir/test.properties").text = "errorCount=$errorCount" 
    } 
    finalizedBy 'afterTest' 
    ignoreFailures = true
}
task afterTest {
    dependsOn 'test' 
    inputs.file "$buildDir/test.properties"
    doLast {
        def props = new Properties() 
        props.load(file("$buildDir/test.properties")) 
        def errorCount = Integer.parseInt(props['errorCount'])
        if (errorCount) {
           // doStuff
           throw new TaskExecutionException("$errorCount tests failed") 
        } 
    } 
} 

Upvotes: 1

M.Ricciuti
M.Ricciuti

Reputation: 12096

There are two parts in your question: 1) make a custom task executed always after test task is executed, 2) make the test "result" available in this custom task.

1) First part is very simple, you just have to use the dedicated Task.finalizedBy method to create a "finalized by" dependency between test task and your custom task. (see Finalizer tasks)

2) Second part is a bit tricky, as there is no simple way provided by Gradle, as far as I know, to get the "result" (SUCCESS or FAILURE) of test task. But you could use API exposed by the Test Task to store the number of test in error into a variable and test this counter in your custom task : here is a working example:

ext{
    // counter of test cases in error
    nbTestOnError = 0
}

test {
    // use "afterTest" hook to increment nbTestOnError   counter
    afterTest {  desc ,  result  ->
        if (result.getResultType().equals(TestResult.ResultType.FAILURE)){
            nbTestOnError++
        }
    }
}

task('afterTest') {
    doLast {
        // implement your logic depending on counter value
        if (nbTestOnError > 0) {
            // do something if test failed
        } else{
            // do something when all tests passed
        }
    }
}

// create "finalized by" dependency
test.finalizedBy afterTest

EDIT : based on important remark in comment from @lance-java : in order to support up-to-date check , you could configure your custom task to be "skipped" if test task is not executed. A simple way would be to use Task upToDateWhen feature (see here) :

task('afterTest') {
    // consider this task "UP TO DATE" if `test` task did not execute
    outputs.upToDateWhen {
        !test.didWork
    }
    doLast {
    //...
    }
}

Upvotes: 9

Related Questions