How to give System property to my test via Gradle and -D
JavaTestingGradleJava Problem Overview
I have a a Java program which reads a System property
System.getProperty("cassandra.ip");
and I have a Gradle build file that I start with
gradle test -Pcassandra.ip=192.168.33.13
or
gradle test -Dcassandra.ip=192.168.33.13
however System.getProperty will always return null.
The only way I found was to add that in my Gradle build file via
test {
systemProperty "cassandra.ip", "192.168.33.13"
}
How Do I do it via -D
Java Solutions
Solution 1 - Java
The -P flag is for gradle properties, and the -D flag is for JVM properties. Because the test may be forked in a new JVM, the -D argument passed to gradle will not be propagated to the test - it sounds like that is the behavior you are seeing.
You can use the systemProperty in your test
block as you have done but base it on the incoming gradle property by passing it with it -P:
test {
systemProperty "cassandra.ip", project.getProperty("cassandra.ip")
}
or alternatively, if you are passing it in via -D
test {
systemProperty "cassandra.ip", System.getProperty("cassandra.ip")
}
Solution 2 - Java
Came across this very much problem, except i don't want to list all properties given on the commandline in the gradle script again. Therefore i send all system properties to my test
task integrationTest(type: Test) {
useTestNG()
options {
systemProperties(System.getProperties())
}
}
Solution 3 - Java
I had a case where I needed to pass multiple system properties into the test JVM but not all (didn't want to pass in irrelevant ones). Based on the above answers, and by using subMap
to filter the ones I needed, this worked for me:
task integrationTest(type: Test) {
// ... Do stuff here ...
systemProperties System.getProperties().subMap(['PROP1', 'PROP2'])
}
In this example, only PROP1
and PROP2
will be passed in, if they exist in gradle's JVM.
Solution 4 - Java
Here's a variant that passes numerous project properties to the test JVM as system properties. I prefer project properties over system properties to increase flexibility.
task intTest(type: Test) {
systemProperties project.properties.subMap(["foo", "bar"])
}
Which may be passed on the command-line:
$ gradle intTest -Pfoo=1 -Pbar=2
And retrieved in your test:
String foo = System.getProperty("foo");
Solution 5 - Java
So I've stumbled on that issue today as well, and what worked for me was the following:
ext.env='prod'
test {
systemProperty 'env', System.properties['env'] ?: "${env}"
println "# test environment: " + systemProperties['env']
...
}
I'm calling my test task using -Penv=dev and I get my 'dev' value in my print, or 'prod' if I do not send any value, which is the expected behavior for me.
Value is also accessible on java side, using System.getProperty("env").
My conclusion on the matter is that input value (parameter) is actually stored under System, making it accessible through either System.properties['env'] or System.getProperty("env"), whereas output (system property) is stored in a systemProperties array, making it readable through systemProperties['env'].
Solution 6 - Java
Here is something that worked for me
//in build.gradle file
tasks.withType(Test) {
systemProperties = [ ip: System.getProperty('ip', '192.168.33.13'), ]
}
task integrationTests(type: Test){
useTestNG()
}
Suppose if you are using TestNG, you can add the annotation @Parameters as shown below
public class IpAddress {
@Test
@Parameters("ip")
public void printIpAddress(String ip) {
System.out.println(ip);
}
}
Now you are good to execute a gradlew command
./gradlew clean -Dip="xx.xx.xx.xx" integrationTests --tests "IpAddress"
If you want to use @DataProvider to pass the test data, you can pass it like below and execute the same above gradle command to run the test
public class IpAddress {
@DataProvider(name = "GetIP")
private static Object[][] getIp() {
return new Object[][]{
//if -Dip is not provided in command, then by default it gets the value assigned in build.gradle file i.e.'192.168.33.13'
{System.getProperty("ip")},
};
}
@Test(dataProvider = "GetIP")
public void printIpAddress(String ip) {
System.out.println(ip);
}
}