Como dar a propriedade do sistema ao meu teste via Gradle e -D

103

Eu tenho um programa Java que lê uma propriedade do sistema

System.getProperty("cassandra.ip");

e eu tenho um arquivo de compilação do Gradle com o qual começo

gradle test -Pcassandra.ip=192.168.33.13

ou

gradle test -Dcassandra.ip=192.168.33.13

no entanto, System.getProperty sempre retornará nulo .

A única maneira que encontrei foi adicionar isso ao meu arquivo de compilação do Gradle via

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

Como faço isso via -D

Robkuz
fonte
1
O que acontece quando você usa gradle -Dcassandra.ip=192.168.33.13? De qualquer forma, a tarefa de teste bifurca uma ou várias JVMs novas. Portanto, você terá que passar as propriedades explicitamente. Ninguém o força a codificar seu valor na construção, no entanto.
JB Nizet
Também dê uma olhada nesta resposta: stackoverflow.com/questions/23689054/…
IgalS

Respostas:

123

O sinalizador -P é para propriedades gradle e o sinalizador -D é para propriedades JVM. Como o teste pode ser bifurcado em uma nova JVM, o argumento -D passado para gradle não será propagado para o teste - parece que esse é o comportamento que você está vendo.

Você pode usar a propriedade systemProperty em seu testbloco como fez, mas basea-la na propriedade gradle de entrada, passando-a com -P:

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

ou alternativamente, se você estiver passando via -D

test {
    systemProperty "cassandra.ip", System.getProperty("cassandra.ip")
}
Jeff Storey
fonte
1
Isso não funciona para mim (testei usando System.getProperties().stringPropertyNames().forEach(System.out::println);o código Java, não parece)
CLOVIS
Aviso: getPropertylança MissingPropertyExceptionse a propriedade não for encontrada. Em vez disso, use a resposta de Eron: stackoverflow.com/a/43112126/915441
Yngvar Kristiansen
1
Adicionar valores padrão a gradle.propertiesevitará o MissingPropertyException.
Duncan Calvert
Não consigo fazer nenhum desses métodos funcionar. O que quer que eu faça, minha propriedade é sempre nula. Isso inclui todos os métodos mencionados abaixo também. Eu gostaria de saber se isso tem a ver com uma versão mais recente, já que todos os comentários são de 2018? @CLOVIS você encontrou uma solução para isso?
Hester Lyons
@HesterLyons Eu só queria saber se o build estava testando ou rodando normalmente, então usei a propriedade gradle em si adiciona ao testar; você pode ver o código aqui: github.com/CLOVIS-AI/wildfyre-java/blob/master/src/main/java/…
CLOVIS
27

Deparei com esse mesmo problema, exceto que não quero listar todas as propriedades fornecidas na linha de comando no script do Gradle novamente. Portanto, envio todas as propriedades do sistema para o meu teste

task integrationTest(type: Test) {
    useTestNG()
    options {
        systemProperties(System.getProperties())
    }
}
MrSpock
fonte
Tenha cuidado ao fazer isso. Ele pode facilmente interromper as verificações atualizadas do Gradle quando as propriedades do sistema são alteradas durante as chamadas.
thokuest
9

Tive um caso em que precisei passar várias propriedades do sistema para a JVM de teste, mas não todas (não queria passar as irrelevantes). Com base nas respostas acima, e usando subMappara filtrar as que eu precisava, isso funcionou para mim:

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

Neste exemplo, apenas PROP1e PROP2será transmitido, se existirem na JVM do gradle.

avivr
fonte
5

Aqui está uma variante que passa várias propriedades do projeto para a JVM de teste como propriedades do sistema. Eu prefiro propriedades de projeto em vez de propriedades de sistema para aumentar a flexibilidade.

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

Que pode ser passado na linha de comando:

 $ gradle intTest -Pfoo=1 -Pbar=2

E recuperado em seu teste:

String foo = System.getProperty("foo");
Eron Wright
fonte
Ao executar o System.getProperty("someprop")método subMap, obtive em {someprop=foo}vez de foo. Tive que usar systemProperty "foo", project.properties.subMap(["foo"]).get("foo")em build.gradle
Yngvar Kristiansen
@YngvarKristiansen onde (como) você estava usando systemProperty "foo"? ou seja, estou pedindo para ver a linha completa de código onde isso foi usado? Estou tentando tudo sugerido nesta pergunta e ainda assim Gradle não está passando nenhum argumento. Esperando que isso resolva!
Hester Lyons
@HesterLyons Desculpe, não guardei meu código, então não sei mais: \ Concordo que parece fora do lugar.
Yngvar Kristiansen
Obrigado @YngvarKristiansen. Desde então, descobri que meu problema estava sendo causado pelo plug-in junit gradle que foi incluído em meu gradle.build. Muito estranho.
Hester Lyons
0

Também me deparei com esse problema hoje, e o que funcionou para mim foi o seguinte:

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

Estou chamando minha tarefa de teste usando -Penv = dev e recebo meu valor 'dev' na minha impressão, ou 'prod' se não enviar nenhum valor, que é o comportamento esperado para mim.

O valor também é acessível no lado java, usando System.getProperty ("env") .

Minha conclusão sobre o assunto é que o valor de entrada (parâmetro) é realmente armazenado em Sistema , tornando-o acessível por meio de System.properties ['env'] ou System.getProperty ("env") , enquanto a saída (propriedade do sistema) é armazenada em uma matriz systemProperties , tornando-a legível por meio de systemProperties ['env'] .

Olivier B.
fonte