Ken Pronovici
Ken Pronovici

Reputation: 784

Is it possible to configure system properties dynamically for a Gradle test task?

Is it possible to configure system properties dynamically for a Gradle test task? I haven't found a way to make it work.

I am working within my own Gradle plugin, GwtPlugin. The apply() method looks like this:

/** Apply the plugin. */
void apply(Project project) {
   project.plugins.apply(JavaPlugin)
   project.plugins.apply(WarPlugin)

   project.extensions.create("gwt", GwtPluginExtension, project)
   project.extensions.create("testSuite", TestSuitePluginExtension, project)
   project.convention.plugins.gwt = new GwtPluginConvention(project)

   applyGwt(project)
   applyTestSuite(project)
}

In the applyTestSuite() method, I create a tasks for my test suites. The definition for the integrationtest task looks like this:

// Run integration tests, assumed to be found in a class suites/IntegrationTestSuite.
project.task("integrationtest", type: org.gradle.api.tasks.testing.Test, dependsOn: project.tasks.buildApplication) {
    workingDir = { project.testSuite.getWorkingDir() == null ? project.projectDir : project.testSuite.getWorkingDir() }
    scanForTestClasses = false
    scanForTestClasses = false
    enableAssertions = false
    outputs.upToDateWhen { false }

    include "suites/IntegrationTestSuite.class"
    systemProperty "integration.test.server.wait", project.gwt.getServerWait()

    beforeSuite { descriptor ->
       if (descriptor.className == "suites.IntegrationTestSuite") {
          project.convention.plugins.gwt.rebootDevmode()
       }
    }

    afterSuite { descriptor ->
       if (descriptor.className == "suites.IntegrationTestSuite") {
          project.convention.plugins.gwt.killDevmode()
       }
    }
}

I want to get configuration for the integration.test.server.wait system property from project.gwt.getServerWait(). I can't figure out how to make this work, and I'm beginning to think it's not possible.

If I hardcode the system property, everything works as expected:

systemProperty "integration.test.server.wait", 10

The problem seems to be that the system property is set when the task is defined, but my extension doesn't have any values at that point. I can't figure out how to work around this.

For instance, I tried putting the project.gwt.getServerWait() call in a closure, but in that case the system property gets set to a string like:

com.me.gradle.GwtPlugin$_applyTestSuite_closure10_closure42@320de756

I also tried moving the systemProperty line to a doFirst block. In that case, the doFirst block gets a sensible value from my extension (I can print it), but the assignment is apparently too late to influence the test runner.

Is there any way for me to accomplish this? If not, is there another way to pass dynamic configuration to my test runner?

Upvotes: 2

Views: 3115

Answers (4)

HelloWorld
HelloWorld

Reputation: 617

Dunno what version you were using to do this, but this seems the most convenient way to me:

task doSomethingBeforeTest {
    doLast {
      // some stuff to do
        test {
            systemProperties['some.property'] = 'prop'
        }
    }
}

basically, just put that test block in your task and set the property. (this works as of gradle 4.0 - not sure about previous versions, but I imagine it would).

Upvotes: 1

Damien Coraboeuf
Damien Coraboeuf

Reputation: 163

What I do is:

ext {
    // Sets a sensible default
    myProperty project.properties.myProperty
}
task preTest << {
    // Computes the property...
    project.ext.myProperty = ...
}
task myTest {
    ...
    doFirst {
        systemProperty 'myProperty', project.ext.myProperty
    }
}

I define a sensible default value in the gradle.properties file:

myProperty = A sensible default value

In a multi module environment, it can be trickier. I then use rootProject.ext.myProperty from the test task.

Best regards, Damien.

Upvotes: 1

Peter
Peter

Reputation: 793

I'm not sure if this works, but have you tried to do it in this way

doLast {
    systemProperty "integration.test.server.wait", project.gwt.getServerWait()
}

within your plugin script?

May be this has to do with the phase (configuration, ... ) when the things are resolved in gradle.

Upvotes: 0

Ken Pronovici
Ken Pronovici

Reputation: 784

I have found a way to make this work. The trick is to set the system property on the test task sometime later, when the property is certain to be available. The simplest way to make that happen seems to be via a dummy dependency:

project.task("integrationtestconfig") << {
   outputs.upToDateWhen { false }
   project.tasks.integrationtest.systemProperty("integration.test.server.wait", project.gwt.getServerWait())
}

project.task("integrationtest", type: org.gradle.api.tasks.testing.Test, 
             dependsOn: project.tasks.buildApplication, project.tasks.integrationtestconfig)
...

It's not the elegant solution I was hoping for, but it does work and it's not too difficult to follow.

Upvotes: 2

Related Questions