2012-02-16 10 views
12

Tengo en mi proyecto muchas pruebas unitarias, escritas en JUnit y TestNG. El proceso de construcción se basa en maven con el plugin surefire.maven - construcción fallida cuando la prueba de la unidad lleva demasiado tiempo

¿Hay alguna forma/complemento para que maven falle la compilación cuando al menos una prueba de unidad toma demasiados segundos? Sé que hay algunos complementos para fallar compilados en TeamCity, Jenkins, pero esto es "demasiado lejos".

En mi proyecto, quiero tener solo pruebas rápidas para que el proceso de prueba de la unidad sea efectivo. Puedo mejorar mis pruebas anteriores pero necesito proteger para los compromisos futuros

+0

Las pruebas de unidades fallidas porque se ejecutan demasiado tiempo son parte del marco que está utilizando para ejecutar estos casos de prueba. ¿Estás usando JUnit o TestNG? – Gaurav

+0

No quiero fallar la prueba de la unidad por separado, quiero fallar toda la compilación si al menos una prueba de unidad lleva demasiado tiempo. Estoy usando JUnit y TestNG – smas

+0

Si fallas una prueba de unidad fallará también la compilación a menos que le preguntes también al plugin. – Gaurav

Respuesta

0

Una vez tuve el mismo requisito, y desde que estaba usando TestNG, utilicé el "group feature".

Si le pegan con JUnit, trate de usar la suite de pruebas (http://stackoverflow.com/questions/817135/grouping-junit-tests)

+1

También puede establecer el timout en el nivel suite en su archivo testng xml. Gaurav

1

Ha intentado especificar el tiempo de espera para la prueba a través @Test (timeout = xx)? Encontrar la documentación de la API oficial aquí: http://junit.sourceforge.net/javadoc/org/junit/Test.html

EDITAR ---

También puede considerar el uso de la propiedad de tiempo de espera para la suite TestNG, se tendrá que mover todas sus pruebas a TestNG sin embargo, pero esto le permitirá para especificar tiempos de espera para grupos.

Esta es la documentación API oficial: http://testng.org/javadoc/org/testng/xml/XmlSuite.html#setTimeOut(java.lang.String)

+1

No puedo hacer esto porque tengo un proyecto bastante grande y una gran cantidad de pruebas. – smas

+0

Revise mi edición, creo que con testNg podrá especificar un tiempo de espera para un conjunto completo –

4

Por qué no añadir un tiempo de espera en una base por prueba. Asumo que está programando en Java, por lo que en JUnit se puede hacer algo como esto:

@Test(timeout=100) public void testQuickly() 

Si la prueba no termina después de 100 milisegundos, se producirá un error.

+2

¿Qué pasa si tiene pruebas de billones y quiere tener un valor constante en segundos para controlar estos requisitos? No se puede establecer por prueba. – smas

4

En maven surefire, puede usar forkedProcessTimeoutInSeconds, junto con forkMode=once.

Esto matará a la JVM ahorquillada si lleva demasiado tiempo. Si desea hacer esto por prueba, puede forkMode = pertest o forkMode = always (que lo hace para cada clase).

+1

en el mundo real - bifurcar no es efectivo – smas

0

Intente utilizar la tarea junit Ant con el parámetro timeout.

http://ant.apache.org/manual/Tasks/junit.html

EDIT:
Otra cosa que puedes hacer es usar aspectj con calle detrás de esa manera:

public aspect TestTimeoutChecker { 
    long TIMEOUT = 60000; 

    pointcut invokeEvent() : 
     execution(@Test * *(..)); 

    Object around() : invokeEvent() { 

     long start = System.currentTimeMillis(); 
     Object object = proceed(); 
     long took = System.currentTimeMillis() - start; 
     if (took > TIMEOUT) { 
      throw new RuntimeException("timeout! it took:" + took); 
     } 
     return object; 
    } 
} 
+0

Lo consideré, pero requiere el modo de horquilla - lo cual es inaceptable en proyectos grandes – smas

9

Si todas las pruebas se extienden alguna clase base, creo que puede pegar @Rule allí que se aplicará a todos los @Test en la clase secundaria.

p. Ej.

import org.junit.rules.Timeout; 
public abstract class BaseTestConfiguration { 
    @Rule public Timeout testTimeout = new Timeout(60000); // 60k ms = 1 minute 
} 

public class ThingTests extends BaseTestConfiguration { 
    @Test 
    public void testThis() { 
     /*will fail if not done in 1 minute*/ 
    } 
    @Test 
    public void testThat() { 
     /*will fail if not done in 1 minute*/ 
    } 
} 

Hemos encontrado que es más fácil que jugar con AspectJ o las directivas de configuración secreta. Es más probable que los desarrolladores descubran las partes de Java que todo el XML secreto de esto y aquello. Puede poner @Before@After y cualquier cantidad de otras directivas junit en la clase base también.

+1

Pero en su escenario tenemos muchos casos de prueba. Necesitamos extender todas las pruebas a BaseTestConfiguration. – om39a

+0

Si bien este es un paso adicional para crear pruebas, esta es de lejos la implementación más fácil que he visto hasta ahora. –

+0

Sí, me di cuenta de que definitivamente era una advertencia crítica, que podría tener que establecer un costo inicial para que todas sus pruebas extiendan algo cuando aún no lo hicieron. Dado que el OP tiene más información que nosotros, pensamos que vale la pena mencionarla de todos modos. –

Cuestiones relacionadas