Как передать свойство System моему тесту через 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
Также взгляните на этот ответ: stackoverflow.com/questions/23689054/…
IgalS

Ответы:

126

Флаг -P предназначен для свойств Gradle, а флаг -D - для свойств JVM. Поскольку тест может быть разветвлен в новой JVM, аргумент -D, переданный в gradle, не будет передан в тест - похоже, что вы наблюдаете именно такое поведение.

Вы можете использовать systemProperty в своем testблоке, как вы это сделали, но основывать его на входящем свойстве gradle, передав его с параметром -P:

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 09
Предупреждение: getPropertyвыбрасывается, MissingPropertyExceptionесли свойство не найдено. Вместо этого используйте ответ Эрона: stackoverflow.com/a/43112126/915441
Ингвар Кристиансен
1
Добавление значений по умолчанию gradle.propertiesпредотвратит расширение MissingPropertyException.
Дункан Калверт
Я не могу заставить ни один из этих методов работать. Что бы я ни делал, myProperty всегда имеет значение null. Сюда также входят все методы, упомянутые ниже. Мне интересно, связано ли это с более поздней версией, поскольку все комментарии относятся к 2018 году? @CLOVIS, вы нашли решение?
Hester Lyons
@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())
    }
}
MrSpock
источник
Будьте осторожны при этом. Это может легко нарушить текущие проверки Gradle, когда свойства системы изменяются во время вызовов.
thokuest
9

У меня был случай, когда мне нужно было передать несколько системных свойств в тестовую JVM, но не все (я не хотел передавать нерелевантные). Основываясь на приведенных выше ответах и ​​используя subMapдля фильтрации нужных мне, это сработало для меня:

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

В этом примере будут переданы только PROP1и PROP2, если они существуют в JVM Gradle.

Авивр
источник
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
Ингвар Кристиансен
@YngvarKristiansen где (как) вы использовали systemProperty "foo"? т.е. я прошу увидеть полную строку кода, где это использовалось? Я пробую все, что предлагается в этом вопросе, и все же Gradle не передает никаких аргументов. Надеюсь, это разрешится!
Hester Lyons
@HesterLyons Простите, я не сохранил свой код, поэтому я больше не знаю: \ Я согласен, что это выглядит неуместно.
Yngvar Kristiansen
Спасибо @YngvarKristiansen. С тех пор я выяснил, что моя проблема была вызвана плагином junit gradle, который был включен в мой gradle.build. Очень странно.
Hester Lyons
0

Так что сегодня я тоже наткнулся на эту проблему, и мне помогло следующее:

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

Я вызываю свою тестовую задачу, используя -Penv = dev, и получаю свое значение 'dev' в моем print или 'prod', если я не отправляю никакого значения, что является ожидаемым поведением для меня.

Значение также доступно на стороне Java, используя System.getProperty ("env") .

Мой вывод по этому поводу заключается в том, что входное значение (параметр) фактически хранится в системе , что делает его доступным через System.properties ['env'] или System.getProperty ("env") , тогда как выходные данные (системное свойство) хранятся в systemProperties массив, что делает его доступным для чтения через systemProperties [ «окр»] .

Оливье Б.
источник