Looking for a way to force a successful Test task to run again on subsequent runs without performing a clean

(Doug Lethin) #1

I have several tasks of Type Test that I have added to my build, like this:

// dynamically build up a testng task for every testng suite found.
// for example testng-unit-test-suite will become a task called runTestSuiteUnit
def testngSuiteTree = fileTree('test/resources/conf/testng').include('testng-*-test-suite.xml')
testngSuiteTree.each { file ->
    def matcher = file.name =~ /testng-(.*)-test-suite.xml/
  def suiteName = matcher[0][1]
  def relativePath = ("${file.path}" =~ /${projectDir}\//).replaceFirst("")
    task "runTestSuite${suiteName.capitalize()}"(type: Test) {
     // need to get relative path
    useTestNG() {
       suites "${relativePath}"

This is working great. The problem is that if my test task succeeds, the task will get marked as ‘UP-TO-DATE’ on subsequent runs and skipped.

Are there suggests on how I can change this behavior such that my Test task will always run, even if a previous build succeeded and nothing changes?



(Doug Lethin) #2

An answer from the man himself… thank you so much. I had to modify the syntax a bit, but you set me in the right direction.

Looks like I need

task ... {
   outputs.upToDateWhen { false }

With that it worked.

BTW… look forward to your talk at the end of November @ Project Automation Experience in Ft. Lauderdale. Just booked last week.

(Hans Dockter) #3

Looking forward to meeting you there. Thanks for the erratum. I have fixed my initial posting.

(Mark Petrovic) #4

Just what I was looking for, as I wish to force integration tests in src/intTest to run without an associated clean. Thanks.

But when I went to read about what

outputs.upToDateWhen { false }

does in the current API docs


I found that getOutputs() is a method on org.gradle.api.internal.AbstractTask, which is a class that has no Javadoc/Groovydoc on the API site.

Where is the documentation on Test.getOutputs() ?

Thank you.

(Mark Petrovic) #5

Incidentally, I have a few subprojects that all have this type of canonical integration-test-like form:

task intTest(type: Test) {

testClassesDir = sourceSets.intTest.output.classesDir

classpath = sourceSets.intTest.runtimeClasspath }

In the parent build.gradle file where allprojects{} is implemented, is there a way I can apply

outputs.upToDateWhen { false }

to each of those intTest tasks?

Thank you.

(Shin Tai) #6

can you search on projects that have a task called intTest?

allprojects {
    configure(tasks.matching { it.name == "intTest" }) {
    outputs.upToDateWhen { false }

I haven’t tested it but my understanding that it’ll go through all projects and configure tasks called inTest.


(Hans Dockter) #7

There might be one problem with the above. It assumes that the intTest tasks are already created. If you do the following, you specify a configuration rule that is either applied to the existing tasks of tasks that will be added in the future:

allprojects {
   tasks.matching { task -> task.name == "intTest" }.all {
      outputs.upToDateWhen { false }

(kambiz shahri) #8

I made not changes to my build.gradle and only did as Hans has said on the command line. It worked a charm. I was going insane trying to get my jacoco report generated…the above forced my tests to be run, so that the .exec was generated, so that my jacocoTestReport would run.

(Hans Dockter) #9

If they should always run you can do:

task ... {
   outputs.upToDateWhen { false }

Do rerun them on demand you can write on the command line something like: ‘gradle cleanTest build’ or ‘gradle cleanTest test’