Qual è la differenza tra fallimento ed errore in JUnit?


93

Sto eseguendo i test JUnit su una vasta base di codice e mi sono reso conto che a volte ottengo "Errori" mentre altre volte ottengo "Errori". Qual è la differenza?

Risposte:


116

Ok, ho appena notato uno schema e penso di averlo capito (correggimi se sbaglio). Mi sembra che gli errori si verifichino quando i tuoi casi di test falliscono, ovvero le tue affermazioni non sono corrette. Gli errori sono errori imprevisti che si verificano durante il tentativo di eseguire effettivamente il test: eccezioni, ecc.


5
Tuttavia, se java.lang.AssertionErrorviene lanciato qualcosa che si estende , verrà mostrato come un fallimento del test invece di un errore del test. Dovresti considerare di accettare la tua risposta perché è corretta.
ponzao

Sì, questa è esattamente la differenza. E da una prospettiva pragmatica non c'è "nessuna differenza" - in quanto se ottieni un errore o un fallimento, devi risolverlo. Quindi è stato probabilmente un errore contare "fallimenti" ed "errori" separatamente in JUnit. JUnit 4 combina i due (come spiegato in una risposta di seguito).
Jeff Grigg

E se è prevista l'eccezione, è necessario annotare @Testcon expected = SomeException.class.
Downhillski

@ JeffGrigg c'è una differenza pragmatica. Se si fa affidamento su un comportamento in più casi di test, posso comunque scrivere solo un caso di test che asserisca quel comportamento, mentre lancio eccezioni non rilevate, probabilmente di runtime in tutto il resto. Questo significa che il resto dei casi di test sta testando qualcos'altro anche se dipendono ancora da quel particolare comportamento per funzionare. Quando quel comportamento viene interrotto, solo un caso di test segnalerà un errore mentre il resto segnala l'errore, e da questo posso vedere che ho esattamente un bug da correggere anche se molti casi di test non sono stati superati.
RonJRH

org.junit.Assert.assertEquals () se fallisce è considerato ERRORE dal report HTML JUnit4. Ciò contraddice la tua affermazione (di cui ero a conoscenza fino ad ora). Puoi per favore mettere più luce su questo?
Krishnom

15

Se il test genera un'eccezione che non viene ribaltata tramite il framework di asserzioni in Junit, viene segnalata come errore. Ad esempio, un'eccezione NullPointer o ClassNotFound segnalerà un errore:

String s = null;
s.trim();

o,

try {

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

Detto questo, verrà segnalato un guasto:

Assert.fail("Failure here");

o,

Assert.assertEquals(1, 2);

o anche:

throw new AssertionException(e);

Dipende dalla versione di Junit che stai utilizzando. Junit 4- farà la distinzione tra un fallimento e un errore, ma Junit 4 lo semplifica solo come fallimenti.

Il seguente collegamento fornisce input più interessanti:

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


Questo non è accurato. La distinzione tra il fallimento del test e l'errore del test non è andata in JUnit 4. L'ho appena testato. L'articolo collegato era fuorviante. Diceva "JUnit 4 rende tutto più semplice utilizzando solo errori" ma dovrebbe sottolineare che JUnit 4 trasforma java.lang.AssertionError in errori di test, quindi non è necessario utilizzare junit.framework.AssertionFailedError. Il vantaggio è che puoi iniziare a scrivere asserzioni di test nel codice di produzione senza che il progetto si colleghi a JUnit. Anche la distinzione tra errore del test e fallimento del test è immensamente utile e sarebbe un passo indietro se rimossa.
RonJRH

RonJRH, sei in grado di vedere gli errori nel tuo rapporto junit predefinito?
Neel

Sì Neel. L'ho appena provato. Non sono esattamente sicuro dell'etica del collegamento dell'immagine qui, ma questo mostra il risultato del mio test: imagebucket.net/abpxucddkvn1/Capture.PNG
RonJRH

6

Da "Pragmatic Unit Testing in Java 8 con JUnit":

Le asserzioni (o asserzioni) in JUnit sono chiamate di metodi statici che inserisci nei tuoi test. Ogni affermazione è un'opportunità per verificare che alcune condizioni siano vere. Se una condizione asserita non è vera, il test si interrompe proprio lì e JUnit segnala un errore del test.

(È anche possibile che quando JUnit esegue il test, viene generata un'eccezione e non viene rilevata. In questo caso, JUnit riporta un errore di test.)


5

Il test sottostante spiega la differenza tra Errore di test e Fallimento del test .

Ho commentato la riga che genera errore di test e fallimento del test.

    @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"
        }

Quindi Junit mostra un errore di test ogni volta che si ottiene un'eccezione e un errore di test quando il valore del risultato atteso non corrisponde al valore effettivo


2

Classe di origine: 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;
                    }
                }
}

Come puoi vedere sotto la riga nel metodo sopra

tr.getThrowable () instanceof AssertionError

il conteggio degli errori aumenta quando si tratta di un'istanza di AssertionError altrimenti (qualsiasi Throwable) viene conteggiato come errori.


1

Hai ragione che gli errori provengono dagli AssertionErrors lanciati dai metodi di asserzione JUnit, o lanciando un AssertionError, o generando un'eccezione che hai dichiarato nella tua @Testannotazione, e gli errori provengono da altre eccezioni impreviste. Ma c'è un'importante distinzione tra di loro:

Un errore significa che il test è stato eseguito correttamente e ha identificato un difetto nel codice.

Un errore potrebbe significare un bug nel tuo codice, ma che non stavi nemmeno testando. Potrebbe anche significare che il bug è nel test stesso.

In breve, un errore significa che è necessario riscrivere il codice che viene testato. Un errore significa che potrebbe essere lo unit test che devi riscrivere. Può significare questo anche se l'errore era nel tuo codice, ad esempio a NullPointerException, perché hai rilevato un difetto per il quale non stavi nemmeno testando, quindi potrebbe essere saggio testarlo.


0

Ironia della sorte, junit e altri framework relativi ai test (testng, hamcrest) forniscono operazioni di asserzione che verificano la condizione e, se fallisce, viene lanciato "sotto il cofano" un java.lang.AssertionError, che btw estende java.lang.Error.

Ma non è affatto in contraddizione con le risposte di cui sopra che sono ovviamente pienamente valide. Quindi, per contrassegnare un flusso di test specifico come errore, si può lanciare AssertionError, tuttavia non sono sicuro che sia realmente documentato nei manuali corrispondenti, perché è più appropriato utilizzare l'API fail () dedicata. Altri tipi di Throwable saranno considerati errori, non fallimenti.


0

Fondamentalmente, i fallimenti si riferiscono ad asserzioni non soddisfatte mentre gli errori sono dovuti a un'esecuzione anormale del test . e penso che ogni IDE abbia icone simboliche con colori diversi per test passati , falliti e con errori .

Per ulteriori informazioni, controlla questo .

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.