java - unitaria - ¿Hay alguna manera de hacer que Eclipse ejecute una prueba JUnit varias veces hasta que falle?
prueba unitaria con junit (7)
No creo que haya una forma integrada para que Junit haga exactamente lo que estás pidiendo.
Si varias ejecuciones producen resultados diferentes, debe tener una prueba unitaria que pruebe ese caso. Lo cual podría ser tan simple como ejecutar un bucle for en los casos de prueba relevantes.
Ocasionalmente tenemos errores que aparecen una vez en cada X carreras. Antes de que las personas revisen cosas (donde se JUnit''d automáticamente), nuestros desarrolladores deben pasar JUnit localmente a través de Eclipse.
¿Hay alguna forma conveniente (integrado o Plugin de alta calidad) para hacer que Eclipse ejecute la misma prueba X veces y detener si hay una falla? ¿Una alternativa a simplemente hacer clic en Ejecutar X veces?
Tenga en cuenta que estoy buscando algo en la interfaz de usuario (por ejemplo, haga clic derecho y diga "Ejecutar X veces" en lugar de simplemente "Ejecutar").
Sé que no responde la pregunta directamente, pero si una prueba no está pasando cada vez que se ejecuta, es un olor conocido como prueba errática . Hay varias causas posibles para esto (de xUnit Test Patterns ):
- Pruebas de interacción
- Suites de prueba interactivas
- Prueba solitaria
- Fuga de recursos
- Optimismo de recursos
- Prueba irrepetible
- Prueba Run War
- Prueba no determinista
Los detalles de cada uno de estos están documentados en el Capítulo 16 de xUnit Test Patterns .
Si el bucle for funciona, entonces estoy de acuerdo con los nos.
Si necesita repetir todo el setup-test-desmontaje, puede usar TestSuite:
- Haga clic derecho en el paquete que contiene la prueba para repetir
- Vaya a Nuevo y elija crear una prueba JUnit SUITE
- Asegúrese de seleccionar solo la prueba que desea repetir y hacer clic para finalizar.
- Edite el archivo para ejecutarlo varias veces.
En el archivo, acaba de encontrar el
addTestSuite(YourTestClass.class)
línea, y envolver eso en un bucle for.
Estoy bastante seguro de que puedes usar addTest en lugar de addTestSuite para que solo ejecute una prueba de esa clase si solo quieres repetir un único método de prueba.
Si realmente desea ejecutar una clase de prueba hasta la falla, necesita su propio corredor.
@RunWith(RunUntilFailure.class)
public class YourClass {
// ....
}
que podría implementarse de la siguiente manera ...
package com.example;
import org.junit.internal.runners.*;
import org.junit.runner.notification.*;
import org.junit.runner.*;
public class RunUntilFailure extends Runner {
private TestClassRunner runner;
public RunUntilFailure(Class<?> klass) throws InitializationError {
this.runner = new TestClassRunner(klass);
}
@Override
public Description getDescription() {
Description description = Description.createSuiteDescription("Run until failure");
description.addChild(runner.getDescription());
return description;
}
@Override
public void run(RunNotifier notifier) {
class L extends RunListener {
boolean fail = false;
public void testFailure(Failure failure) throws Exception { fail = true; }
}
L listener = new L();
notifier.addListener(listener);
while (!listener.fail) runner.run(notifier);
}
}
... liberando código no probado, sintiendo culpabilidad TDD :)
Aquí hay una publicación que escribí que muestra varias formas de ejecutar las pruebas repetidamente con ejemplos de código: http://codehowtos.blogspot.com/2011/04/run-junit-test-repeatedly.html
Puede usar el corredor @Parametrized, o usar el corredor especial incluido en la publicación. También hay una referencia a una implementación @Retry.
Basado en la respuesta de @ akuhn, esto es lo que se me ocurrió: en lugar de funcionar para siempre, esto se ejecutará 50 veces o hasta que falle, lo que ocurra primero.
package com.foo
import org.junit.runner.Description;
import org.junit.runner.Runner;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunListener;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.InitializationError;
public class RunManyTimesUntilFailure extends Runner {
private static final int MAX_RUN_COUNT = 50;
private BlockJUnit4ClassRunner runner;
@SuppressWarnings("unchecked")
public RunManyTimesUntilFailure(final Class testClass) throws InitializationError {
runner = new BlockJUnit4ClassRunner(testClass);
}
@Override
public Description getDescription() {
final Description description = Description.createSuiteDescription("Run many times until failure");
description.addChild(runner.getDescription());
return description;
}
@Override
public void run(final RunNotifier notifier) {
class L extends RunListener {
boolean shouldContinue = true;
int runCount = 0;
@Override
public void testFailure(@SuppressWarnings("unused") final Failure failure) throws Exception {
shouldContinue = false;
}
@Override
public void testFinished(@SuppressWarnings("unused") Description description) throws Exception {
runCount++;
shouldContinue = (shouldContinue && runCount < MAX_RUN_COUNT);
}
}
final L listener = new L();
notifier.addListener(listener);
while (listener.shouldContinue) {
runner.run(notifier);
}
}
}
Es posible implementar dicho bucle con TestRule
s (desde JUnit 4.9)
Una implementación muy simple que ejecuta cada prueba 10 veces:
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
public class SimpleRepeatRule implements TestRule {
private static class SimpleRepeatStatement extends Statement {
private final Statement statement;
private SimpleRepeatStatement(Statement statement) {
this.statement = statement;
}
@Override
public void evaluate() throws Throwable {
for (int i = 0; i < 10; i++) {
statement.evaluate();
}
}
}
@Override
public Statement apply(Statement statement, Description description) {
return new SimpleRepeatStatement(statement);
}
}
uso:
public class Run10TimesTest {
@Rule
public SimpleRepeatRule repeatRule = new SimpleRepeatRule();
@Test
public void myTest(){...}
}
Para una implementación más útil basada en una anotación que defina qué método de prueba debe ejecutarse, con qué frecuencia eche un vistazo a este blog: http://www.codeaffine.com/2013/04/10/running-junit-tests-repeatedly -sin bucles /