Pracuję nad dość dużą aplikacją, z ~ 260 tys. LOC i około 1800 testów jednostkowych w pakiecie. Trochę tła:JUnit Tests: Dlaczego Maven (Surefire) jest o wiele wolniejszy niż działanie w Eclipse?
- Multi-modułowy projekt Maven
- Wszystkie testy wykonywane na osobnym module i JaCoCo służy do sprawdzania pokrycia.
- Testy są składane w niektórych pakietach, a następnie pakiety są włączone do konfiguracji Surefire.
- Korzystanie
SpringJUnit4ClassRunner
aby uruchomić testy - Murowany jest obecnie skonfigurowana tak, aby używać tego samego VM budować i test (
forkCount
równa jeden ireuseForks
równa true). Robi to jestem pewien, że używam zalety Static Context Cache sprężyny (ponowne wykorzystanie tego samegoApplicationContext
na każdy test)
Kiedy prowadzimy testy na nasz rozwój VMS wykorzystaniem Oracle JDK 7u79/80 widzimy bardzo szybko testy. Na przykład dość duża klasa testowa z 50+ metodami testowymi pozwala uruchomić coś około 1: 30 m (w tym czas inicjalizacji kontekstu).
Naszym głównym Dev VM takim jak:
- dwurdzeniowego i5 (z hiperwątkowości SO4 nici wirtualnych)
- 8GB RAM
- średnich, napędami (5K czy 7k2 obr./min)
- Windows 7 x64 działa Oracle JDK tryb Client (-client)
Używamy Jenkinsa jako naszego serwera CI, a Maven (3.2) dba o proces budowania. Mamy architekturę Master + 2 Slaves. Wszystkie maszyny wirtualne są dokładnie takie same:
- 8 Xeon E5 Rdzenie (Real rdzeni)
- 8 GB RAM
- SSD LUN obsługujących maszyny wirtualne (1,2 GB/s średnia przepustowość)
- Debian Linux 8 64
- Oracle JDK na trybie serwera
Pamiętasz te testy, które zazwyczaj 1:30 min uruchomić na naszych Eclipse? Tutaj na serwerze trwają ponad 15 minut! Oto, co już próbowałem zrobić (jak dotąd bezskutecznie.):
- Set MAVEN_OPTS o stałej wielkości sterty (2GB sterty), dużej przestrzeni PermGen, strojonych ustawień GC/dev/urandom jako losowej nasion
- Zainstalowałem JDK o 32 bitach, aby użyć tego samego trybu klienta, którego używamy w urządzeniach Dev.
- Dostrojone na konfigurację Surefire w celu zwiększenia pamięci, dostrojenia GC itp. (Ponieważ nie używam rozwidlonej maszyny wirtualnej do wykonywania testów już wziąłem to, ponieważ nic by to nie zmieniło.)
Dolna linia, czy jest jakaś konkretna reaso n, dlaczego wykonanie Surefire jest znacznie wolniejsze niż uruchomienie JUnit na Eclipse?Piszę o tym przez kilka dni i to naprawdę zaczyna mnie denerwować! Nienawidzę tego, gdy rozwiązanie wydaje się tak bliskie, ale jak dotąd jest tak daleko.
Nie mogłem przetestować z Maven na mojej maszynie Dev, ponieważ nie mogłem przydzielić całej pamięci potrzebnej do tego, ale fragmenty klas (nie cały zestaw testów 1.8k) wciąż okazują się być wolniejsze niż działa na Eclipse.
Rozumiem, że Maven ma wszystkie te fazy i tak dalej, ale różnica nie powinna być tak duża. Nie zgadzasz się?
Wszelkie dane wejściowe będą bardzo cenne. Mogę podać wszelkie dodatkowe informacje, które uznasz za potrzebne!
PS: Murowany v2.17, Maven 3.2.2, JUnit 4.12, Wiosna testowa 3.2.13
Dzięki wielkie!
UPDATE 1
Starałem dezaktywacja JaCoCo na serwerze CI, aby zobaczyć, czy to dotyczy czasów budowy. Tak nie jest. Czasy wykonania pozostają takie same.
Znajdź środowisko, w którym można przeprowadzać testy zarówno w trybie maven, jak i Eclipse, aby wyeliminować obszar problemowy w celu zbudowania narzędzia lub środowiska. Upewnij się, że używasz (lub nie używasz) JaCoCo w obu przypadkach, ponieważ może to znacznie spowolnić wykonywanie testów. Jeśli nic z tego nie pomoże, spróbuj porównać wydajność mavenów z Jenkinsem i bez niego. –
Witam @ogondza. Dzięki za twoje wejście. Czy myślisz, że JaCoCo może tak drastycznie zwiększyć czas realizacji? Spróbuję wyłączyć agenta w Surefire i opublikuję wyniki tutaj. Wielkie dzięki! –
Nigdy nie spotkałem się z tak dużą różnicą. Zwykle kilka sekund między surefire a IDE. Jeśli coś jest o wiele wolniej ... to naprawdę dziwne. Czy istnieje skaner antywirusowy na serwerze CI, który musi skanować każdy nowy plik jar? (Widziałem to na lokalnych komputerach, biorąc 40 minut zamiast 10 minut na serwerze CI) – wemu