Sé que esta es una mala práctica, pero es necesario hacerlo, o tendré que cambiar a testng
. ¿Hay alguna manera, similar a testSuite de JUnit 3, de especificar el orden de las pruebas que se ejecutarán en una clase?Especificar una orden para junit 4 pruebas en el nivel Método (no nivel de clase)
Respuesta
Si está seguro de que realmente quiere hacer esto: puede haber una mejor manera, pero esto es todo lo que podía llegar a ...
junit4 tiene una anotación: @RunWith
que permite anula el Runner predeterminado para tus pruebas.
En su caso, usted querrá crear una subclase especial de BlockJunit4ClassRunner
, y anular computeTestMethods()
para devolver las pruebas en el orden en que las quiere ejecutar. Por ejemplo, digamos que yo quiero para ejecutar mis pruebas en orden alfabético inverso:
public class OrderedRunner extends BlockJUnit4ClassRunner {
public OrderedRunner(Class klass) throws InitializationError {
super(klass);
}
@Override
protected List computeTestMethods() {
List list = super.computeTestMethods();
List copy = new ArrayList(list);
Collections.sort(copy, new Comparator() {
public int compare(FrameworkMethod o1, FrameworkMethod o2) {
return o2.getName().compareTo(o1.getName());
}
});
return copy;
}
}
@RunWith(OrderedRunner.class)
public class OrderOfTest {
@Test public void testA() { System.out.println("A"); }
@Test public void testC() { System.out.println("C"); }
@Test public void testB() { System.out.println("B"); }
}
Al ejecutar esta prueba produce:
C B A
para su caso específico, usted quiere un comparador que lo haría clasifique las pruebas por nombre en el orden en que las quiere ejecutar. (Sugeriría definir el comparador usando algo como la clase de Google Guava Ordering.explicit("methodName1","methodName2").onResultOf(...);
donde onResultOf se proporciona una función que convierte FrameworkMethod a su nombre ... aunque obviamente usted es libre de implementar eso de cualquier manera que desee.
Puedo ver varios razones para hacer esto, especialmente cuando se utiliza JUnit para ejecutar pruebas funcionales o probar objetos persistentes. Por ejemplo, considere un objeto Article
que persista en algún tipo de almacenamiento persistente. Si me gustaría probar la funcionalidad de inserción, actualización y eliminación en el Article
objeto siguiendo el principio de la prueba de la unidad "todas las pruebas deben ser reorientables y probar solo una parte específica de la funcionalidad", tendría tres pruebas:
testInsertArticle()
testUpdateArticle()
testDeleteArticle()
Sin embargo, para poder probar la funcionalidad de actualización, me gustaría necesario insertar primero el artículo. Para probar la funcionalidad de eliminación, también necesitaría insertar un artículo. Por lo tanto, en la práctica, la funcionalidad de inserción ya se ha probado tanto en testUpdateArticle()
como en testDeleteArticle()
. Entonces es tentador simplemente crear un método de prueba testArticleFunctionality()
que lo hace todo, pero los métodos de este tipo se volverán enormes (y no solo probarán parte de la funcionalidad del objeto Article
).
Lo mismo vale para ejecutar pruebas funcionales contra, por ejemplo, una API relajante. JUnit también es excelente para estos casos si no fuera por el orden indeterminado de las pruebas.
Dicho esto, amplié Michael D's OrderedRunner
para usar anotaciones para determinar el orden de las pruebas, solo pensé que debía compartirlas. Se puede ampliar aún más, por ejemplo, especificando exactamente de qué pruebas depende cada prueba, pero esto es lo que estoy usando por ahora.
Así es como se usa. Evita la necesidad de nombrar pruebas como AA_testInsert()
, AB_testUpdate()
, AC_testDelete()
, ..., ZC_testFilter()
, etc.
@RunWith(OrderedRunner.class)
public class SomethingTest {
@Test
@Order(order=2)
public void testUpdateArticle() {
// test update
}
@Test
@Order(order=1)
public void testInsertArticle() {
// test insert
}
@Test
@Order(order=3)
public void testDeleteArticle() {
// test delete
}
}
No importa cómo estas pruebas se colocan en el archivo, siempre van a ser ejecutados como order=1
primera, order=2
segundo y último order=3
, no importa si ellos se ejecutan desde dentro de Eclipse, utilizando Ant, o cualquier otra forma .
Implementación a continuación. Primero, la anotación Order
.
@Retention(RetentionPolicy.RUNTIME)
public @interface Order {
public int order();
}
Luego, modificó OrderedRunner
.
public class OrderedRunner extends BlockJUnit4ClassRunner {
public OrderedRunner(Class<?> klass) throws InitializationError {
super(klass);
}
@Override
protected List<FrameworkMethod> computeTestMethods() {
List<FrameworkMethod> list = super.computeTestMethods();
Collections.sort(list, new Comparator<FrameworkMethod>() {
@Override
public int compare(FrameworkMethod f1, FrameworkMethod f2) {
Order o1 = f1.getAnnotation(Order.class);
Order o2 = f2.getAnnotation(Order.class);
if (o1 == null || o2 == null)
return -1;
return o1.order() - o2.order();
}
});
return list;
}
}
+1 para el orden basado en anotaciones en lugar de alfabéticamente – Matt
Exactamente lo que quería encontrar . Podría haber sido mejor si el método de anotación fue 'value()' y simplemente escriba '@Order (1)' – lyomi
He seguido su código, funciona muy bien, pero después de importar el mismo código a los casos de prueba que tiene 50 casos de prueba I tenía el error 'initializationerror0'. Estoy usando Kepler con JUnit4.10 – yashhy
Si desea ejecutar las pruebas JUnit en orden "tal como se presentan en el código fuente", y no desea modificar el código de pruebas, ver mi nota sobre esto aquí:
How to run junit tests in order as they present in your source code
Pero realmente no es una buena idea, las pruebas deben ser independientes.
Desde JUnit versión 4.11 en adelante, es posible influir en el orden de ejecución de la prueba al anotar su clase con @FixMethodOrder
y especificar cualquiera de los MethodSorters
disponibles. Vea el enlace this para más detalles.
Usando junit 4.11
la new annotation@FixMethodOrder
permite establecer un orden específico:
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
Así que, en mi caso, la razón por la que estoy buscando esto -similar al cartel de arriba y su objeto de "artículo" - es que si la primera prueba falla no se moleste en ejecutar las otras, ya que están usando una característica probada por la primera prueba. Para ese fin, lo que me gustaría es, si la primera prueba falla, que las pruebas restantes arrojen algo así como 'AssumptionViolatedException' (haciendo que las pruebas se etiqueten como 'omitidas' en mi corredor particular, intelliJ). Puedo hacer esto con if-statements y fields, pero me pregunto si JUnit tiene una facilidad mejor incorporada. ¿Alguna idea? – Groostav
@Groostav Hay 'assumeTrue()'/'assumeThat()' etc. Puede hacer que la primera prueba establezca un booleano estático en la clase de prueba a 'true' si pasa y luego' assumeTrue (flag) 'en las otras pruebas , por ejemplo. O puede verificarlo solo una vez en un método '@ Before' (necesita otro indicador o un indicador de tres estados para omitir el control la primera vez antes de que se ejecute la primera prueba). –
Joscarsson y Michael D código en mi repo GitHub. Espero que no les importe. También proporciono la versión ordenada para la clase Parametrizada. Ya es para usar como dependencia maven
<repositories>
<repository>
<id>git-xxx</id>
<url>https://github.com/crsici/OrderedRunnerJunit4.11/raw/master/</url>
</repository>
</repositories>
<dependency>
<groupId>com.sici.org.junit</groupId>
<artifactId>ordered-runner</artifactId>
<version>0.0.1-RELEASE</version>
</dependency>
- 1. Diferencia de nivel bajo: clase no estática con método estático vs. clase estática con método estático
- 2. Ejecutar todas las pruebas en Junit 4
- 3. clase genérica y la interacción restricciones de tipo nivel Método
- 4. ¿Alguien puede explicarme la diferencia entre el controlador de nivel de clase y el controlador de nivel de método ...?
- 5. ¿Por qué el soporte de C# no es const en un nivel de clase/método?
- 6. Reemplazar un método en el nivel de instancia
- 7. Conjunto de pruebas Junit 4 y clases de prueba individuales
- 8. Maven 2 No se ejecuta Junit 4 Pruebas
- 9. Agrupando pruebas de JUnit
- 10. C#: (Estático) Variables de nivel de clase
- 11. Bloqueo de nivel de clase Java vs. bloqueo de nivel de objeto
- 12. "Advertencia de memoria recibida. Nivel = 2" con 4.x?
- 13. anotaciones de nivel de clase vs interfaces
- 14. Ruby Minitest: ¿Configuración de nivel Suite o Clase?
- 15. @parameters en Junit 4
- 16. Android - Procedimiento para interceptar un POST forma en WebViewClient androide en el nivel API 4
- 17. Descripción Atributos a nivel de clase
- 18. ¿Hay un atributo Condicional en el nivel de clase?
- 19. jUnidad: ¿Cómo determinar el nivel de cobertura del código?
- 20. Maven no encuentra pruebas JUnit para ejecutar
- 21. Propiedades de solo lectura de nivel de clase en Python
- 22. ¿Las pruebas de software deberían convertirse realmente en un concepto de primera clase a nivel académico?
- 23. No se puede entender el comando de nivel de nivel en TCL
- 24. ¿Usando diferentes clasificadores para diferentes pruebas JUnit?
- 25. Pruebas de JUnit para POJOs
- 26. Recorrido de orden de nivel de un árbol binario
- 27. ¿Sigue siendo una buena práctica ejecutar pruebas con JUnit 3.x vs JUnit 4.x?
- 28. Travesía de orden de nivel de árbol binario
- 29. Suites paramétricas en Junit 4?
- 30. Scala: Especificar método público de primer orden método
Gracias por tomarse el tiempo para responder a esto Michael. –
Eso es útil, ¡gracias! Por cierto, necesitaba hacer un pequeño cambio para compilarlo: "nuevo comparador()" -> "nuevo comparador()" –
kc2001