unit tutorial tests test make instalar how example español create java unit-testing junit4 junit3

java - tutorial - Especificar una orden para junit 4 pruebas en el nivel de Método(no nivel de clase)



junit tutorial español (6)

Sé que esta es una mala práctica, pero debe hacerse, o tendré que pasar a la testng . ¿Hay alguna manera, similar a testSuite de JUnit 3, de especificar el orden de las pruebas que se ejecutarán en una clase?


Desde la versión 4.11 de JUnit en adelante, es posible influir en el orden de ejecución de la prueba anotando su clase con @FixMethodOrder y especificando cualquiera de los MethodSorters disponibles. Vea this enlace para más detalles.


Joscarsson y Michael D codifican en mi repositorio github. Espero que no les importe. También proporciono la versión ordenada para la clase Parametrizada. Ya es para usar como dependencia de 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>


Puedo ver varias razones para hacer esto, especialmente cuando uso JUnit para ejecutar pruebas funcionales o probar objetos persistentes. Por ejemplo, considere un objeto Article que persiste en algún tipo de almacenamiento persistente. Si quisiera probar la funcionalidad de inserción, actualización y eliminación en el objeto Article siguiendo el principio de prueba de la unidad "todas las pruebas deben ser reordenables 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, primero tendría que insertar 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 haga 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 ocurre con la ejecución de 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, OrderedRunner Michael D''para usar anotaciones para determinar el orden de las pruebas, solo pensé que deberí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 se coloquen estas pruebas en el archivo, siempre se ejecutarán como order=1 first, order=2 second y last order=3 , no importa si las ejecuta desde Eclipse, usando Ant o de cualquier otra manera.

Implementación a continuación. Primero, la Order anotación.

@Retention(RetentionPolicy.RUNTIME) public @interface Order { public int order(); }

Luego, el OrderedRunner modificado.

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; } }



Si estás seguro de que realmente quieres hacer esto: puede haber una manera mejor, pero esto es todo lo que pude hacer ...

JUnit4 tiene una anotación: @RunWith que le permite anular el Runner predeterminado para sus pruebas.

En su caso, querría crear una subclase especial de BlockJunit4ClassRunner y anular computeTestMethods() para devolver las pruebas en el orden en que las quiere ejecutar. Por ejemplo, supongamos que quiero 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"); } }

Ejecutar esta prueba produce:

C B A

Para su caso específico, desea un comparador que clasifique las pruebas por su nombre en el orden en que desea que se ejecuten. (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 en su nombre ... aunque obviamente usted es libre de implementarlo de la forma que desee.


Utilizando junit 4.11 la this @FixMethodOrder permite establecer un orden específico:

@FixMethodOrder(MethodSorters.NAME_ASCENDING)