Jak sprawić, by testy jednostkowe działały szybko?

40

Osiągnęliśmy punkt w naszym projekcie, w którym mamy prawie tysiąc testów, a ludzie przestali męczyć się z ich uruchomieniem przed sprawdzeniem, ponieważ trwa to tak długo. W najlepszym wypadku przeprowadzają testy, które są związane z fragmentem kodu, który zmienili, aw najgorszym sprawdzają to bez testowania.

Uważam, że ten problem wynika z faktu, że rozwiązanie rozwinęło się do 120 projektów (zwykle wykonujemy znacznie mniejsze projekty i to dopiero drugi raz, gdy robimy TDD poprawnie), a czas kompilacji + testu wydłużył się do około 2-3 minut na mniejszych maszynach.

Jak obniżyć czas wykonywania testów? Czy są jakieś techniki? Udajesz więcej? Udajesz mniej? Może większe testy integracyjne nie powinny uruchamiać się automatycznie podczas uruchamiania wszystkich testów?

Edycja: w odpowiedzi na kilka odpowiedzi używamy już CI i serwera kompilacji, dlatego wiem, że testy się nie powiodły. Problem (właściwie symptom) polega na tym, że ciągle otrzymujemy wiadomości o nieudanych kompilacjach. Przeprowadzanie częściowych testów jest czymś, co robi większość ludzi, ale nie wszyscy. a jeśli chodzi o testy, są one naprawdę dobrze wykonane, używają podróbek do wszystkiego i nie ma w ogóle IO.

Ziv
źródło
8
Uzyskaj lepszy sprzęt? Sprzęt jest tani w porównaniu do czasu programisty.
Bryan Oakley,
18
Sugerujesz już rozwiązanie w swoim pytaniu: uruchamiaj tylko te testy, które dotyczą fragmentu kodu, który został zmieniony. Okresowo uruchamiaj cały zestaw testów, jako część cyklu QA / Release. To powiedziawszy, od 2 do 3 minut nie zabiera dużo czasu, więc może się zdarzyć, że zespół programistów zbyt często się sprawdza.
Robert Harvey,
3
Pierwszy punkt odniesienia, aby dowiedzieć się, skąd bierze się koszt wydajności. Czy jest kilka drogich testów, czy to zwykła liczba testów? Czy niektóre konfiguracje są drogie?
CodesInChaos
13
Cholera, chciałbym, żeby nasze testy trwały tylko 2-3 minuty. Przeprowadzenie wszystkich naszych testów jednostkowych zajmuje 25 minut - i nie mamy jeszcze żadnych testów integracyjnych.
Izkata
4
2 do 3 minut? Jezu. Nasze mogą trwać kilka godzin ...
Roddy z mrożonego groszku

Odpowiedzi:

51

Możliwym rozwiązaniem byłoby przeniesienie części testowej z maszyn programistycznych do konfiguracji ciągłej integracji ( na przykład Jenkins ) za pomocą oprogramowania do kontroli wersji o dowolnym smaku ( git , svn itp.).

Kiedy trzeba napisać nowy kod, dany programista utworzy gałąź dla wszystkiego, co robią w repozytorium. Wszystkie prace zostaną wykonane w tej gałęzi i mogą zatwierdzić swoje zmiany w gałęzi w dowolnym momencie, nie psując głównego wiersza kodu.

Po zakończeniu danej funkcji, naprawy błędu lub czegokolwiek, nad czym pracują, gałąź może zostać z powrotem połączona z magistralą (lub jak wolisz to zrobić), w której przeprowadzane są wszystkie testy jednostkowe. Jeśli test się nie powiedzie, scalenie zostanie odrzucone, a programista zostanie powiadomiony, aby mógł naprawić błędy.

Możesz także zlecić serwerowi CI przeprowadzanie testów jednostkowych dla każdej gałęzi funkcji, gdy dokonywane są zatwierdzenia. W ten sposób programista może wprowadzić pewne zmiany, zatwierdzić kod i pozwolić serwerowi na uruchomienie testów w tle, podczas gdy nadal będą pracować nad dodatkowymi zmianami lub innymi projektami.

Świetny przewodnik po jednym ze sposobów przeprowadzenia takiej konfiguracji można znaleźć tutaj (specyficzny dla git, ale powinien działać w przypadku innych systemów kontroli wersji): http://nvie.com/posts/a-successful-git-branching-model/

Mikrofon
źródło
15
To. Jeśli programiści „przestali męczyć się z ich uruchomieniem (testy jednostkowe) przed dokonaniem odprawy”, to chcesz, aby konfiguracja CI uruchamiała je po odprawie.
Carson63000,
+1: Dalszą poprawą byłaby modularyzacja testów. Jeśli określony moduł / plik nie zmienił się od ostatniego uruchomienia, nie ma powodu, aby ponownie uruchamiać testy odpowiedzialne za jego testowanie. Coś jak makefile, który nie rekompiluje wszystkiego tylko dlatego, że jeden plik się zmienił. Może to wymagać trochę pracy, ale prawdopodobnie zapewni również czystsze testy.
Leo
Czy metodologia rozgałęziania będzie działać z TFS? Piszemy C # w TFS, a rozgałęzianie w TFS jest mniej przyjazne niż w git. Wierzę, że ten pomysł zostanie nawet odrzucony, ponieważ nigdy nie rozgałęziamy się.
Ziv
Nie mam osobistego doświadczenia w pracy z TFS; udało mi się jednak natknąć na ten przewodnik od Microsoftu, który wydaje się przedstawiać podobną strategię rozgałęziania do tego w poście: msdn.microsoft.com/en-us/magazine/gg598921.aspx
Mike
33

Większość testów jednostkowych powinna trwać mniej więcej 10 milisekund. Mając „prawie tysiąc testów” jest nic i powinien być może kilka sekund, aby uruchomić.

Jeśli nie są, powinieneś przestać pisać wysoce sprzężone testy integracyjne (chyba, że ​​tego właśnie potrzebuje kod) i zacząć pisać dobre testy jednostkowe (zaczynając od dobrze oddzielonego kodu i właściwego użycia podróbek / makiet / skrótów itp.). To sprzężenie wpłynie na jakość testu i czas potrzebny na ich napisanie - więc nie chodzi tylko o skrócenie czasu wykonywania testu.

Telastyn
źródło
30
Cóż, prawdopodobnie nie powinieneś przestać pisać testów integracyjnych i innych niejednostkowych testów automatycznych, ponieważ są one przydatne same w sobie. Po prostu nie należy mylić ich z testami jednostkowymi i trzymać je osobno, częściowo dlatego, że są wolniejsze.
2
Masz rację, że wydają się to być testy integracyjne.
Tom Squires,
9
Ta odpowiedź nie jest produktywna. Po pierwsze, stawia nieuzasadnione oczekiwania. W samej strukturze testów jednostkowych występują koszty ogólne; że każdy test trwa krócej niż milisekundę, nie oznacza, że ​​tysiąc testów musi trwać krócej niż kilka sekund. To, że cały zestaw testów OP kończy się w ciągu 2-3 minut, jest bardzo dobrym znakiem, pod wieloma względami.
rwong
6
@rwong - przepraszam, nazywam bzdury. Metryka, którą otrzymałem, polegała na uruchomieniu dwóch różnych dostępnych projektów profesjonalnych: jednego z ~ 300 testami, jednego z ~ 30000 testów i spojrzenia na środowiska testowe. Zestaw testów zajmujący 2-3 minuty dla <1000 testów jest okropny i świadczy o tym, że testy nie są wystarczająco izolowane.
Telastyn
2
@rwong W tym samym duchu co Telastyn, oto punkt danych ode mnie: nawet z kilkoma większymi niż idealne testami, framework testowy ( py.test) robi mnóstwo magii w tle, a wszystko to czysty kod Pythona („100x wolniej niż C ”), przeprowadzenie około 500 testów w moim projekcie zajmuje mniej niż 6 sekund na powolnym netbooku sprzed kilku lat. Liczba ta jest z grubsza liniowa pod względem liczby testów; podczas gdy istnieje pewne obciążenie początkowe, jest ono amortyzowane we wszystkich testach, a obciążenie ogólne na test wynosi O (1).
16

Jest kilka metod, które wykorzystałem do rozwiązania podobnego problemu:

  1. Sprawdź czas wykonania i znajdź wszystkie najwolniejsze testy, a następnie przeanalizuj, dlaczego wykonanie ich zajmuje tyle czasu .
  2. Masz 100 projektów, być może nie musisz ich budować i testować za każdym razem? Czy potrafisz biegać jak najbardziej nietolerancyjnie tylko w nocy? Utwórz kilka „szybkich” konfiguracji kompilacji do codziennego użytku . Serwer CI będzie wykonywał tylko ograniczony zestaw najjaśniejszych projektów związanych z „gorącymi” częściami twojego obecnego procesu programistycznego .
  3. Kpij i izoluj wszystko, co możesz , unikaj dyskowych / sieciowych we / wy, gdy tylko jest to możliwe
  4. Jeśli nie można wyodrębnić takich operacji, być może masz testy integracyjne? Czy możesz zaplanować testy integracyjne tylko na kompilacje nocne ?
  5. Sprawdź wszystkie okazjonalne singletony, które przechowują odwołania do instancji / zasobów i zajmują pamięć, może to prowadzić do obniżenia wydajności podczas uruchamiania wszystkich testów.

Ponadto możesz użyć następujących narzędzi, aby ułatwić sobie życie i przyspieszyć testy

  1. Zatwierdzone bramkowane niektóre serwery CI można skonfigurować do wykonywania kompilacji i testowania przed przekazaniem kodu do repozytorium źródłowego. Jeśli ktoś zatwierdzi kod bez uprzedniego uruchomienia wszystkich testów, który zawiera również testy zakończone niepowodzeniem, zostanie odrzucony i zwrócony autorowi.
  2. Skonfiguruj serwer CI, aby równolegle wykonywał testy : przy użyciu kilku maszyn lub procesów. Przykładami są pnunitkonfiguracja CI z kilkoma węzłami.
  3. Ciągłe testowanie wtyczki dla programistów, która automatycznie uruchomi wszystkie testy podczas pisania kodu.
Akim
źródło
12

0. Słuchaj swoich programistów.

Jeśli nie przeprowadzają testów, oznacza to, że postrzegają koszt (oczekiwanie na uruchomienie testów, radzenie sobie z fałszywymi awariami) na wartość wyższą niż wartość (natychmiastowe wykrywanie błędów). Zmniejsz koszty, zwiększ wartość, a ludzie będą przeprowadzać testy przez cały czas.

1. Sprawdź, czy testy są w 100% wiarygodne.

Jeśli kiedykolwiek zdarzy Ci się test, który zakończy się niepowodzeniem z fałszywymi negatywami, zrób to natychmiast. Napraw je, zmień, wyeliminuj, bez względu na wszystko, aby zagwarantować 100% niezawodności. (Można mieć zestaw niewiarygodnych, ale wciąż przydatnych testów, które można uruchomić osobno, ale główny zestaw testów musi być niezawodny).

2. Zmień swoje systemy, aby zagwarantować, że wszystkie testy przebiegną cały czas.

Użyj systemów ciągłej integracji, aby upewnić się, że tylko zatwierdzające przekazywanie zostaną włączone do głównej / oficjalnej / wydania / dowolnej gałęzi.

3. Zmień swoją kulturę na wartość 100% pozytywnych testów.

Naucz lekcji, że zadanie nie jest „wykonane”, dopóki nie przejdzie 100% testów i zostanie ono włączone do głównej / oficjalnej / wydania / dowolnej gałęzi.

4. Wykonaj testy szybko.

Pracowałem nad projektami, w których testy trwają sekundę, oraz nad projektami, w których trwają cały dzień. Istnieje silna korelacja między czasem potrzebnym do uruchomienia testów a moją produktywnością.

Im dłużej trwają testy, tym rzadziej będziesz je uruchamiać. Oznacza to, że dłużej będziesz otrzymywać informacje zwrotne o wprowadzanych zmianach. Oznacza to również, że będziesz przechodził dłużej między zatwierdzeniami. Częste zatwierdzanie oznacza mniejsze kroki, które łatwiej jest scalić; łatwiej jest śledzić historię zatwierdzeń; łatwiej znaleźć błąd w historii; cofanie jest również łatwiejsze.

Wyobraź sobie testy, które działają tak szybko, że nie przeszkadza ci automatyczne uruchamianie ich za każdym razem, gdy kompilujesz.

Szybkie przeprowadzanie testów może być trudne (o to poprosił OP, prawda!). Oddzielenie jest kluczem. Fałszywe / fałszywe są w porządku, ale myślę, że możesz to zrobić lepiej, dokonując refaktoryzacji w celu uczynienia fałszywych / fałszywych fałszywymi. Zobacz blog Arlo Belshee, zaczynając od http://arlobelshee.com/post/the-no-mocks-book .

5. Spraw, aby testy były przydatne.

Jeśli testy nie zawiodą, kiedy spieprzysz, to po co? Naucz się pisać testy, które wychwycą błędy, które prawdopodobnie stworzysz. Jest to umiejętność sama w sobie i będzie wymagała dużej uwagi.

Jay Bazuzi
źródło
2
MOCNIE zgadzają się, szczególnie w punktach 3 i 1. Jeśli programiści nie przeprowadzają testów, testy są zepsute, środowisko jest zepsute lub jedno i drugie. Punkt 1 jest minimum. Fałszywe niepowodzenia są gorsze niż brakujące testy. Ponieważ ludzie uczą się akceptować, zawodzą. Gdy awaria jest tolerowana, rozprzestrzenia się i wymaga ogromnego wysiłku, aby wrócić do 100% podania i OCZEKIWANIA 100% podania. Zacznij to naprawiać już dziś .
Bill IV
Jak możesz nie zgodzić się z punktem 5?!? oprócz 1 i 3, lub cholera, 2 i 4 też! W każdym razie świetna odpowiedź dookoła.
fourpastmidnight
4

Kilka minut jest OK na testy jednostkowe. Należy jednak pamiętać, że istnieją 3 główne typy testów:

  1. Testy jednostkowe - przetestuj każdą „jednostkę” (klasę lub metodę) niezależnie od reszty projektu
  2. Testy integracyjne - przetestuj projekt jako całość, zwykle wykonując wywołania w programie. Niektóre projekty, które widziałem, łączą to z testami regresji. Wyśmiewanie jest tu znacznie mniejsze niż w testach jednostkowych
  3. Testy regresyjne - przetestuj ukończony projekt jako całość, ponieważ pakiet testowy jest użytkownikiem końcowym. Jeśli masz aplikację konsolową, możesz użyć konsoli do uruchomienia i przetestowania programu. Nigdy nie narażasz wewnętrznych testów na te testy, a użytkownik końcowy Twojego programu powinien (teoretycznie) móc uruchomić zestaw testów regresji (nawet jeśli nigdy tego nie zrobi)

Są one wymienione w kolejności prędkości. Testy jednostkowe powinny być szybkie. Nie złapią każdego błędu, ale ustalają, że program jest przyzwoicie zdrowy. Testy jednostkowe powinny zostać uruchomione za 3 minuty lub krócej lub przyzwoity sprzęt. Mówisz, że masz tylko 1000 testów jednostkowych i trwają 2-3 minuty? Cóż, to chyba OK.

Rzeczy do sprawdzenia:

  • Upewnij się jednak, że testy jednostkowe i testy integracyjne są osobne. Testy integracyjne będą zawsze wolniejsze.

  • Upewnij się, że testy jednostkowe przebiegają równolegle. Nie ma powodu, aby nie, jeśli są to prawdziwe testy jednostkowe

  • Upewnij się, że testy jednostkowe są „niezależne”. Nigdy nie powinni uzyskiwać dostępu do bazy danych lub systemu plików

Poza tym twoje testy nie brzmią teraz tak źle. Jednak dla porównania, jeden z moich przyjaciół w zespole Microsoft ma 4000 testów jednostkowych, które przebiegają w niecałe 2 minuty na przyzwoitym sprzęcie (i jest to skomplikowany projekt). Możliwe są szybkie testy jednostkowe. Eliminowanie zależności (i kpiąc tylko tyle, ile potrzeba) jest najważniejsze, aby uzyskać szybkość.

Earlz
źródło
3

Przeszkol programistów w zakresie Personal Software Process (PSP), pomagając im zrozumieć i poprawić ich wydajność, stosując większą dyscyplinę. Pisanie kodu nie ma nic wspólnego z trzaskaniem palcami na klawiaturze, a następnie naciśnij przycisk kompilacji i odprawy.

W przeszłości PSP było bardzo popularne, gdy kompilacja kodu była procesem, który zajmował dużo czasu (godziny / dni na komputerze mainframe, więc wszyscy musieli udostępniać kompilator). Ale kiedy osobiste stacje robocze stały się potężniejsze, wszyscy zaczęliśmy akceptować ten proces:

  1. wpisz kod bez zastanowienia
  2. naciśnij kompilację / kompilację
  3. napraw swoją składnię, aby się kompilowała
  4. uruchom testy, aby sprawdzić, czy to, co napisałeś, ma sens

Jeśli pomyślisz przed wpisaniem, a następnie po wpisaniu, przejrzyj to, co napisałeś, możesz zmniejszyć liczbę błędów przed uruchomieniem kompilacji i zestawu testów. Naucz się nie naciskać kompilacji 50 razy dziennie, ale może raz lub dwa, wtedy nie ma to większego znaczenia, że ​​kompilacja i czas testowania zajmuje kilka minut dłużej.

Bart Koopman
źródło
2
Zdecydowanie zgadzam się z twoją listą, ale absolutnie nie z „uruchamianiem kompilacji tylko dwa razy dziennie jest lepsze niż 50 razy”.
Doc Brown
3

Jeden możliwy sposób: podziel swoje rozwiązanie. Jeśli rozwiązanie ma 100 projektów, jest to niemożliwe do zarządzania. To, że dwa projekty (powiedzmy A i B) używają wspólnego kodu z innego projektu (powiedzmy Lib), nie oznacza, że ​​muszą być w tym samym rozwiązaniu.

Zamiast tego możesz utworzyć rozwiązanie A z projektami A i Lib, a także rozwiązanie B z projektami B i Lib.

svick
źródło
2

Jestem w podobnej sytuacji. Mam testy jednostkowe, które testują komunikację z serwerem. Testują zachowanie z limitami czasu, anulują połączenia itp. Cały zestaw testów trwa 7 minut.

7 minut to stosunkowo krótki czas, ale nie jest to coś, co zrobisz przed każdym zatwierdzeniem.

Posiadamy również zestaw automatycznych testów interfejsu użytkownika, których czas działania wynosi 2 godziny. To nie jest coś, co chcesz uruchamiać codziennie na swoim komputerze.

Co więc robić?

  1. Zmiana testów zwykle nie jest bardzo skuteczna.
  2. Przeprowadź tylko odpowiednie testy przed zatwierdzeniem.
  3. Uruchom wszystkie testy codziennie (lub kilka razy dziennie) na serwerze kompilacji. Daje to również możliwość generowania ładnego pokrycia kodu i raportów analizy kodu.

Ważne jest: wszystkie testy powinny być uruchamiane często, ponieważ ważne jest, aby znaleźć błędy. Jednak nie jest absolutnie konieczne, aby je znaleźć przed zatwierdzeniem.

Sułtan
źródło
1
Jeśli chodzi o testy komunikujące się z serwerami: jeśli rozmawia z serwerem, to nie jest tak naprawdę test jednostkowy, to coś wyższego. Gdybym był tobą, wydzieliłbym testy jednostkowe (które powinny działać szybko) i przynajmniej uruchomiłbym je przed każdym zatwierdzeniem. W ten sposób przynajmniej usuniesz szybkie rzeczy (rzeczy, które nie muszą rozmawiać z serwerem), zanim kod zostanie zatwierdzony.
Michael Kohne,
@MichaelKohne Wiedziałem, że ktoś to zauważy. Wiem, że nie są to dokładnie testy jednostkowe, ale służą temu samemu celowi, chodzi tylko o to, jak je nazwiesz.
Sulthan
1
głównie chodzi o to, jak je nazywasz, ale dobrze jest pamiętać o różnicy (niezależnie od nazwy, której używasz). Jeśli nie różnicujesz, to (z mojego doświadczenia) twórcy mają tendencję do pisania testów na wyższym poziomie. W tym momencie nie dostajesz testów zmuszających cię do rozsądku w swoich abstrakcjach i sprzężeniu.
Michael Kohne,
1

Chociaż twój opis problemu nie daje dokładnego wglądu w bazę kodu, myślę, że mogę spokojnie powiedzieć, że twój problem jest dwojaki.

Naucz się pisać odpowiednie testy.

Mówisz, że masz prawie tysiąc testów i masz 120 projektów. Zakładając, że co najwyżej połowa tych projektów to projekty testowe, masz 1000 testów do 60 projektów kodu produkcyjnego. To daje około 16-17 testów pr. projekt!!!

To prawdopodobnie ilość testów, które musiałbym przeprowadzić w ramach systemu produkcyjnego w zakresie około 1-2 klas. Więc jeśli nie masz tylko 1-2 klas w każdym projekcie (w takim przypadku struktura projektu jest zbyt drobnoziarnista), twoje testy są zbyt duże, obejmują zbyt dużo gruntu. Mówisz, że to pierwszy projekt, w którym właściwie robisz TDD. Powiedzmy, że liczby, które podajesz, wskazują, że tak nie jest, nie robisz właściwości TDD.

Musisz nauczyć się pisać odpowiednie testy, co prawdopodobnie oznacza, że ​​musisz nauczyć się, jak sprawić, by kod był testowalny. Jeśli nie możesz znaleźć doświadczenia w zespole, aby to zrobić, sugerowałbym zatrudnienie pomocy z zewnątrz, np. W postaci jednego lub dwóch konsultantów pomagających Twojemu zespołowi przez 2-3 miesiące w nauce pisania testowalnego kodu i małych minimalne testy jednostkowe.

Dla porównania, w projekcie .NET, nad którym obecnie pracuję, możemy przeprowadzić około 500 testów jednostkowych w czasie krótszym niż 10 sekund (i nie zostało to nawet zmierzone na maszynie o wysokiej specyfikacji). Gdyby to były twoje dane, nie bałbyś się ich uruchamiać lokalnie tak często.

Naucz się zarządzać strukturą projektu.

Podzieliłeś rozwiązanie na 120 projektów. To według moich standardów oszałamiająca ilość projektów.

Jeśli więc sensowne jest posiadanie takiej liczby projektów (co wydaje mi się, że tak nie jest - ale twoje pytanie nie zawiera wystarczających informacji, aby dokonać właściwej oceny tego), musisz podzielić projekty na mniejsze elementy, które można budować, wersjonować i wdrażać osobno. Tak więc, gdy programista uruchamia jednostkę zestawu testów, musi jedynie przeprowadzić testy dotyczące komponentu, nad którym aktualnie pracuje. Serwer kompilacji powinien zadbać o sprawdzenie, czy wszystko integruje się poprawnie.

Ale podzielenie projektu na wiele komponentów budowanych, wersjonowanych i wdrażanych osobno wymaga z mojego doświadczenia bardzo dojrzałego zespołu programistów, zespołu, który jest bardziej dojrzały niż mam wrażenie, że twój zespół jest.

Ale w każdym razie musisz coś zrobić ze strukturą projektu. Podziel projekty na osobne komponenty lub rozpocznij scalanie projektów.

Zadaj sobie pytanie, czy naprawdę potrzebujesz 120 projektów?

ps Może chcesz sprawdzić NCrunch. To wtyczka Visual Studio, która automatycznie uruchamia test w tle.

Pete
źródło
0

Test JUnit ma zwykle być szybki, ale niektóre z nich muszą po prostu trochę potrwać.

Na przykład test bazy danych zwykle trwa kilka razy, aby zainicjować i zakończyć.

Jeśli masz setki testów, nawet jeśli są one szybkie, ich uruchomienie wymaga dużo czasu.

Co można zrobić, to:

1) Zidentyfikuj kluczowe testy. Te dla najważniejszych części bibliotek i tych, które najprawdopodobniej zawiodą po zmianach. Tylko te testy powinny być uruchamiane zawsze podczas kompilacji. Jeśli jakiś kod jest często łamany, jego testy powinny być obowiązkowe, nawet jeśli jego wykonanie zajmuje dużo czasu, z drugiej strony, jeśli jakaś część oprogramowania nigdy nie spowodowała problemu, możesz bezpiecznie pominąć testy dla każdej kompilacji.

2) Przygotuj serwer ciągłej integracji, który uruchomi wszystkie testy w tle. Od Ciebie zależy, czy zdecydujesz się budować co godzinę lub budować po każdym zatwierdzeniu (drugi ma sens tylko wtedy, gdy chcesz automatycznie wykryć, czyje zatwierdzenie spowodowało problemy).

Żeglarz naddunajski
źródło
0

Problemy, które widziałem:

a) Używanie MKOl do budowania elementów testowych. 70 sekund -> 7 sekund po zdjęciu pojemnika.

b) Nie wyśmiewanie wszystkich klas. Trzymaj testy jednostkowe w jednym elemencie. Widziałem testy, które wędrują przez kilka klas. To nie są testy jednostkowe i znacznie bardziej prawdopodobne jest uszkodzenie.

c) Profiluj je, aby dowiedzieć się, co się dzieje. Odkryłem, że konstruktor budował rzeczy, których nie potrzebowałem, więc zlokalizowałem je i skróciłem czasy działania.

d) Profil. być może kod nie jest zbyt dobry i możesz zyskać na skuteczności dzięki recenzji.

e) Usuń zależności. Utrzymanie małego testowego pliku wykonywalnego skróci czas ładowania. Użyj biblioteki interfejsu i kontenerów IOC, aby uruchomić ostateczne rozwiązanie, ale główne projekty testowe powinny mieć tylko zdefiniowaną bibliotekę interfejsów. Zapewnia to separację, ułatwia testowanie, a także zmniejsza odcisk stopy testowej.

Waratah
źródło
0

Czuję twój ból i natknąłem się na kilka miejsc, w których szybkość budowy można znacznie poprawić. Jednak zalecana przeze mnie liczba polega na dokładnym pomiarze, aby dowiedzieć się, gdzie twoja wersja trwa najdłużej. Na przykład mam kompilację z około 30 projektami, których uruchomienie zajmuje nieco ponad minutę. To jednak tylko część obrazu. Wiem też, które projekty najdłużej trwają, co pomaga skoncentrować moje wysiłki.

Rzeczy, które pochłaniają czas budowy:

  • Pobieranie pakietów (Nuget dla C #, Maven dla Java, Gem dla Ruby itp.)
  • Kopiowanie dużych ilości plików w systemie plików (przykład: pliki obsługi GDAL)
  • Otwieranie połączeń z bazą danych (niektóre zajmują sekundę na połączenie do negocjacji)
  • Kod oparty na odbiciu
  • Kod wygenerowany automatycznie
  • Używanie wyjątków do kontrolowania przebiegu programu

Biblioteki próbne albo używają odbicia, albo wstrzykują kod za pomocą bibliotek kodów bajtowych, aby wygenerować próbkę. Jest to bardzo wygodne, ale zużywa czas testu. Jeśli generujesz symulacje w pętli w teście, może to dodać mierzalny czas do testów jednostkowych.

Istnieją sposoby rozwiązania problemów:

  • Przenieś testy obejmujące bazę danych do integracji (tj. Tylko na serwerze kompilacji CI)
  • Unikaj tworzenia próbnych testów w pętlach. W rzeczywistości po prostu unikaj pętli w testach. W takim przypadku można prawdopodobnie uzyskać te same wyniki, stosując sparametryzowany test.
  • Rozważ podzielenie swojego ogromnego rozwiązania na osobne rozwiązania

Gdy Twoje rozwiązanie zawiera ponad 100 projektów, masz kombinację kodu biblioteki, testów i kodu aplikacji. Każda z bibliotek może być własnym rozwiązaniem z powiązanymi testami. Jet Brains Team City to serwer kompilacji CI, który działa również jako serwer Nuget - i jestem pewien, że nie jest to jedyny. Daje to elastyczność przenoszenia bibliotek, które prawdopodobnie nie są często zmieniane, do własnych rozwiązań / projektów i używania Nuget do rozwiązywania zależności w kodzie aplikacji. Mniejsze rozwiązania oznaczają, że możesz szybko i bezproblemowo wprowadzać zmiany w bibliotece i cieszyć się korzyściami płynącymi z głównego rozwiązania.

Berin Loritsch
źródło
-1

Czy twoje środowisko testowe może działać gdziekolwiek? Jeśli to możliwe, użyj przetwarzania w chmurze, aby uruchomić testy. Podziel testy na N maszyn wirtualnych. Jeśli czas uruchomienia testów na pojedynczej maszynie wynosi T1 sekund, to czas na uruchomienie ich w podziale, T2, może zbliżyć się do T2 = T1 / N. (Zakładając, że każdy przypadek testowy zajmuje tyle samo czasu.) I musisz płacić za maszyny wirtualne tylko wtedy, gdy ich używasz. Więc nie masz garści testowych maszyn siedzących w jakimś laboratorium gdzieś 24 godziny na dobę. (Chciałbym móc to zrobić tam, gdzie pracuję, ale jesteśmy powiązani z konkretnym sprzętem. Brak maszyn wirtualnych dla mnie.)

Nani Tatiana Isobel
źródło