Come dare la proprietà di sistema al mio test tramite Gradle e -D


103

Ho un programma Java che legge una proprietà di sistema

System.getProperty("cassandra.ip");

e ho un file di build Gradle con cui inizio

gradle test -Pcassandra.ip=192.168.33.13

o

gradle test -Dcassandra.ip=192.168.33.13

tuttavia System.getProperty restituirà sempre null .

L'unico modo che ho trovato è stato aggiungerlo nel mio file di build Gradle tramite

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

Come lo faccio tramite MrGreen


1
Cosa succede quando usi gradle -Dcassandra.ip=192.168.33.13? Ad ogni modo, l'attività di test esegue il fork di una o più nuove JVM. Quindi dovrai passare le proprietà in modo esplicito. Nessuno ti obbliga a codificare il loro valore nella build, però.
JB Nizet

Anche dare un'occhiata a questa risposta: stackoverflow.com/questions/23689054/...
IgalS

Risposte:


124

Il flag -P è per le proprietà gradle e il flag -D è per le proprietà JVM. Poiché il test può essere biforcato in una nuova JVM, l'argomento -D passato a gradle non verrà propagato al test - sembra che questo sia il comportamento che stai vedendo.

Puoi usare systemProperty nel tuo testblocco come hai fatto ma basarlo sulla proprietà gradle in entrata passandola con -P:

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

o in alternativa se lo stai passando in via MrGreen

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

1
Questo non funziona per me (testato utilizzando System.getProperties().stringPropertyNames().forEach(System.out::println);nel codice Java, non appare)
CLOVIS

Avviso: getPropertygenera MissingPropertyExceptionse la proprietà non viene trovata. Usa invece la risposta di Eron: stackoverflow.com/a/43112126/915441
Yngvar Kristiansen

1
L'aggiunta di valori predefiniti a gradle.propertiesimpedirà il MissingPropertyException.
Duncan Calvert

Non riesco a far funzionare nessuno di questi metodi. Qualunque cosa io faccia myProperty è sempre nulla. Ciò include anche tutti i metodi menzionati di seguito. Mi chiedo se abbia qualcosa a che fare con una versione più recente, poiché tutti i commenti sono del 2018? @CLOVIS hai trovato una soluzione a questo?
Hester Lyons

@HesterLyons Volevo solo sapere se la build era in fase di test o normalmente in esecuzione, quindi ho usato la proprietà che gradle stessa aggiunge durante il test; puoi vedere il codice qui: github.com/CLOVIS-AI/wildfyre-java/blob/master/src/main/java/…
CLOVIS

27

Mi sono imbattuto in questo problema molto, tranne che non voglio elencare di nuovo tutte le proprietà fornite sulla riga di comando nello script gradle. Pertanto mando tutte le proprietà del sistema al mio test

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

Fai attenzione quando lo fai. Potrebbe facilmente interrompere i controlli aggiornati di Gradle quando le proprietà del sistema cambiano durante le chiamate.
thokuest

9

Ho avuto un caso in cui avevo bisogno di passare più proprietà di sistema nella JVM di test ma non tutte (non volevo passare a quelle irrilevanti). Sulla base delle risposte di cui sopra e utilizzando subMapper filtrare quelle di cui avevo bisogno, questo ha funzionato per me:

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

In questo esempio, solo PROP1e PROP2verranno trasmessi, se esistono nella JVM di gradle.


5

Ecco una variante che passa numerose proprietà del progetto alla JVM di test come proprietà di sistema. Preferisco le proprietà del progetto rispetto alle proprietà del sistema per aumentare la flessibilità.

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

Che può essere passato dalla riga di comando:

 $ gradle intTest -Pfoo=1 -Pbar=2

E recuperato nel tuo test:

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

Quando si esegue System.getProperty("someprop")utilizzando quel metodo subMap, ho ottenuto {someprop=foo}invece di foo. Ho dovuto usare systemProperty "foo", project.properties.subMap(["foo"]).get("foo")in build.gradle
Yngvar Kristiansen il

@YngvarKristiansen dove (come) stavi usando systemProperty "foo"? cioè sto chiedendo di vedere l'intera riga di codice in cui è stato utilizzato? Sto provando tutto ciò che viene suggerito in questa domanda e ancora Gradle non sta passando alcun argomento. Sperando che questo possa risolversi!
Hester Lyons

@HesterLyons Mi dispiace, non ho mantenuto il mio codice, quindi non lo so più: \ Sono d'accordo che sembra fuori posto.
Yngvar Kristiansen

Grazie @YngvarKristiansen. Da allora ho capito che il mio problema era causato dal plugin junit gradle che era incluso nel mio gradle.build. Molto strano.
Hester Lyons

0

Quindi anche oggi mi sono imbattuto in questo problema e ciò che ha funzionato per me è stato il seguente:

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

Sto chiamando la mia attività di test usando -Penv = dev e ottengo il mio valore 'dev' nella mia stampa, o 'prod' se non invio alcun valore, che è il comportamento previsto per me.

Il valore è accessibile anche dal lato Java, utilizzando System.getProperty ("env") .

La mia conclusione in merito è che il valore di input (parametro) è effettivamente memorizzato in System , rendendolo accessibile tramite System.properties ['env'] o System.getProperty ("env") , mentre l'output (proprietà di sistema) è memorizzato in un array systemProperties , che lo rende leggibile tramite systemProperties ['env'] .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.