Jak utrzymać stabilność pnia, gdy testy trwają długo?

9

Mamy trzy zestawy pakietów testowych:

  • „Mały” apartament, którego uruchomienie zajmuje tylko kilka godzin
  • „Średni” apartament, który zajmuje wiele godzin, zwykle jest uruchamiany co noc (co noc)
  • „Duży” pakiet, którego uruchomienie zajmuje tydzień +

Mamy też kilka krótszych pakietów testowych, ale nie skupiam się na nich tutaj.

Obecna metodologia polega na uruchomieniu małego pakietu przed każdym zatwierdzeniem do pnia. Następnie średni zestaw uruchamia się każdej nocy, a jeśli rano okaże się, że się nie udało, staramy się ustalić, które z wczorajszych zobowiązań było winne, wycofać się z zatwierdzenia i ponowić testy. Podobny proces, tylko co tydzień zamiast co noc, odbywa się w przypadku dużego zestawu.

Niestety średni zestaw dość często zawodzi. Oznacza to, że pień jest często niestabilny, co jest bardzo denerwujące, gdy chcesz wprowadzić modyfikacje i przetestować je. Jest to denerwujące, ponieważ kiedy wymeldowuję się z bagażnika, nie jestem pewien, czy jest stabilny, a jeśli test się nie powiedzie, nie jestem pewien, czy to moja wina, czy nie.

Moje pytanie brzmi: czy istnieje jakaś znana metodologia radzenia sobie z tego rodzaju sytuacjami w sposób, który sprawi, że bagażnik będzie zawsze w najlepszym stanie? np. „zatwierdzanie w specjalnej gałęzi przedwstępnej, która następnie okresowo aktualizuje pień za każdym razem, gdy noc przechodzi”.

I czy ma to znaczenie, czy jest to scentralizowany system kontroli źródła, taki jak SVN, czy rozproszony, jak git?

Nawiasem mówiąc, jestem młodszym programistą z ograniczoną zdolnością do zmiany rzeczy, po prostu próbuję zrozumieć, czy istnieje sposób na poradzenie sobie z tym bólem, którego doświadczam.

Dąb
źródło
6
Nie mam pojęcia, nad jakim oprogramowaniem pracujesz, ale niewielki pakiet testowy, którego uruchomienie zajmuje wiele godzin, to trochę WTF. Gdyby działały szybciej, byłoby to łatwiejsze, nie ma sposobu na usprawnienie swoich testów?
Benjamin Bannier,
2
co jest tak „wyjątkowo denerwującego” w niestabilności tułowia? Nie wiem, czy wiesz, ale jedna z najpopularniejszych strategii rozgałęziania jest nawet nazywana niestabilnym pniem
gnat
1
Istnieje wiele sposobów optymalizacji pakietu testowego (jak w przypadku każdego innego oprogramowania). Nie mam pojęcia, dlaczego zajmuje to tak długo, ale możesz np. Być w stanie ponownie użyć części środowiska testowego lub po prostu użyć lepszych algorytmów / struktur danych podczas pracy (profilowanie pomaga). Możliwe, że nikt nie poświęci czasu na identyfikację reprezentatywnych próbek, a Ty po prostu przetestujesz każdy możliwy sygnał wejściowy / wyjściowy pod kątem odniesienia. Być może twój buildsystem pozwala ci zakodować zależności testowania kodu, więc nie musisz uruchamiać pełnego zestawu. I wiem, że to nie było twoje pytanie, dlatego napisałem komentarz, a nie odpowiedź.
Benjamin Bannier
1
... hmm, lepsza opcja może poprawić testy i rejestrowanie aplikacji, aby łatwiej było znaleźć przyczynę niepowodzenia. W ten sposób należałoby znaleźć i naprawić przyczynę niepowodzenia, zamiast marnować wysiłki na „dochodzenia detektywistyczne”, szukając, kto, kiedy i dlaczego zmienił konkretną linię kodu ...
gnat
1
@honk Niektóre testy trwają długo. Pracuję dla firmy produkującej sprzęt do akwizycji danych, a nasz „częściowy” test trwa około godziny. Testy muszą wykonywać różne rodzaje pomiarów, a to zajmuje tylko czas.
Velociraptors

Odpowiedzi:

1

Jedynym sposobem naprawienia pierwotnej przyczyny niestabilności jest oddzielenie kodu, aby zmiany były bardziej izolowane, jak sugerują inne odpowiedzi.

Jednak jako indywidualny programista, jeśli chcesz bardziej stabilną kompilację, na której możesz osobiście pracować, jest to stosunkowo łatwe do rozwiązania. Zamiast pracować z końcówką, wyciągasz tylko ostatnią kompilację, która przekazała zestaw testów na noc do twojego drzewa roboczego. Jeśli możesz utworzyć gałęzie funkcji dla każdej zmiany, odejdź od ostatniej stabilnej wersji.

Tak, twoje drzewo będzie kilka dni w tyle, ale przez większość czasu to nie ma znaczenia. Wykonuj swoją pracę w stosunku do stabilnej wersji, abyś wiedział, że twoje zmiany przełamały wszelkie testy, a następnie, zanim się zalogujesz, zaktualizuj do najnowszej wersji i wykonaj normalną integrację. Następnie po odprawie wróć do ostatniej stabilnej wersji.

Nadal musisz wykonać nieporządną pracę integracyjną, ale to, co podoba mi się w tej metodzie, to to, że izoluje pracę integracyjną na czas bardziej dogodny dla mnie i daje mi stabilną bazę kodu do programowania, gdy nie jest to wygodne. Mam o wiele lepszy pomysł, kiedy moje zmiany prawdopodobnie złamały kompilację w porównaniu do czyjejś innej.

Karl Bielefeldt
źródło
1
-1 praca z gałęzi jest realną opcją, ale zalecenie jej bez sugestii przetestowania może przynieść więcej szkody niż pożytku. Tylko testy mogą wykazać, czy jest to wykonalne dla konkretnego projektu, czy nie. Np. W projekcie, który przeprowadziłem około 2 lata temu, takie testy wykazały, że praca w oddziałach wymaga ~ 7 razy więcej wysiłku w porównaniu do niestabilnego pnia
komara
Dzięki Karl! Chociaż nie tego chciałem się nauczyć, jest to bardzo praktyczne podejście, które może pomóc mi rozwiązać dany problem. Zgadzam się, że praca przez kilka dni za pniem rzadko powoduje problemy z integracją.
Dąb
12

Wiem, że próbujesz tego uniknąć, ale prawdziwy wgląd tutaj polega na uświadomieniu sobie, że coś jest nie tak z twoją bazą kodu: musisz uruchomić pełny zestaw testów, który zajmie tydzień, aby upewnić się, że kod jest stabilny!

Najkorzystniejszym sposobem rozwiązania tego problemu jest rozpoczęcie rozdzielania bazy kodu i testów na (niezależne) podjednostki.
Są to ogromne zalety:

  • Testy dla każdej z tych jednostek będą przebiegały szybciej (jest ich po prostu mniej) i nie ulegną one przerwaniu, jeśli coś pójdzie nie tak w jednej z niezależnych lub dalszych jednostek.
  • Nieudany test zostanie wskazany na konkretnej jednostce, co znacznie ułatwi znalezienie źródła problemu.
  • Możesz oddzielić lokalizacje VCS różnych jednostek, tak aby gałąź „stabilna” mogła być połączeniem najnowszej pomyślnie przetestowanej wersji każdej jednostki, tak aby jedna lub dwie uszkodzone jednostki nie zdestabilizowały twojej „stabilnej” wersji .

Z drugiej strony zarządzanie strukturą VCS stanie się bardziej skomplikowane, ale za cały tydzień pełnego testu, myślę, że możesz znieść ból!

Nadal zalecam stosowanie strategii gałęzi „stabilnej” i „programistycznej” w takiej lub innej formie, ale istnieje wiele sposobów, aby to zrobić i możesz wybrać ten, który najlepiej pasuje do Twojej organizacji (meta-repozytoria ze stałymi poprawkami wskazującymi na osobne repozytoria dla każdej jednostki, gałąź stabilna i gałąź programistów, gałęzie funkcji ....)

Joris Timmermans
źródło
1
Nigdy nie mówiłem, że duży test to test atomowy, to zestaw testów . Gdy indywidualny programista dokonuje modyfikacji elementu X, uruchamia testy odpowiednie dla X - bez względu na to, z którego zestawu testów pochodzą. Jest to dodatek do cotygodniowego testu, który jest przeprowadzany, aby upewnić się, że zmiana w jednym miejscu nie wpłynęła nieoczekiwanie na inne miejsce. Ale robisz interesujący punkt, że przynajmniej rozdzielenie rzeczy w ten sposób przyspieszy testy konkretnych modułów, utrzymując ryzyko na mniej więcej tym samym poziomie.
Dąb
2
@oak - Cóż, w pewnym sensie pakiet JEST atomowy, jeśli uruchomienie go w całości jest jedynym sposobem, w jaki masz pewność, że kod jest stabilny, ale robisz dobry punkt, więc zredagowałem moją odpowiedź.
Joris Timmermans,
4
Mamy ogromne testy dla naszych kompilatorów, których uruchomienie zajmuje kilka dni, i nie sądzę, że jest to rzadkie w przypadku oprogramowania tak złożonego jak kompilator C ++. To nie jest tak, że pakiet definiuje to, co należy uznać za „stabilne”, ale raczej, że istnieją miliony różnych przypadków generowania kodu, których nie można przetestować każdego dnia.
JesperE
1
@JesperE - jest to zrozumiałe, jeśli ogromny zestaw testów nie definiuje „stabilny”, ale jest gigantycznym testem poczytalności. Nie spodziewałbym się, że pełny pakiet (a nawet średni pakiet) będzie bardzo często zawodził.
Joris Timmermans
1

W przypadku SVN nie wiem o czymś takim, jak „wstępne zatwierdzenie”. Myślę, że prawdopodobnie spowoduje to zatwierdzenie i wycofanie, gdy test się nie powiedzie. Jak mówi doc-brown, jedynym sposobem jest zatwierdzenie tymczasowej gałęzi i połączenie jej z pniem później.

Używając rozproszonego takiego jak git lub merkurial, myślę, że byłoby to możliwe. Korzystanie z repozytorium „testującego” i repozytorium „stabilnego”. Naciskasz na przedstawiciela testowego, testujesz go co noc, a jeśli wszystko działa dobrze, przesuwasz się z testu na stabilny. W przeciwnym razie wycofasz przedstawiciela testującego. Nie jestem pewien, jak wyglądałaby historia wersji, kiedy przechodzisz od testowania do stabilnego, ale myślę, że można w ten sposób wykluczyć zepsute wycofane elementy. Najpierw najbezpieczniej byłoby trochę poeksperymentować.

Alternatywą byłoby również przetestowanie lokalnego bagażnika każdej osoby co noc. Następnie osoby, które przeszły pomyślnie testy, mogą wypchnąć go rano na serwer centralny.

Dagnele
źródło
1

IMHO nie ma to nic wspólnego z używanym VCS. Użycie „testowanego” oddziału może być rozwiązaniem, które można zrealizować również za pomocą scentralizowanego lub rozproszonego VCS. Ale szczerze mówiąc, myślę, że najlepszą rzeczą w twojej sytuacji jest próba zoptymalizowania średniego zestawu testów (wydaje się, że zawiera najważniejsze testy), aby działał znacznie szybciej, więc możesz go użyć do pre-commit-to-trunk testy, tak jak robisz to teraz z „małym pakietem”.

Doktor Brown
źródło
Najczęściej pytam tutaj o metodologię - tj. Czy istnieje wspólny sposób radzenia sobie z taką sytuacją. Załóżmy, przynajmniej ze względu na tę dyskusję, że testów nie można zoptymalizować poza tym, czym już są.
Dąb
@Oak: ktoś tutaj (ty?) Przegłosował moją odpowiedź - ale czasami rzeczy, których nie chcesz słyszeć, są jedynymi rzeczami, które pomogą. Jak widać w dyskusji poniżej twojego pytania, inni zasugerowali to samo, więc moja sugestia nie wydaje się wcale taka zła.
Doc Brown
+1, to właściwa odpowiedź. Prawdziwe pytanie PO brzmi: „Pomoc, tonę w gównie, jakiej metodologii mogę użyć, żeby sobie pomóc?” a odpowiedź brzmi: tak naprawdę metodologia nie jest tym, o co powinieneś się martwić.
MrFox,
1

Testy średnich testów: Czy to prawda, że ​​w większości przypadków te same testy kończą się niepowodzeniem?

Jeśli wystąpi awaria, czy zawsze występują te same powiązane testy, które zawodzą?

Jeśli prawda: możliwe, że możesz selektywnie wybrać niektóre średnie testy, które często kończą się niepowodzeniem (jeden test dla każdej klasy błędu) i wykonać je w małym zestawie.

Czy większość testów-testów integracyjnych wykorzystujących prawdziwą bazę danych? Jeśli tak, to czy można je zastąpić najbardziej nieprzystosowanym, który ma próbną bazę danych?

k3b
źródło
1

Musisz przyspieszyć testy, nie ma innego sposobu na wyprostowanie tego koła.

Rozważ problem: chcesz mieć pewność, że przy kasie masz działający kod. Jasne, możesz opóźnić zatwierdzenia i rozgałęzić się przed wydaniem, ale opóźni to początek problemu do momentu integracji. Czy po każdym fuzji będziesz musiał uruchomić tygodniowy pakiet? Metodologia nie jest rozwiązaniem, rozwiązanie jest czysto techniczne.

Oto, co sugeruję:

1) Spraw, aby testy były jak najbardziej atmomiczne i zmaksymalizuj ponowne użycie środowiska.

2) Uzyskaj farmę z pakietem testów, aby je uruchomić. Jeśli zamiast 8 dużych modułów uzyskasz 50, możesz rozdzielić kilka instancji spotów Amazon EC2 i uruchomić cały pakiet równolegle. Jestem pewien, że będzie to kosztowało trochę pieniędzy, ale pozwoli zaoszczędzić ogromne ilości czasu programisty.

MrFox
źródło
0

Kluczową rzeczą, którą bierzesz za oczywistość w swoim pytaniu, jest to, że wszystkie zatwierdzenia muszą przejść testy. Chociaż jest to miła zasada do naśladowania i wydaje się, że ma to jakiś sens, czasami nie jest praktyczna. Twój przypadek jest przykładem (chociaż MadKeithV ma rację) i mogę sobie wyobrazić utrzymanie oddziału VCS tak nieskazitelnego, co może być trudne, jeśli nie będzie wystarczającej współpracy między devloperami.

W rzeczywistości to, co chcesz, to dowiedzieć się, które zatwierdzenia kończą się pomyślnie. Jak sugerowałeś, gałąź „wstępnie zatwierdzająca” działałaby, ale może wymagać dodatkowego wysiłku ze strony programistów, którzy dokonują zatwierdzeń, co może być trudne do sprzedania.

Podobnym podejściem, które mogłoby być łatwiejsze, jest pozostawienie pnia, aby ludzie mogli złamać, jak chcą, i mieć oddział dla zatwierdzeń, które nie są zepsute. Zautomatyzowany skrypt może przechodzić przez zatwierdzenia, gdy są wykonywane do linii głównej, uruchamiać na nich testy i dodawać je do gałęzi, jeśli przejdą pomyślnie.

Lub możesz być absurdalnie uproszczony i mieć skrypt, który wyświetla zatwierdzające przekazywanie w pliku tekstowym (który może, ale nie musi, być kontrolowany w wersji).

Lub mieć system wsadowy, który przyjmuje żądania przetestowania gałęzi / wersji (z dowolnego miejsca w drzewie), i testuje je i zatwierdza do linii głównej (lub innej gałęzi), jeśli przejdą.

Michael Slade
źródło