¿Cuál es la diferencia entre falla y error en JUnit?

93

Estoy ejecutando pruebas de JUnit en una gran base de código y me he dado cuenta de que a veces obtengo "Errores" mientras que otras veces obtengo "Fallos". ¿Cual es la diferencia?

froadie
fuente

Respuestas:

116

Ok, acabo de notar un patrón y creo que lo he descubierto (corrígeme si me equivoco). Me parece que las fallas se producen cuando fallan sus casos de prueba, es decir, sus afirmaciones son incorrectas. Los errores son errores inesperados que ocurren al intentar ejecutar la prueba: excepciones, etc.

froadie
fuente
5
Aunque si java.lang.AssertionErrorse lanza algo extendido , se mostrará como un error de prueba en lugar de un error de prueba. Debería considerar aceptar su propia respuesta porque es correcta.
ponzao
Sí, esa es exactamente la diferencia. Y desde una perspectiva pragmática, "no hay diferencia", ya que si obtiene un error o una falla, debe solucionarlo. Así que probablemente fue un error contar los "fallos" y los "errores" por separado en JUnit. JUnit 4 combina los dos (como se explica en una respuesta a continuación).
Jeff Grigg
Y si se espera la excepción, debe anotar @Testcon expected = SomeException.class.
Downhillski
@JeffGrigg hay una diferencia pragmática. Si se confía en un comportamiento en varios casos de prueba, todavía puedo escribir solo un caso de prueba que afirme ese comportamiento, mientras que arrojo excepciones de tiempo de ejecución no detectadas en el resto. Esto significa que el resto de los casos de prueba están probando algo más, aunque todavía dependen de ese comportamiento en particular para ejecutarse. Cuando ese comportamiento se rompe, solo un caso de prueba informará el error mientras que el resto informará un error, y de esto puedo ver que tengo exactamente un error para corregir aunque muchos casos de prueba no pasaron.
RonJRH
org.junit.Assert.assertEquals () si falla se considera ERROR por el informe HTML JUnit4. Esto contradice su declaración (que yo conocía hasta ahora). ¿Podrías aclarar más esto?
Krishnom
15

Si su prueba arroja una excepción que no se propaga a través del marco de Assertion en Junit, se informa como un error. Por ejemplo, una excepción NullPointer o ClassNotFound informará un error:

String s = null;
s.trim();

o,

try {

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

Dicho esto, lo siguiente informará una falla:

Assert.fail("Failure here");

o,

Assert.assertEquals(1, 2);

o incluso:

throw new AssertionException(e);

Depende de la versión de Junit que esté utilizando. Junit 4 hará la distinción entre una falla y un error, pero Junit 4 lo simplifica como solo fallas.

El siguiente enlace proporciona entradas más interesantes:

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

Neel
fuente
Esto no es exacto. La distinción entre error de prueba y error de prueba no desaparece en JUnit 4. Acabo de probarlo. El artículo vinculado era engañoso. Decía "JUnit 4 lo hace más simple usando solo fallas", pero debería enfatizar que JUnit 4 convierte java.lang.AssertionError en fallas de prueba para que no tenga que usar junit.framework.AssertionFailedError. El beneficio es que puede comenzar a escribir afirmaciones de prueba en el código de producción sin que el proyecto se vincule a JUnit. La distinción entre error de prueba y falla de prueba también es inmensamente útil y sería un paso atrás si se elimina.
RonJRH
RonJRH, ¿puedes ver los errores en tu informe junit predeterminado?
Neel
Sí Neel. Solo lo probé. No estoy exactamente seguro de la etiqueta de vincular la imagen aquí, pero esto muestra el resultado de mi prueba: imagebucket.net/abpxucddkvn1/Capture.PNG
RonJRH
6

De "Pruebas unitarias pragmáticas en Java 8 con JUnit":

Las afirmaciones (o afirmaciones) en JUnit son llamadas a métodos estáticos que colocas en tus pruebas. Cada afirmación es una oportunidad para verificar que alguna condición se cumple. Si una condición afirmada no se cumple, la prueba se detiene allí mismo y JUnit informa de un error de prueba.

(También es posible que cuando JUnit ejecuta su prueba, se lance una excepción y no se detecte. En este caso, JUnit informa un error de prueba).

Matias Elorriaga
fuente
5

La siguiente prueba explica la diferencia entre el error de prueba y el error de prueba .

He comentado la línea que arroja error de prueba y falla de prueba.

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

Entonces, Junit muestra un error de prueba cada vez que obtiene una excepción, y prueba un error cuando el valor de resultado esperado no coincide con su valor real

Deen John
fuente
2

Clase de fuente: 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 puede ver debajo de la línea en el método anterior

tr.getThrowable () instancia de AssertionError

el recuento de errores aumenta cuando es una instancia de AssertionError, de lo contrario (cualquier Throwable) se cuenta como fallas.

Roushan
fuente
1

Tiene razón en que las fallas provienen de los AssertionErrors lanzados por los métodos de aserción JUnit, o al lanzar un AssertionError, o al lanzar una excepción que declaró en su @Testanotación, y los Errores provienen de otras Excepciones inesperadas. Pero hay una distinción importante entre ellos:

Una falla significa que su prueba se ejecutó correctamente e identificó un defecto en su código.

Un error podría significar un error en su código, pero uno que ni siquiera estaba probando. También podría significar que el error está en la propia prueba.

En resumen, una falla significa que debe volver a escribir el código que se está probando. Un error significa que puede ser la prueba unitaria la que necesita reescribir. Puede significar esto incluso si la falla estaba en su código, como a NullPointerException, porque detectó una falla que ni siquiera estaba probando, por lo que sería prudente probarla.

Miguel Muñoz
fuente
0

Irónicamente, junit y otros marcos relacionados con las pruebas (testng, hamcrest) proporcionan operaciones de aserción que verifican la condición y, si falla , se lanza "bajo el capó" un java.lang.AssertionError, que por cierto extiende java.lang.Error.

Pero de ninguna manera contradice las respuestas anteriores que, por supuesto, son completamente válidas. Entonces, para marcar un flujo de prueba específico como falla, uno puede lanzar AssertionError, sin embargo, no estoy seguro de que esté realmente documentado en los manuales correspondientes, porque es más apropiado usar la API de fail () dedicada. Otros tipos de Throwable se considerarán errores, no fallas.

agolubev81
fuente
0

Básicamente, las fallas se refieren a afirmaciones no cumplidas, mientras que los errores se deben a una ejecución anormal de la prueba . y creo que cada IDE tiene iconos simbólicos con diferentes colores para pruebas aprobadas , fallidas y con errores .

Para obtener más información, consulte esto .

Soufiane Roui
fuente