Qual é a diferença entre falha e erro no JUnit?

93

Estou executando testes JUnit em uma grande base de código e tenho percebido que às vezes recebo "Erros", enquanto outras vezes recebo "Falhas". Qual é a diferença?

Froadie
fonte

Respostas:

116

Ok, acabei de notar um padrão e acho que descobri (corrija-me se estiver errado). Parece-me que as falhas ocorrem quando seus casos de teste falham - ou seja, suas afirmações estão incorretas. Os erros são erros inesperados que ocorrem ao tentar realmente executar o teste - exceções, etc.

Froadie
fonte
5
Porém, se alguma extensão java.lang.AssertionErrorfor lançada, ela será mostrada como uma falha de teste em vez de um erro de teste. Você deve considerar aceitar sua própria resposta porque ela está correta.
ponzao
Sim, essa é exatamente a diferença. E de uma perspectiva pragmática, "não há diferença" - se você obtiver um erro ou falha, será necessário corrigi-lo. Portanto, provavelmente foi um erro contar "falhas" e "erros" separadamente no JUnit. JUnit 4 combina os dois (conforme explicado em uma resposta abaixo).
Jeff Grigg
E se a exceção for esperada, você deve anotar o @Testcom expected = SomeException.class.
Downhillski
@JeffGrigg há uma diferença pragmática. Se um comportamento está sendo confiado em vários casos de teste, ainda posso escrever apenas um caso de teste que afirma esse comportamento, enquanto lança prováveis ​​exceções de tempo de execução não detectadas em todo o resto. Isso quer dizer que o resto dos casos de teste estão testando outra coisa, embora ainda dependam daquele comportamento específico para serem executados. Quando esse comportamento é quebrado, apenas um caso de teste relatará falha enquanto o resto relata erro, e a partir disso eu posso ver que tenho exatamente um bug para corrigir, embora muitos casos de teste não tenham passado.
RonJRH
org.junit.Assert.assertEquals () se falhar, é considerado ERRO pelo relatório HTML JUnit4. Isso contradiz sua declaração (da qual eu estava ciente até agora). Você pode, por favor, esclarecer melhor isso?
Krishnom
15

Se o seu teste lançar uma exceção que não surge através da estrutura de asserção no Junit, ele é relatado como um erro. Por exemplo, um NullPointer ou uma exceção ClassNotFound relatará um erro:

String s = null;
s.trim();

ou,

try {

    // your code
} catch(Exception e) {
    // log the exception
    throw new MyException(e);
}

Dito isso, o seguinte relatará uma falha:

Assert.fail("Failure here");

ou,

Assert.assertEquals(1, 2);

ou mesmo:

throw new AssertionException(e);

Depende da versão do Junit que você está usando. A Junit 4 fará a distinção entre uma falha e um erro, mas a Junit 4 a simplifica apenas como falhas.

O link a seguir fornece informações mais interessantes:

http://www.devx.com/Java/Article/31983/1763/page/2

Neel
fonte
Isso não é exato. A distinção entre falha de teste e erro de teste não desapareceu no JUnit 4. Acabei de testá-lo. O artigo vinculado era enganoso. Ele dizia que "JUnit 4 torna mais simples usando apenas falhas", mas deve enfatizar que JUnit 4 transforma java.lang.AssertionError em falhas de teste, então você não precisa usar junit.framework.AssertionFailedError. O benefício é que você pode começar a escrever asserções de teste no código de produção sem que o projeto seja vinculado ao JUnit. A distinção entre erro de teste e falha de teste também é extremamente útil e seria um retrocesso se removida.
RonJRH
RonJRH, você consegue ver os erros em seu relatório junit padrão?
Neel
Sim Neel. Eu apenas tentei. Não tenho certeza da etique da imagem de link aqui, mas isso mostra o resultado do meu teste: imagebucket.net/abpxucddkvn1/Capture.PNG
RonJRH
6

De "Pragmatic Unit Testing in Java 8 with JUnit":

Assertions (ou asserts) em JUnit são chamadas de método estático que você coloca em seus testes. Cada afirmação é uma oportunidade de verificar se alguma condição é verdadeira. Se uma condição declarada não for verdadeira, o teste para ali mesmo e o JUnit relata uma falha de teste.

(Também é possível que, quando JUnit executa seu teste, uma exceção seja lançada e não detectada. Nesse caso, JUnit relata um erro de teste.)

Matias Elorriaga
fonte
5

O teste abaixo explica a diferença entre o erro do teste e a falha do teste .

Eu comentei a linha que gera erro de teste e falha de teste.

    @Test
    public void testErrorVsTestFailure() {

        final String sampleString = null;

        assertEquals('j', sampleString.charAt(0) );
        //above line throws test error as you are trying to access charAt() method on null reference

        assertEquals(sampleString, "jacob");
        //above line throws Test failure as the actual value-a null , is not equal to expected value-string "jacob"
        }

Portanto, o Junit mostra o erro de teste sempre que você obtém uma exceção e falha no teste quando o valor do resultado esperado não corresponde ao seu valor real

Deen John
fonte
2

Classe de origem: JUnitReportReporter.java

public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites, String defaultOutputDirectory) {
//......

            for (ITestResult tr : (Set) entry.getValue()) {
                TestTag testTag = new TestTag();

                boolean isSuccess = tr.getStatus() == 1;
                if (!(isSuccess)) {
                    if (tr.getThrowable() instanceof AssertionError)
                        ++errors;
                    else {
                        ++failures;
                    }
                }
}

Como você pode ver a linha abaixo no método acima

tr.getThrowable () instanceof AssertionError

a contagem de erros é aumentada quando é uma instância de AssertionError, caso contrário (qualquer Throwable) é contado como falhas.

Roushan
fonte
1

Você está certo de que as falhas vêm dos AssertionErrors lançados pelos métodos de asserção JUnit, ou lançando um AssertionError, ou lançando uma exceção que você declarou em sua @Testanotação, e os erros vêm de outras exceções inesperadas. Mas há uma distinção importante entre eles:

Uma falha significa que seu teste foi executado corretamente e identificou um defeito em seu código.

Um erro pode significar um bug em seu código, mas que você nem estava testando. Também pode significar que o bug está no próprio teste.

Resumindo, uma falha significa que você precisa reescrever o código que está sendo testado. Um erro significa que pode ser o teste de unidade que você precisa reescrever. Pode significar isso mesmo se a falha estiver em seu código, como um NullPointerException, porque você detectou uma falha que nem estava testando, então pode ser sábio testar isso.

MiguelMunoz
fonte
0

Ironicamente, junit e outras estruturas relacionadas a testes (testng, hamcrest) fornecem operações de declaração que verificam a condição e, se ela falhar , "por baixo do capô" um java.lang.AssertionError está sendo lançado, o qual estende java.lang.Error.

Mas de forma alguma contradiz as respostas acima, as quais são totalmente válidas, é claro. Portanto, para marcar o fluxo de teste específico como falha, pode-se lançar AssertionError, no entanto, não tenho certeza se ele está realmente documentado nos manuais correspondentes, porque é mais apropriado usar a API fail () dedicada. Outros tipos de Throwable serão considerados erros, não falhas.

agolubev81
fonte
0

Basicamente, as falhas referem-se a afirmações não cumpridas, enquanto os erros são devidos à execução anormal do teste . e acho que cada IDE tem ícones simbólicos com cores diferentes para aprovado , reprovado e com testes de erro .

Para mais informações, verifique isto .

Soufiane Roui
fonte