Przyspieszenie testów RSpec w dużej aplikacji Rails

Mam aplikację Rails z ponad 2000 przykładami w moich testach RSpec. Nie trzeba dodawać, że jest to duża aplikacja i jest wiele do przetestowania. Uruchamianie tych testów w tym momencie jest bardzo nieefektywne, a ponieważ trwa to tak długo, jesteśmy prawie na etapie zniechęcania się do ich pisania przed wprowadzeniem nowej kompilacji. Dodałem -- profil do mojej specyfikacji.wybiera najdłużej działające przykłady i jest co najmniej 10 z nich, które zajmują średnio 10 sekund, aby uruchomić. Czy to normalne wśród was eksperci RSpec? Czy 10 sekund jest za długie na jeden przykład? Zdaję sobie sprawę, że z 2000 przykładów, zajmie nietrywialną ilość czasu, aby przetestować wszystko dokładnie - ale w tym momencie 4 godziny to trochę niedorzeczne.

Jakie czasy widzisz dla swoich najdłużej działających przykładów? Co mogę zrobić, aby rozwiązać problemy z istniejącymi specyfikacjami, aby wykryć wąskie gardła i przyspieszyć działanie. Każda minuta bardzo by pomogła.

Author: randombits, 2010-09-08

12 answers

10 sekund to bardzo długi czas na uruchomienie pojedynczego testu. Mam przeczucie, że twój cel przeprowadza testy jednostkowe i integracyjne w tym samym czasie. Jest to typowa rzecz, w którą wpadają projekty i na pewnym etapie będziesz musiał pokonać ten techniczny dług , jeśli chcesz produkować więcej, szybciej. Istnieje wiele strategii, które mogą ci w tym pomóc... i polecę kilka, które używałem w przeszłości.

1. Oddzielna Jednostka Od Integracji Testy

Pierwszą rzeczą, którą chciałbym zrobić, to oddzielić unit od testów integracyjnych. Możesz to zrobić albo przez:

  1. przenoszenie ich (do osobnych folderów pod katalogiem spec) - i modyfikowanie celów rake
  2. oznaczanie ich (rspec pozwala na oznaczanie testów)

Filozofia głosi, że chcesz, aby twoje regularne buildy były szybkie - w przeciwnym razie ludzie nie będą zbyt szczęśliwi, aby je często uruchamiać. Więc wracaj na to terytorium. Pobierz regularne testy do uruchomienia szybko i Użyj serwera ciągłej integracji, aby uruchomić bardziej kompletną kompilację.

Test integracji jest testem, który obejmuje zewnętrzne zależności (np. bazy danych, WebService, Queue, a niektórzy twierdzą, że system plików). Test jednostkowy testuje tylko określony element kodu, który chcesz sprawdzić. Powinien działać szybko (9000 w 45 sekund jest możliwe), tzn. większość powinna działać w pamięci.

2. Konwersja Testów Integracyjnych Na Testy Jednostkowe

Jeśli większość twoich testów jednostkowych jest mniejszy niż twój pakiet testów integracyjnych, masz problem. Oznacza to, że niespójności zaczną pojawiać się łatwiej. Od tego momentu zacznij tworzyć więcej testów jednostkowych, które zastąpią testy integracyjne. Co możesz zrobić, aby pomóc w tym procesie to:

  1. użyj szyderczego frameworka zamiast realnego zasobu. Rspec ma wbudowany framework szyderczy.
  2. Uruchom rcov na swoim zestawie testów jednostkowych. Użyj tego, aby ocenić, jak dokładny jest Twój zestaw testów jednostkowych.

Once masz odpowiednie testy jednostkowe, aby zastąpić test integracji - Usuń test integracji. Zduplikowane testy tylko pogarszają konserwację.

3. Nie używaj osprzętu

Oprawy są złe. Zamiast tego użyj factory (machinist lub factory_girl). Systemy te mogą tworzyć bardziej elastyczne wykresy danych, a co ważniejsze, mogą budować obiekty w pamięci, których można używać, zamiast ładować rzeczy z zewnętrznego źródła danych.

4. Dodawanie Kontroli W Celu Zatrzymania Testów Jednostkowych Testy Integracyjne

Teraz, gdy masz szybsze testy w miejscu, czas na wprowadzenie kontroli, aby zatrzymać to ponownie.

Istnieją biblioteki, które poprawiają active record, aby rzucić błąd podczas próby uzyskania dostępu do bazy danych (UnitRecord).

Możesz również spróbować parowania i TDD, które mogą zmusić Twój zespół do napisania szybszych testów, ponieważ:

  1. ktoś sprawdza-żeby nikt nie był leniwy
  2. prawidłowe TDD wymaga szybkiego sprzężenia zwrotnego. Slow testy sprawiają, że wszystko jest bolesne.

5. Użyj Innych Bibliotek, Aby Rozwiązać Problem

Ktoś wspomniał o spork (przyspiesza czas ładowania zestawu testów pod rails3), hydra / parallel_tests - Uruchamianie testów jednostkowych równolegle (na wielu rdzeniach).

To powinno być używane jako ostatnie. Twój prawdziwy problem jest aż w kroku 1, 2, 3. Rozwiąż to, a będziesz w lepszej sytuacji, aby wykorzystać dodatkową infrastrukturę.

 119
Author: BlueFish,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-23 00:43:36

Aby uzyskać świetną książkę kucharską na temat poprawy wydajności zestawu testów, sprawdź prezentację Grease Your Suite .

Dokumentuje 45-krotne przyspieszenie w czasie uruchamiania zestawu testowego, wykorzystując takie techniki, jak:

 16
Author: marshally,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-08 13:29:37

Możesz użyć Spork. Posiada wsparcie dla 2.3.x,

Https://github.com/sporkrb/spork

Lub ./ script / spec_server który może działać dla 2.x

Możesz również edytować konfigurację bazy danych (co zasadniczo przyspiesza zapytania do bazy danych itp.), co również zwiększy wydajność testów.

 5
Author: Rishav Rastogi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-11 17:48:48

10 sekund na przykład wygląda na bardzo długi czas. Nigdy nie widziałem spec, który zajmuje więcej niż jedną sekundę, a większość zajmuje znacznie mniej. Testujesz połączenia sieciowe? Bazy danych pisze? Filesystem pisze?

Używaj Mock 'ów i Stub' ów jak najwięcej - są one dużo szybsze niż pisanie kodu, który trafia do bazy danych. Niestety szydzenie i stubowanie również zajmuje więcej czasu na pisanie (i są trudniejsze do zrobienia poprawnie). Musisz zrównoważyć czas spędzony na pisaniu testów a czas spędzony na testach.

Popieramkomentarz Andrew Grimma o zbadaniu systemu CI, który może pozwolić na równoległe połączenie Twojego zestawu testów. Dla czegoś takiego, to może być jedyne realne rozwiązanie.

 3
Author: zetetic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:53:49

Kilka osób wspomniało o Hydrze powyżej. Korzystaliśmy z niego z wielkim sukcesem w przeszłości. Niedawno udokumentowałem proces uruchamiania Hydry: http://logicalfriday.com/2011/05/18/faster-rails-tests-with-hydra/

Zgadzam się z przekonaniem, że tego rodzaju technika nie powinna być używana jako substytut pisania testów, które są dobrze ustrukturyzowane i szybkie domyślnie.

 2
Author: Rodreegez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-19 15:01:29

Jeśli używasz modeli ActiveRecord, powinieneś również wziąć pod uwagę koszt szyfrowania BCrypt.

Możesz przeczytać więcej na ten temat w tym wpisie na blogu: http://blog.syncopelabs.co.uk/2012/12/speed-up-rspec-test.html

 2
Author: egezer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-21 22:43:20

Sprawdź tę prezentację: http://grease-your-suite.heroku.com/#1

 1
Author: user456733,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-23 22:58:27
 0
Author: Reactormonk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-08 08:18:33

Faster_require gem może Ci pomóc. Poza tym jedynym sposobem jest (tak jak zrobiłeś) profilowanie i optymalizacja, lub użycie spork lub coś, co uruchamia specyfikacje równolegle dla Ciebie. http://ruby-toolbox.com/categories/distributed_testing.html

 0
Author: rogerdpack,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-08 22:50:41

Jest bardzo ogólny film tutaj na poprawę prędkości testu. Może pomóc.

 0
Author: Neil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-25 12:44:37

Możesz wykonać kilka prostych wskazówek, aby najpierw zbadać, gdzie spędza się większość czasu, jeśli jeszcze ich nie wypróbowałeś. Spójrz na poniższy artykuł:

Https://blog.mavenhive.in/7-tips-to-speed-up-your-webdriver-tests-4f4d043ad581

Myślę, że większość z nich to ogólne kroki, które mają zastosowanie niezależnie od narzędzia używanego do testowania.

 0
Author: jake,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-22 18:44:22

Usuń istniejący zestaw testów. Będzie niesamowicie skuteczny.

 -3
Author: thedanotto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-05 00:44:44