Comment donner la propriété System à mon test via Gradle et -D

103

J'ai un programme Java qui lit une propriété système

System.getProperty("cassandra.ip");

et j'ai un fichier de construction Gradle avec lequel je commence

gradle test -Pcassandra.ip=192.168.33.13

ou

gradle test -Dcassandra.ip=192.168.33.13

cependant System.getProperty renverra toujours null .

Le seul moyen que j'ai trouvé était d'ajouter cela dans mon fichier de construction Gradle via

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

Comment faire via -D

Robkuz
la source
1
Que se passe-t-il lorsque vous utilisez gradle -Dcassandra.ip=192.168.33.13? Quoi qu'il en soit, la tâche de test fourche une ou plusieurs nouvelles JVM. Vous devrez donc transmettre les propriétés explicitement. Personne ne vous oblige à coder en dur leur valeur dans la construction, cependant.
JB Nizet
Jetez également un œil à cette réponse: stackoverflow.com/questions/23689054/…
IgalS

Réponses:

126

L'indicateur -P est pour les propriétés gradle et l'indicateur -D est pour les propriétés JVM. Comme le test peut être forké dans une nouvelle JVM, l'argument -D passé à gradle ne sera pas propagé au test - il semble que c'est le comportement que vous voyez.

Vous pouvez utiliser la propriété systemProperty dans votre testbloc comme vous l'avez fait, mais basez-la sur la propriété gradle entrante en la passant avec -P:

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

ou bien, si vous le transmettez via -D

test {
    systemProperty "cassandra.ip", System.getProperty("cassandra.ip")
}
Jeff Storey
la source
1
Cela ne fonctionne pas pour moi (testé en utilisant System.getProperties().stringPropertyNames().forEach(System.out::println);le code Java, cela n'apparaît pas)
CLOVIS
Attention: getPropertylance MissingPropertyExceptionsi la propriété n'est pas trouvée. Utilisez la réponse d'Eron à la place: stackoverflow.com/a/43112126/915441
Yngvar Kristiansen
1
L'ajout de valeurs par défaut à gradle.propertiesempêchera le MissingPropertyException.
Duncan Calvert
Je ne peux faire fonctionner aucune de ces méthodes. Quoi que je fasse, myProperty est toujours nul. Cela inclut également toutes les méthodes mentionnées ci-dessous. Je me demande si cela a quelque chose à voir avec une version plus récente, car tous les commentaires datent de 2018? @CLOVIS avez-vous trouvé une solution à cela?
Hester Lyons
@HesterLyons Je voulais seulement savoir si la construction était en cours de test ou en cours d'exécution, alors j'ai utilisé la propriété gradle elle-même ajoutée lors du test; vous pouvez voir le code ici: github.com/CLOVIS-AI/wildfyre-java/blob/master/src/main/java
...
27

Je suis tombé sur ce problème, sauf que je ne veux pas lister à nouveau toutes les propriétés données sur la ligne de commande dans le script gradle. Par conséquent, j'envoie toutes les propriétés du système à mon test

task integrationTest(type: Test) {
    useTestNG()
    options {
        systemProperties(System.getProperties())
    }
}
MrSpock
la source
Soyez prudent en faisant cela. Cela pourrait facilement interrompre les vérifications à jour de Gradle lorsque les propriétés du système changent pendant les appels.
thokuest
9

J'ai eu un cas où je devais passer plusieurs propriétés système dans la JVM de test, mais pas toutes ( je ne voulais pas passer de propriétés non pertinentes). Sur la base des réponses ci-dessus et en utilisant subMappour filtrer celles dont j'avais besoin, cela a fonctionné pour moi:

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

Dans cet exemple, uniquement PROP1et PROP2seront transmis, s'ils existent dans la JVM de gradle.

avivr
la source
5

Voici une variante qui transmet de nombreuses propriétés de projet à la JVM de test en tant que propriétés système. Je préfère les propriétés du projet aux propriétés du système pour augmenter la flexibilité.

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

Qui peut être passé sur la ligne de commande:

 $ gradle intTest -Pfoo=1 -Pbar=2

Et récupéré dans votre test:

String foo = System.getProperty("foo");
Eron Wright
la source
Lors de l'exécution de System.getProperty("someprop")cette méthode subMap, j'ai obtenu à la {someprop=foo}place de foo. J'ai dû utiliser systemProperty "foo", project.properties.subMap(["foo"]).get("foo")dans build.gradle
Yngvar Kristiansen
@YngvarKristiansen où (comment) utilisiez-vous systemProperty "foo"? c'est-à-dire que je demande à voir la ligne complète de code où cela a été utilisé? J'essaie tout ce qui est suggéré dans cette question et Gradle ne transmet toujours aucun argument. En espérant que cela résoudra!
Hester Lyons
@HesterLyons Je suis désolé, je n'ai pas gardé mon code, donc je ne sais plus: \ Je suis d'accord qu'il a l'air déplacé.
Yngvar Kristiansen
Merci @YngvarKristiansen. Depuis, j'ai découvert que mon problème était causé par le plugin junit gradle qui était inclus dans mon gradle.build. Très étrange.
Hester Lyons
0

Je suis donc tombé sur ce problème aujourd'hui, et ce qui a fonctionné pour moi était le suivant:

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

J'appelle ma tâche de test en utilisant -Penv = dev et j'obtiens ma valeur 'dev' dans mon impression, ou 'prod' si je n'envoie aucune valeur, ce qui est le comportement attendu pour moi.

La valeur est également accessible côté Java, en utilisant System.getProperty ("env") .

Ma conclusion à ce sujet est que la valeur d'entrée (paramètre) est en fait stockée sous System , ce qui la rend accessible via System.properties ['env'] ou System.getProperty ("env") , alors que la sortie (propriété système) est stockée dans un tableau systemProperties , le rendant lisible via systemProperties ['env'] .

Olivier B.
la source