2012-02-16 16 views
12

Mam w moim projekcie wiele testów jednostkowych, napisanych w JUnit i TestNG. Proces budowania opiera się na maven z wtyczką surefire.maven - fail build, gdy test jednostkowy trwa zbyt długo

Czy jest jakiś sposób/plugin dla maven, aby nie powiodło się kompilacji, gdy co najmniej jeden test jednostkowy trwa zbyt wiele sekund? Wiem, że istnieje kilka wtyczek, które mogą zawieść w TeamCity, Jenkins, ale jest to "za daleko".

W moim projekcie chcę mieć tylko szybkie testy, aby proces testowania jednostkowego był skuteczny. Mogę poprawić moje stare testy, ale muszę chronić na przyszłe zobowiązania.

+0

Niepowodzenie testów jednostkowych, ponieważ trwają zbyt długo, jest częścią struktury używanej do uruchamiania tych przypadków testowych. Czy używasz JUnit lub TestNG? – Gaurav

+0

Nie chcę odrywać osobnego testu jednostkowego, chcę, aby wszystko się ułożyło, jeśli przynajmniej jeden test jednostkowy trwa zbyt długo. Używam JUnit i TestNG – smas

+0

Jeśli nie uda ci się przetestować jednego urządzenia, nie powiedzie się również jego kompilacja, chyba że nie poprosisz o wtyczkę. – Gaurav

Odpowiedz

0

Miałem kiedyś takie same wymagania, a ponieważ używałem TestNG, użyłem "group feature".

Jeśli utkniesz z JUnit, spróbuj użyć pakietu testów (http://stackoverflow.com/questions/817135/grouping-junit-tests)

+1

Możesz także ustawić limit czasu na poziomie pakietu w pliku testng xml. Gaurav

1

próbowałeś określenie limitu czasu dla testu poprzez @Test (timeout = xx)? Znajdź oficjalnej dokumentacji API tutaj: http://junit.sourceforge.net/javadoc/org/junit/Test.html

EDIT ---

Można również rozważyć użycie właściwość limitu czasu dla pakietu TestNG, trzeba będzie przenieść wszystkie testy TestNG chociaż, ale to pozwolisz określić limity czasu dla grup.

To jest oficjalna dokumentacja API: http://testng.org/javadoc/org/testng/xml/XmlSuite.html#setTimeOut(java.lang.String)

+1

Nie mogę tego zrobić, ponieważ mam dość duży projekt i ogromną liczbę testów. – smas

+0

Sprawdź moją edycję, myślę, że dzięki testNg będziesz mógł określić limit czasu dla całego pakietu –

4

Dlaczego nie dodać timeout w przeliczeniu na podstawie testu. Zakładam, że jesteś programowania w Javie, więc w JUnit można zrobić coś takiego:

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

Jeśli test nie kończy się po 100 milisekundach, zakończy się niepowodzeniem.

+2

Co, jeśli masz testy gazillions i chcesz mieć jedną stałą wartość w sekundach, aby kontrolować te wymagania? Nie można go ustawić na jeden test. – smas

4

W maven surefire można użyć forkedProcessTimeoutInSeconds, wraz z forkMode=once.

To zabije rozwidlone jvm, jeśli potrwa to zbyt długo. Jeśli chcesz to zrobić dla każdego testu, możesz forkMode = pertest lub forkMode = always (co robi to dla każdej klasy).

+1

w prawdziwym świecie - rozwidlenie nie działa – smas

0

Spróbuj użyć zadającego zadania Ant z parametrem timeout.

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

EDIT:
Inną rzeczą, jaką możesz zrobić, to użyć AspectJ z widzielismy cos takiego:

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

Rozważałem to, ale wymaga trybu rozwidlenia - co jest niedopuszczalne w dużych projektach – smas

9

Jeśli wszystkie testy rozszerzyć niektóre klasy bazowej, myślę, że można tam wstawić @Rule, który będzie dotyczył wszystkich @Test w klasie potomnej.

np.

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

Okazało się, że jest to najłatwiejszy zamiast bawić z AspectJ lub tajnych dyrektyw konfiguracyjnych. Devs są bardziej prawdopodobne, aby dowiedzieć się części Java niż wszystkie tajne XML to i tamto. Możesz wstawić @Before@After i dowolną liczbę innych dyrektyw junitowych również w klasie bazowej.

+1

Ale w jego scenariuszu mamy wiele przypadków testowych. Musimy rozszerzyć wszystkie testy do BaseTestConfiguration. – om39a

+0

Chociaż jest to dodatkowy krok do tworzenia testów, jest to zdecydowanie najłatwiejsza implementacja, jaką widziałem. –

+0

Tak, zdałem sobie sprawę, że było to zdecydowanie krytyczne zastrzeżenie, że być może trzeba będzie ponieść początkowy koszt, aby wszystkie testy rozszerzyć, gdy jeszcze tego nie zrobili. Ponieważ PO ma więcej informacji niż my, pomyślałem, że warto o tym wspomnieć. –

Powiązane problemy