2012-04-05 28 views
14

que tienen un conjunto de pruebas JUnit en la forma:Detener suite de JUnit si determinada prueba falla

@RunWith(Suite.class) 
@Suite.SuiteClasses({ xx.class, yy.cass }) 

public class AllTests { 

public static Test suite() { 
    TestSuite suite = new TestSuite(AllTests.class.getName()); 
    //$JUnit-BEGIN$ 

    //$JUnit-END$ 
    return suite; 
} 
} 

Esto luego llama a pruebas de vainilla como este:

public class xxx { 

@Test 
public void test() throws { 
    ... 

tengo una situación en la que había desea detener el resto del paquete de prueba si hay un error o falla en la primera prueba. Pero los errores/fallas en los otros están bien y el conjunto debe completar tantas otras pruebas como sea posible. Básicamente, la primera falla de la prueba indicaría que no es seguro ejecutar el resto.

¿Esto es posible?

Respuesta

6

¿Qué pasa con llamar al System.exit()?

+0

¿Cómo me programación comprobar si una afirmación ha fallado? – Jonathan

+0

Ok, veo que podría detectar AssertionError en la primera prueba y luego llamar a System.exit(), pero entonces la prueba JUnit no pasará o fallará, solo dejará de ejecutarse. Parece que debería haber una manera más elegante. – Jonathan

+5

Re: de una manera más elegante, no creo que JUnit proporcione esta funcionalidad lista para usar. Puede conducir al acoplamiento entre las pruebas. Lo ideal es que sus pruebas se ejecuten de forma independiente y no se vean afectadas por otras fallas. Si insistes, entonces la sugerencia de Hiro2k es la mejor. –

0

¿Estás realizando pruebas con hormiga?

Puede escribir un oyente de prueba personalizado. Puede configurar esto en ant http://ant.apache.org/manual/Tasks/junit.html (enableTestListenerEvents).

+0

Aunque esa es una opción: generalmente no estoy usando Ant (usando Ejecutar como> Prueba JUnit en Eclipse). – Jonathan

+0

¿Cómo crearías ese "oyente de prueba personalizado"? Obtengo la parte ant con haltonfailure = "true", pero dentro de una Suite no se detiene si falla una de las pruebas de Suite. ¿Qué "oyente de prueba personalizado" puede hacer? –

3

Si es primer test, considere la posibilidad de mover su validación a @BeforeClass y lanzar una excepción si falla. Entonces solo se ejecutaría el método @AfterClass en el caso de esta excepción.

Por supuesto, de esa manera te faltan todos los artefactos de artefactos creados en los métodos de configuración de prueba.

3

Basado en la respuesta de Hiro2k (¡gracias!) He utilizado la siguiente solución. Es un truco pero funciona.

La prueba que puede evitar que se ejecuten otras pruebas se encuentra en la parte superior de la lista @ Suite.SuiteClasses. Esa prueba tiene entonces la siguiente:

private static boolean shouldStopRestOfSuite = false; 

    @Test 
    public void test() throws Throwable { 
    try { 
      ... run some test code... 
    } 
    catch (Throwable e) { 
     shouldStopRestOfSuite = true; 
     throw e; 
    } 
} 

cuenta que lo anterior tiene necesidad de coger Throwable (no excepción) por lo que captura los errores de aserción. También vuelve a arrojar el error para que JUnit lo registre para su análisis.

Luego hay otro método de prueba:

@Test 
public void testKillIfNeeded() throws Exception { 
    if (!shouldStopRestOfSuite) { 
     return; 
    } 

    System.out.println ("Test suite killed due to dangerous error/failure"); 
    System.exit(1); 
} 

Lo anterior se ejecute segundo y matará el proceso de JUnit.

Usando este método, la prueba JUnit no finalizará en el error/error si hay un problema pero el error/error se registra para el análisis por JUnit y no se ejecutarán más pruebas.

No es muy bonito pero hace el trabajo :)

2

Al igual que su respuesta pero utilizando @Before en una prueba de integración, hice algo como esto:

public class FooTest { 

    private static boolean bar; 

    @BeforeClass 
    public static void setUpBeforeClass() throws Exception { 
     bar = false; 
    } 

    @Before 
    public void setUp() throws Exception { 
     assertTrue(bar); 
    } 

    @Test 
    public void test() { 
     System.out.println("something"); 
     assertTrue(true); 
    } 

    @Test 
    public void test1() { 
     System.out.println("Something2"); 
     assertTrue(true); 
    } 
} 

Saludos!

10

primer lugar usted necesita RunListener junit:

import org.junit.runner.notification.Failure; 
import org.junit.runner.notification.RunListener; 
import org.junit.runner.notification.RunNotifier; 

public class FailureListener extends RunListener { 

    private RunNotifier runNotifier; 

    public FailureListener(RunNotifier runNotifier) { 
     super(); 
     this.runNotifier=runNotifier; 
    } 

    @Override 
    public void testFailure(Failure failure) throws Exception { 
     super.testFailure(failure); 
     this.runNotifier.pleaseStop(); 
    } 
} 

luego preparar una suite:

public class StopOnFailureSuite extends Suite { 

    public StopOnFailureSuite(Class<?> klass, Class<?>[] suiteClasses) throws InitializationError { 
     super(klass, suiteClasses); 
    } 

    public StopOnFailureSuite(Class<?> klass) throws InitializationError { 
     super(klass, klass.getAnnotation(SuiteClasses.class).value()); 
    } 

    @Override 
    public void run(RunNotifier runNotifier) { 
     runNotifier.addListener(new FailureListener(runNotifier)); 
     super.run(runNotifier); 
    } 
} 

y ejecutar su suite:

@RunWith(StopOnFailureSuite.class) 
@Suite.SuiteClasses({ 
    FirstTestClass.class, 
    SecondTestClass.class, 
    ... 
}) 
+0

Para implementar lo que la pregunta hace, 'FailureListener' no debe detener la prueba en caso de falla. Podría ser mejor filtrar el tipo de falla y solo detener las pruebas en un error específico. por ejemplo, creando su propia clase 'Exception' y lance eso en su' FirstTestClass'. Luego use 'failure.getException()' para determinar si detener la prueba. – artificerpi

1

En primer lugar usted debe coger un error y comprobar la lo mismo antes de ejecutar la segunda prueba.

@Rule 
public ErrorCollector collector = new ErrorCollector(); 

1. Agregar error.

collector.addError(new Throwable("first thing went wrong")); 

2. Comprobar antes de la carrera depende.

collector.checkThat(getResult(), not(containsString("ERROR!"))); 

Referencia - ErrorCollector

Cuestiones relacionadas