如何通过Gradle和-D将系统属性赋予我的测试


103

我有一个读取系统属性的Java程序

System.getProperty("cassandra.ip");

我有一个Gradle构建文件

gradle test -Pcassandra.ip=192.168.33.13

要么

gradle test -Dcassandra.ip=192.168.33.13

但是System.getProperty将始终返回null

我发现的唯一方法是通过以下方式将其添加到我的Gradle构建文件中

test {
    systemProperty "cassandra.ip", "192.168.33.13"
}

我如何通过-D做到这一点


1
使用时会发生什么gradle -Dcassandra.ip=192.168.33.13?无论如何,测试任务会派生一个或几个新的JVM。因此,您必须显式地传递属性。但是,没有人会强迫您在构建中硬编码它们的价值。
JB Nizet 2014年

也可参加这个答案一看:stackoverflow.com/questions/23689054/...
IgalS

Answers:


123

-P标志用于gradle属性,-D标志用于JVM属性。因为测试可能是在新的JVM中派生的,所以传递给gradle的-D参数不会传播到测试中-听起来这就是您所看到的行为。

您可以test像完成操作一样在您的块中使用systemProperty,但可以通过将其与-P一起传递来基于传入的gradle属性:

test {
    systemProperty "cassandra.ip", project.getProperty("cassandra.ip")
}

或者,如果您通过-D传递

test {
    systemProperty "cassandra.ip", System.getProperty("cassandra.ip")
}

1
这对我不起作用(System.getProperties().stringPropertyNames().forEach(System.out::println);在Java代码中使用过测试 ,但未显示)
CLOVIS

警告:如果找不到属性,则getProperty引发MissingPropertyException。请改用Eron的答案:stackoverflow.com/a/43112126/915441
Yngvar Kristiansen,

1
添加默认值gradle.properties将防止MissingPropertyException
邓肯·卡尔弗特

我无法使这些方法都起作用。无论我做什么,myProperty始终为null。这也包括下面提到的所有方法。我想知道这是否与更新版本有关,因为所有评论均来自2018年?@CLOVIS您是否找到解决方案?
海斯特·里昂

@HesterLyons我只是想知道,如果构建正在测试或正常运行,所以我使用的属性gradle这个测试时本身增加; 您可以在此处查看代码:github.com/CLOVIS-AI/wildfyre-java/blob/master/src/main/java/…–
CLOVIS

27

遇到了这个非常大的问题,只是我不想再次在gradle脚本中列出命令行上给出的所有属性。因此,我将所有系统属性发送给我的测试

task integrationTest(type: Test) {
    useTestNG()
    options {
        systemProperties(System.getProperties())
    }
}

这样做时要小心。当系统属性在调用期间更改时,它很容易破坏Gradle的最新检查。
thokuest

9

我遇到一种情况,我需要将多个系统属性传递给测试JVM,但不是全部(不想传递不相关的属性)。根据以上答案,并通过使用subMap筛选所需的内容,这对我有用:

task integrationTest(type: Test) {
    // ... Do stuff here ...
    systemProperties System.getProperties().subMap(['PROP1', 'PROP2'])
}

在此示例中,如果它们存在于gradle的JVM中,则仅PROP1PROP2将被传入。


5

这是一个变体,它将众多项目属性作为系统属性传递给测试JVM。与系统属性相比,我更喜欢项目属性,以增加灵活性。

task intTest(type: Test) {
    systemProperties project.properties.subMap(["foo", "bar"])
}

可以在命令行中传递:

 $ gradle intTest -Pfoo=1 -Pbar=2

并在您的测试中检索到:

String foo = System.getProperty("foo");

System.getProperty("someprop")使用该subMap方法运行时,我得到的 {someprop=foo}不是foo。我必须systemProperty "foo", project.properties.subMap(["foo"]).get("foo")在build.gradle中使用
Yngvar Kristiansen,

@YngvarKristiansen您在哪里(如何)使用systemProperty "foo"?即我要查看使用它的完整代码行?我正在尝试此问题中建议的所有内容,但Gradle仍未传递任何参数。希望这可以解决!
海斯特·里昂

@HesterLyons对不起,我没有保留我的代码,所以我也不知道了:\我同意它看起来不合适。
Yngvar Kristiansen

谢谢@YngvarKristiansen。从那以后,我发现我的问题是由gradle.build中包含的junit gradle插件引起的。很奇怪。
海斯特·里昂

0

所以我今天也偶然发现了这个问题,对我有用的是:

ext.env='prod'
test {
  systemProperty 'env', System.properties['env'] ?: "${env}"
  println "# test environment: " + systemProperties['env']
  ...
}

我正在使用-Penv = dev调用测试任务,并且在打印中得到了'dev'值,如果我没有发送任何值,则得到了'prod'值,这是我的预期行为。

还可以使用System.getProperty(“ env”)在Java端访问值。

我对此的结论是,输入值(参数)实际上存储在System下,从而可以通过System.properties ['env']System.getProperty(“ env”)进行访问,而输出(系统属性)存储在一个systemProperties数组,使其可以通过systemProperties ['env']读取。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.