2012-02-16 24 views
12

Ho nel mio progetto molti test unitari, scritti in JUnit e TestNG. Il processo di costruzione è basato su Maven con plugin surefire.Maven - fail build quando il test dell'unità richiede troppo tempo

C'è un modo/plug-in per far sì che Maven non riesca a generare la build quando almeno un test di unità richiede troppi secondi? So che ci sono alcuni plug-in per il fail build in TeamCity, Jenkins ma questo è "troppo lontano".

Nel mio progetto voglio avere solo test rapidi per avere un processo di test unitario efficace. Posso migliorare i miei vecchi test ma devo proteggere per gli impegni futuri

+0

I test delle unità in errore perché sono troppo lunghi fanno parte del framework che si sta utilizzando per eseguire questi test case. Stai usando JUnit o TestNG? – Gaurav

+0

Non voglio fallire il test di unità separate, voglio fallire tutte le build se almeno un test di unità richiede troppo tempo. Sto usando JUnit e TestNG – smas

+0

Se fallisci un test di unità, fallirà anche la compilazione, a meno che tu non chieda anche il plugin. – Gaurav

risposta

0

Una volta avevo lo stesso requisito e, poiché utilizzavo TestNG, usavo lo "group feature".

Se sei bloccato con JUnit, provare a utilizzare la suite di test (http://stackoverflow.com/questions/817135/grouping-junit-tests)

+1

Puoi anche impostare il timeout a livello di suite nel tuo file xml testng. Gaurav

1

Hai provato specificando il timeout per la prova attraverso @Test (timeout = xx)? Trova la documentazione API ufficiale qui: http://junit.sourceforge.net/javadoc/org/junit/Test.html

EDIT ---

Si può anche considerare utilizzando la proprietà di timeout per la suite TestNG, si dovrà spostare tutti i test a TestNG però, ma questo vi permetterà di per specificare i timeout per i gruppi.

Questa è la documentazione ufficiale api: http://testng.org/javadoc/org/testng/xml/XmlSuite.html#setTimeOut(java.lang.String)

+1

Non riesco a farlo perché ho un progetto abbastanza grande e una quantità enorme di test. – smas

+0

Controlla la mia modifica, penso che con testNg sarai in grado di specificare un timeout per un'intera suite –

4

Perché non aggiungi un timeout su una base per test. Presumo che stai programmazione in Java, quindi in JUnit si può fare qualcosa di simile:

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

Se il test non finisce dopo 100 millisecondi, fallirà.

+2

Cosa succede se hai dei test sui gazillions e vuoi avere un valore costante in secondi per controllare questi requisiti? Non può essere impostato per test. – smas

4

In maven surefire, è possibile utilizzare forkedProcessTimeoutInSeconds, insieme a forkMode=once.

Questo ucciderà il jvm a forcella se richiede troppo tempo. Se vuoi eseguire questo test, puoi forkMode = pertest o forkMode = always (che lo fa per ogni classe).

+1

nel mondo reale - la biforcazione non è efficace – smas

0

Provare a utilizzare l'attività Ant junit con il parametro di timeout.

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

EDIT:
Un'altra cosa che puoi fare è quello di utilizzare aspectj con someting così:

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

L'ho preso in considerazione, ma richiede la modalità a forcella - che non è accettabile nei grandi progetti – smas

9

Se tutti i test si estendono un po 'di classe di base, io pensi può attaccare @Rule lì che si applica a tutti i @Test nella classe figlio.

ad es.

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*/ 
    } 
} 

Abbiamo trovato che questo è più facile, piuttosto che fare scherzi con AspectJ o direttive di configurazione segreti. Gli sviluppatori sono più propensi a capire le parti Java di tutti gli XML segreti, questo e quello. È possibile inserire @Before@After e qualsiasi numero di altre direttive junit nella classe base.

+1

Ma nel suo scenario abbiamo molti casi di test. Abbiamo bisogno di estendere tutti i test a BaseTestConfiguration. – om39a

+0

Mentre questo è un ulteriore passo per la creazione di test, questa è di gran lunga l'implementazione più semplice che abbia mai visto. –

+0

Sì, mi sono reso conto che era sicuramente un avvertimento critico, che potrebbe essere necessario inserire un costo iniziale per ottenere tutti i test per estendere qualcosa quando non lo avevano già fatto. Dal momento che l'OP ha più informazioni di quante ne abbiamo, ha ritenuto che ne valesse comunque la pena. –

Problemi correlati