assert vs. Assertions JUnit

85

Hoje eu vi um caso de teste JUnit com uma asserção java em vez das asserções JUnit - há vantagens ou desvantagens significativas em preferir um ao outro?

Robert
fonte
Existem diferenças absolutamente factuais entre as asserções JUnit e a palavra-chave 'assert' do Java. Esta não é uma questão baseada em opinião.
Thomas W

Respostas:

95

No JUnit4, a exceção (na verdade, Error) lançada por uma declaração JUnit é igual ao erro lançado pela assertpalavra-chave java (AssertionError), então é exatamente o mesmo assertTruee diferente do rastreamento de pilha, você não poderia dizer a diferença.

Dito isso, os asserts precisam ser executados com um sinalizador especial na JVM, fazendo com que muitos testes pareçam passar apenas porque alguém se esqueceu de configurar o sistema com aquele sinalizador quando os testes JUnit foram executados - não é bom.

Em geral, por causa disso, eu diria que usar o JUnit assertTrueé a melhor prática, porque garante que o teste seja executado, garante consistência (você às vezes usa assertThatou outras afirmações que não são uma palavra-chave java) e se o comportamento da JUnit afirma deve mudar no futuro (como enganchar em algum tipo de filtro ou outro recurso JUnit futuro) seu código será capaz de aproveitar isso.

O propósito real da palavra-chave assert em java é ser capaz de desligá-la sem penalidade de tempo de execução. Isso não se aplica a testes de unidade.

Yishai
fonte
26

Eu prefiro asserções JUnit, pois elas oferecem uma API mais rica do que a assertinstrução integrada e, mais importante, não precisam ser ativadas explicitamente assert, ao contrário , que requer o -eaargumento JVM.

Adamski
fonte
1
-eaestá sempre ativado mvn test, não há necessidade de -ea. Api mais rico, boa pegada. Às vezes acho que a API é mal utilizada no teste porque não faz parte do aplicativo (a in api), prefiro chamá-la apenas de métodos mais ricos.
Grim
20

Quando um teste falha, você obtém mais informações.

assertEquals(1, 2); resulta em java.lang.AssertionError: expected:<1> but was:<2>

vs

assert(1 == 2); resulta em java.lang.AssertionError

você pode obter ainda mais informações se adicionar o argumento da mensagem a assertEquals

starmer
fonte
9
tente assert 1==2: "1 is not 2";.
Grim
@PeterRader Tente a palavra-chave assert quando -ea não estiver habilitado. Ou melhor ainda, use asserções JUnit que sempre funcionam.
Thomas W
1
@ThomasW quando -ea não está habilitado, não é um teste. As asserções JUnit nem sempre funcionam, elas só funcionam se você decidir usar o JUnit, o que é um framework, e no caso de uma dependência maven, uma dependência maven que deve estar apenas no escopo de teste. Temos dois lados aqui: o que você prefere? 1º lado : Use um framework, como uma dependência apenas no escopo de teste, que deve ser baixado, que o eclipse permite que você use em classes que não estão na pasta src / principal, mas não compilarão lá porque o maven tem junit apenas em teste escopo ou 2o lado : use o material embutido.
Grim
1
@PeterRader Esta pergunta é sobre os casos de teste JUnit. Nesse contexto, JUnit ou classe de asserção semelhante deve ser usada, pois estão sempre ativados. Eu fui pessoalmente pego pela palavra-chave Java 'assert' não habilitada no passado e não acredito que asserções não confiáveis ​​tenham lugar no código de teste.
Thomas W
No contexto separado de asserções no código de recurso - importante para uma prática de programação robusta, embora não seja realmente o tópico da questão - tanto Spring quanto Google Guava têm classes de asserção que estão sempre ativadas. Eu recomendo o uso generoso deles como pré-condições de parâmetro e estado para garantir a correção. Além disso, em áreas críticas de desempenho, pode haver uma pequena área onde o Java assertpode ser preferível - para verificações de exatidão que afetariam o desempenho e, portanto, são melhor desativadas por padrão. No entanto, minha experiência é que a maioria das afirmações deve estar sempre ativa.
Thomas W
8

Eu diria que use declarações JUnit em casos de teste e use declarações de java no código. Em outras palavras, o código real nunca deve ter dependências JUnit, como é óbvio, e se for um teste, ele deve usar as variações JUnit dele, nunca o assert.

Bruno D. Rodrigues
fonte
0

Eu diria que se você estiver usando JUnit, você deve usar as asserções JUnit. assertTrue()é basicamente o mesmo que assert, Caso contrário, por que usar JUnit?

CheesePls
fonte
4
Você usaria JUnit para a estrutura de execução de teste. Asserts são realmente uma pequena parte do valor que o JUnit oferece. JUnit sem Assertexigiria mais clichê. assertsem o JUnit, seria necessário escrever uma estrutura inteira.
Yishai
1
Eu estava mais dizendo se você vai usar a ferramenta, USE A FERRAMENTA. declarações assert antigas regulares parecem um pouco tolas em casos de teste JUnit. Eles pertencem ao código real na minha opinião.
CheesePls de
1
@CheesePls "declarações regulares antigas de afirmação" são, na verdade, mais recentes do que as afirmações do JUnit.
Dolmen
0

Isso pode não se aplicar se você usar exclusivamente coisas brilhantes e novas, mas o assert não foi introduzido no Java até 1.4SE. Portanto, se você precisa trabalhar em um ambiente com tecnologia mais antiga, você pode optar pelo JUnit por motivos de compatibilidade.

Dan Coates
fonte