I have a Java TestNG project set up with gradle running test suites. Currently, most of the tests are pulling certain parameters out of a constants.properties file. How would I modify these on the command line when running the gradle task? Will gradle -DapplicationKey=0000 replace the line applicationKey=1234 in my constants.properties file?
Edit:
To be a bit more clear about the situation and the question, my constants.properties file contains around 400 to 500 properties that are already defined. I would like to avoid rewriting those properties in gradle completely. I just want to override those properties from the command line when Jenkins runs the same commands as part of that build job.
You want to pass system properties to the JVM used to run tests. Here is a way to configure all tasks of type Test:
tasks.withType(Test) {
systemProperty 'applicationKey', System.getProperty('applicationKey', '1234')
}
or just one task
test {
useTestNG()
systemProperties = [
applicationKey: System.getProperty('applicationKey', '1234')
]
}
You can also copy all system properties from the Gradle environment to the child virtual machine with systemProperties = System.getProperties()
Related
We set several key/value pairs in our gradle.properties file. (eg LOGIN_UID, LOGIN_PWD)
We can successfully reference them in our build.gradle (eg $LOGIN_UID) and our JUnit tests (eg System.getProperty("LOGIN_UID") when running gradle test from the cmdline.
However when clicking on a Run Test codelens within a JUnit's Java file within VSCode gradle.properties are not passed in. Guessing the Gradle test task is not being executed?
Greatly appreciate it if someone can help us understand and solve this running from a codelens.
Basically what you need is to add a setting in VS Code, something like this:
{
"java.test.config": {
"vmArgs": ["-DLOGIN_UID=id", ...]
}
}
Then test runner will pick up them and pass the properties to JVM.
At last, the configuration can be persisted in your workspace's .vscode/settings.json. If the properties have any sensitive data, like password, don't commit them to the source control!
When I run a test in Gradle I would like to pass some properties:
./gradlew test -DmyProperty=someValue
So in my Spock test I will use to retrieve the value:
def value = System.getProperty("myProperty")
Im using the kotlin gradle dsl. When I try and use 'tasks.test' as in this documentation:
https://docs.gradle.org/current/userguide/java_testing.html#test_filtering
'test' is not recognised in my build.gradle.kts file.
I'm assuming I would need to use something similar to the answer in the post below but it is not clear how it should be done in the using the gradle kotlin DSL.
How to give System property to my test via Gradle and -D
The answers from your linked question are translatable 1:1 to the kotlin DSL. Here is a full example using junit5.
dependencies {
// ...
testImplementation("org.junit.jupiter:junit-jupiter:5.4.2")
testImplementation(kotlin("test-junit5"))
}
tasks.withType<Test> {
useJUnitPlatform()
// Project property style - optional property.
// ./gradlew test -Pcassandra.ip=xx.xx.xx.xx
systemProperty("cassandra.ip", project.properties["cassandra.ip"])
// Project property style - enforced property.
// The build will fail if the project property is not defined.
// ./gradlew test -Pcassandra.ip=xx.xx.xx.xx
systemProperty("cassandra.ip", project.property("cassandra.ip"))
// system property style
// ./gradlew test -Dcassandra.ip=xx.xx.xx.xx
systemProperty("cassandra.ip", System.getProperty("cassandra.ip"))
}
This example demos three ways of passing system properties to the junit test. Two of them specifies the system properties one at a time. The last avoids having to forward declare each system property by taking all system properties available to the gradle runtime and passes them to the junit test harness.
tasks.withType<Test> {
useJUnitPlatform()
// set system property using a property specified in gradle
systemProperty("a", project.properties["a"])
// take one property that was specified when starting gradle
systemProperty("a", System.getProperty("a"))
// take all of the system properties specified when starting gradle
// which avoids copying each property over one at a time
systemProperties(System.getProperties().toMap() as Map<String,Object>)
}
How do you tell Jenkins to set a property inside gradle.properties in an Android project? I've figured out how to get the properties from Gradle into Jenkins (by using the EnvInject plugin and simply entering gradle.properties into the property file field) but I also want the build number that is managed by Jenkins to be injected into the build artifact.
I also want to set the filename of the resulting artifact which, I think, needs to be injected by using archivesBaseName. But that property isn't part of gradle.properties so I wonder how do I access it?
So far I've only found solutions that change the build.gradle file (or other gradle scripts) in the Android project itself. But that's not what I want to do because that would make the Android code base rely on Jenkins.
Instead I want Jenkins to provide the build number and artifact file name to the Android project before it compiles the code.
The server runs on a Mac. Does anyone have a solution for this? Any shell/Groovy script that does the job would be welcome.
We are just wrinting a file version.properties, which is generated by jenkins "echo "VERSION_CODE=${BUILD_NUBMER}" > version.properies" script.
Then gradle script imports it as following:
// Version code is loaded from a properties file
def versionPropsFile = file('version.properties')
if (versionPropsFile.canRead()) {
def Properties versionProps = new Properties()
versionProps.load(new FileInputStream(versionPropsFile))
def code = versionProps['VERSION_CODE'].toInteger()
versionCode code
}
else {
throw new GradleException("Could not read version.properties!")
}
buildConfigField "String", " some _VERSION", "\"${getVersionString()}\""
}
I need to run project tests both locally and automatically on TeamCity server.
Local test execution must use local database connection, and when run on TeamCity, tests must use a remote connection to the database.
So I need to tell my tests, when to use local connection and when to use remote and pass URL, username and password in this case.
To tell that I decided to use java system properties. I found built-in support in Gradle for that
systemProperty 'some.prop', 'value'
The question is, how can I create a standard test task for local test run, that will not pass any properties, and a custom test task, that will set system properties before run?
I tried something like
task teamCityTest(type : Test) {
scanForTestClasses = false
includes = ['**/*Test.class']
systemProperty 'some.prop', 'value'
}
but it failed with NPE, that means I'm doing something wrong.
The approach is fine (you can use the Java plugin's test task for running tests locally), but you'll have to configure further properties for teamCityTest such as classpath = configurations.testRuntime (or even classpath = test.classpath). For a full example, see samples/java/withIntegrationTests in the gradle-all distribution.
I am writing a console application with Java and gradle. I am using the application plugin and have the required fields correctly configured in build.gradle.
In my main class I have BufferedReader linked with System.in. Here's the problem: When I run gradle run in project directory, the reader does not wait for my console input. BufferedReader#readLine instead returns null on the very first call. This behavior is not desirable for what am I doing.
What is the solution? Is there a separate console application plugin for gradle or do I need to tweak application plugin somehow to suit my needs?
By default, the system.in of your Gradle build is not wired up with the system.in of the run (JavaExec) task. You can do the following:
build.gradle (Groovy syntax):
run {
standardInput = System.in
}
build.gradle.kts (Kotlin DSL syntax):
tasks.named<JavaExec>("run") {
standardInput = System.`in`
}
As stated above, add
run {
standardInput = System.in
}
And run:
gradle console:run -q --console=plain
where:
-q runs task in "quiet" mode (to avoid having > Building > :run)
--console=plain drops execution status: <=-> 80% EXECUTING [TIME]
Source: https://docs.gradle.org/current/userguide/gradle_command_line.html
For build.gradle.kts:
tasks.getByName<JavaExec>("run") {
standardInput = System.`in`
}
Chances are, the problem lies in your java code. All the application plugin does is compile the java code, and run the main class that you specify. Can you post the code in your main class that you specified for the application plugin (mainClassName) ?