¿Manera fácil de ejecutar la misma prueba junit una y otra vez?

Como dice el título, estoy buscando una forma simple de ejecutar JUnit 4.x pruebas varias veces seguidas de forma automática utilizando Eclipse.

Un ejemplo sería ejecutar la misma prueba 10 veces seguidas e informar el resultado.

Ya tenemos una forma compleja de hacerlo, pero estoy buscando una forma sencilla de hacerlo, de modo que pueda estar seguro de que la prueba escamosa que he estado tratando de solucionar se mantiene fija.

Una solución ideal sería un plugin / configuración / función de Eclipse que desconozco.

La manera más fácil (como en la cantidad mínima de código nuevo requerido) para hacer esto es ejecutar la prueba como una prueba parametrizada (anotar con @RunWith(Parameterized.class) y agregar un método para proporcionar 10 parámetros vacíos). De esa manera, el marco ejecutará la prueba 10 veces.

Esta prueba debería ser la única en la clase, o mejor, todos los métodos de prueba deberían ejecutarse 10 veces en la clase.

Aquí hay un ejemplo:

 @RunWith(Parameterized.class) public class RunTenTimes { @Parameterized.Parameters public static Object[][] data() { return new Object[10][0]; } public RunTenTimes() { } @Test public void runsTenTimes() { System.out.println("run"); } } 

Con lo anterior, es posible incluso hacerlo con un constructor sin parámetros, pero no estoy seguro de si los autores del framework lo intentaron, o si eso se romperá en el futuro.

Si está implementando su propio corredor, puede hacer que el corredor ejecute la prueba 10 veces. Si está utilizando un corredor @Rule , luego con 4.7, puede usar la nueva anotación @Rule e implementar la interfaz MethodRule para que tome la statement y la ejecute 10 veces en un bucle for. La desventaja actual de este enfoque es que @Before y @Before se ejecutan solo una vez. Es probable que esto cambie en la próxima versión de JUnit (el @Before se ejecutará después de @Rule ), pero independientemente de que actúe en la misma instancia del objeto (algo que no es cierto para el corredor Parameterized ). Esto supone que cualquier corredor con el que ejecute la clase reconoce correctamente las anotaciones @Rule . Ese es solo el caso si está delegando a los corredores JUnit.

Si se está ejecutando con un corredor personalizado que no reconoce la anotación @Rule , entonces realmente está obligado a tener que escribir su propio corredor que delegue apropiadamente en ese corredor y lo ejecute 10 veces.

Tenga en cuenta que hay otras formas de resolver esto (como el corredor de Theories), pero todas requieren un corredor. Desafortunadamente, JUnit actualmente no admite capas de corredores. Ese es un corredor que encadena a otros corredores.

Descubrí que la anotación repetida de Spring es útil para ese tipo de cosas:

 @Repeat(value = 10) 

Último (Spring Framework 4.3.11.RELEASE API) doc:

  • org.springframework.test.annotation
  • Pruebas unitarias en spring

Con IntelliJ, puede hacer esto desde la configuración de prueba. Una vez que abra esta ventana, puede elegir ejecutar la prueba cuantas veces quiera.

enter image description here

cuando ejecuta la prueba, intellij ejecutará todas las pruebas que haya seleccionado para la cantidad de veces que haya especificado.

Ejemplo ejecutando 624 pruebas 10 veces: enter image description here

Inspirado en esta solución :

Use la anotación @Repeat esta manera:

 public class MyTestClass { @Rule public RepeatRule repeatRule = new RepeatRule(); @Test @Repeat(10) public void testMyCode() { //your test code goes here } } 

Solo necesitarás estas dos clases:

Repeat.java:

 import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.ElementType.METHOD; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention( RetentionPolicy.RUNTIME ) @Target({ METHOD, ANNOTATION_TYPE }) public @interface Repeat { int value() default 1; } 

RepeatRule.java:

 import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; public class RepeatRule implements TestRule { private static class RepeatStatement extends Statement { private final Statement statement; private final int repeat; public RepeatStatement(Statement statement, int repeat) { this.statement = statement; this.repeat = repeat; } @Override public void evaluate() throws Throwable { for (int i = 0; i < repeat; i++) { statement.evaluate(); } } } @Override public Statement apply(Statement statement, Description description) { Statement result = statement; Repeat repeat = description.getAnnotation(Repeat.class); if (repeat != null) { int times = repeat.value(); result = new RepeatStatement(statement, times); } return result; } } 

25-10-2016 Edición: Para usar esta solución cuando usas @RunWith(PowerMockRunner.class) , actualiza a Powermock 1.6.5 ( que incluye este parche ).

Con JUnit 5 pude resolver esto usando la anotación @RepeatedTest :

 @RepeatedTest(10) public void testMyCode() { //your test code goes here } 

Tenga en cuenta que la anotación @Test no se debe utilizar junto con @RepeatedTest .

Cualquier cosa mal con:

 @Test void itWorks() { // stuff } @Test void itWorksRepeatably() { for (int i = 0; i < 10; i++) { itWorks(); } } 

A diferencia del caso en el que está probando cada una de una matriz de valores, no le interesa particularmente la ejecución que falló.

No es necesario hacer en la configuración o anotación lo que puede hacer en el código.

Esto funciona mucho más fácil para mí.

 public class RepeatTests extends TestCase { public static Test suite() { TestSuite suite = new TestSuite(RepeatTests.class.getName()); for (int i = 0; i < 10; i++) { suite.addTestSuite(YourTest.class); } return suite; } } 

Hay una anotación intermitente en la biblioteca tempus-fugit que funciona con @Rule JUnit 4.7 para repetir una prueba varias veces o con @RunWith .

Por ejemplo,

 @RunWith(IntermittentTestRunner.class) public class IntermittentTestRunnerTest { private static int testCounter = 0; @Test @Intermittent(repition = 99) public void annotatedTest() { testCounter++; } } 

Después de ejecutar la prueba (con IntermittentTestRunner en @RunWith ), testCounter sería igual a 99.

Construyo un módulo que permite hacer este tipo de pruebas. Pero está enfocado no solo en repetir. Pero en garantía de que alguna pieza de código es Thread safe.

https://github.com/anderson-marques/concurrent-testing

Dependencia de Maven:

  org.lite concurrent-testing 1.0.0  

Ejemplo de uso:

 package org.lite.concurrent.testing; import org.junit.Assert; import org.junit.Rule; import org.junit.Test; import ConcurrentTest; import ConcurrentTestsRule; /** * Concurrent tests examples */ public class ExampleTest { /** * Create a new TestRule that will be applied to all tests */ @Rule public ConcurrentTestsRule ct = ConcurrentTestsRule.silentTests(); /** * Tests using 10 threads and make 20 requests. This means until 10 simultaneous requests. */ @Test @ConcurrentTest(requests = 20, threads = 10) public void testConcurrentExecutionSuccess(){ Assert.assertTrue(true); } /** * Tests using 10 threads and make 20 requests. This means until 10 simultaneous requests. */ @Test @ConcurrentTest(requests = 200, threads = 10, timeoutMillis = 100) public void testConcurrentExecutionSuccessWaitOnly100Millissecond(){ } @Test(expected = RuntimeException.class) @ConcurrentTest(requests = 3) public void testConcurrentExecutionFail(){ throw new RuntimeException("Fail"); } } 

Este es un proyecto de código abierto. Siéntase libre de mejorar.

Puede ejecutar su prueba JUnit desde un método principal y repetirla tantas veces que necesite:

 package tests; import static org.junit.Assert.*; import org.junit.Test; import org.junit.runner.Result; public class RepeatedTest { @Test public void test() { fail("Not yet implemented"); } public static void main(String args[]) { boolean runForever = true; while (runForever) { Result result = org.junit.runner.JUnitCore.runClasses(RepeatedTest.class); if (result.getFailureCount() > 0) { runForever = false; //Do something with the result object } } } }