80

I'm trying to set an environment variable from my Gradle build. I'm on MacOS X (El Capitan). The command is "gradle test".

I'm trying this in my build.gradle:

task setenv(type: Exec) {
    commandLine "export", "SOME_TEST_VAR=aaa"
}
test.dependsOn setenv

and the build fails:

Execution failed for task ':myproject:setenv'.

A problem occurred starting process 'command 'export''

I also tried this:

test.doFirst {
    ProcessBuilder pb1 = new ProcessBuilder("export SOME_TEST_VAR=some test value")
    pb1.start();
}

The build succeeds. However, if I check the environment variable in my JUnit test it fails:

assertTrue(System.getenv().containsKey("SOME_TEST_VAR"));

Is there any way to set an environment variable from a Gradle build (in the build.gradle file)?

Update:

I've tested it in isolation: the values do get passed and my test task receives everything, be it a systemProperty, environment variables or jvmArgs.

So, it's nothing wrong with Gradle itself here.

The problem arises when I'm trying it on the real project. It uses Spring for dependency injection. I may be wrong but it looks like the Spring framework purges those values somewhere.

That sub-project is currently being frozen and I can't check my guess in detail right now.

John Smith
  • 7,243
  • 6
  • 49
  • 61
user3791111
  • 1,469
  • 1
  • 15
  • 20
  • Another failed experiment: `test { systemProperty 'SOME_TEST_VAR', 'aaa' environment 'SOME_TEST_VAR', 'aaa' }` and in the test: `boolean good = System.getenv().containsKey("SOME_TEST_VAR") || System.getProperties().containsKey("SOME_TEST_VAR"); assertTrue(good);` – user3791111 Mar 31 '16 at 03:23
  • I can't make line breaks work here even after reading the help. Sorry, just assume where I meant to make them. – user3791111 Mar 31 '16 at 03:25
  • 1
    You are supposed to edit your question, if you have more information to provide. – Ortomala Lokni Apr 05 '16 at 18:27
  • Updated the question. The problem is not with Gradle. – user3791111 Apr 07 '16 at 13:18

10 Answers10

98

For a test task, you can use the environment property like this:

test {
  environment "VAR", "val"
}

you can also use the environment property in an exec task

task dropDatabase(type: Exec) {
    environment "VAR", "val"
    commandLine "doit"
}

Note that with this method the environment variables are set only during the task.

Ortomala Lokni
  • 56,620
  • 24
  • 188
  • 240
  • 12
    Things like "environment", "jvmArgs" and "systemProperties" are ignored for the "test" task. I'm desperately trying to understand why. I know that test in run in a separate JVM -- then at least "jvmArgs" should work but it doesn't. – user3791111 Apr 04 '16 at 12:14
  • 1
    You can also use the [JavaExec](https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/JavaExec.html) class if you just want to fork the JVM. – Stuporman Dec 14 '16 at 03:11
  • How to use this for idea task. working fine for test task but not working in idea. Please suggest the best way. – Adit choudhary Mar 08 '19 at 06:49
  • @Aditchoudhary, you should delegate the test running to Gradle first. You can see how to delegate it here - https://mrhaki.blogspot.com/2016/11/gradle-goodness-delegate-build-and-run.html – Max Aug 20 '19 at 04:27
9

You can also "prepend" the environment variable setting by using 'environment' command:

run.doFirst { environment 'SPARK_LOCAL_IP', 'localhost' }
Guildenstern70
  • 1,715
  • 18
  • 18
6

In case you're using Gradle Kotlin syntax, you also can do:

tasks.taskName {
    environment(mapOf("A" to 1, "B" to "C"))
}

So for test task this would be:

tasks.test {
    environment(mapOf("SOME_TEST_VAR" to "aaa"))
}
Alexey Soshin
  • 16,718
  • 2
  • 31
  • 40
4

If you have global environment variables defined outside Gradle,

test {
    environment "ENV_VAR",  System.getenv('ENV_VAR')
    useJUnitPlatform()
}
alegria
  • 1,290
  • 14
  • 23
3

This looks like an old thread but there is one more variant of how we can set an environment variable in the Gradle task.

task runSomeRandomTask(type: NpmTask, dependsOn: [npmInstall]) {
    environment = [ 'NODE_ENV': 'development', BASE_URL: '3000' ]
    args = ['run']
}

The above Gradle task integrates the Gradle and npm tasks.

This way we can pass multiple environment variables. Hope this helps to broaden the understanding which the answers above have already provided. Cheers!!

shaangon
  • 159
  • 12
  • I guess it completely erases all env variables and sets only two NODE_ENV and BASE_URL – Capacytron Jan 26 '23 at 19:41
  • To avoid rewriting environment you can go this way `environment = System.getenv() + ['NODE_ENV': 'https://mymirror.com/dist']` – Kamil W Mar 01 '23 at 10:56
3

If you are using an IDE, go to run, edit configurations, gradle, select gradle task and update the environment variables. See the picture below.

enter image description here

Alternatively, if you are executing gradle commands using terminal, just type 'export KEY=VALUE', and your job is done.

Lagrange
  • 95
  • 7
1

This one is working for me for settings environment variable for the test plugin

test {
    systemProperties = [
        'catalina.home': 'c:/test'
    ]
    println "Starting Tests"
    beforeTest { descriptor ->
       logger.lifecycle("Running test: " + descriptor)                
    }    
}
Maayan Hope
  • 1,482
  • 17
  • 32
0

In my project I have Gradle task for integration test in sub-module:

task intTest(type: Test) {
...
system.properties System.properties 
...

this is the main point to inject all your system params into test environment. So, now you can run gradle like this to pass param with ABC value and use its value by ${param} in your code

gradle :some-service:intTest -Dparam=ABC
0

Please try this one option:

 task RunTest(type: Test) {
         systemProperty "spring.profiles.active", System.getProperty("DEV")
         include 'com/db/project/Test1.class'
     }
27P
  • 1,183
  • 16
  • 22
0

Environment variables are needed to customise the execution of the gradle tasks. Below is the working code in gradle 7.3.2, where need to pass the host and port to the cucumber steps.

    task runFunctionalTests() {
    dependsOn assemble, testClasses
    doLast {
        javaexec {
            mainClass = "io.cucumber.core.cli.Main"
            classpath = configurations.cucumberRuntime + sourceSets.main.output + sourceSets.test.output
            args = [
                    '--glue', 'com.examples.functional.steps',
               'src/test/java/com/examples/tests/functional/features'
            ]
            environment 'PROTOCOL', 'http'
            environment "HOST", "myserver"
            environment 'PORT', '8080'
        }
    }
}

And then you access the environment variable in the cucumber steps as below

String host = System.getenv("HOST");
int port = Integer.parseInt(System.getenv("PORT"));
String host = System.getenv("PROTOCOL");
Sanjay Bharwani
  • 3,317
  • 34
  • 31