Z technicznego punktu widzenia możliwe jest dodanie niektórych zaczepów przed / po naciśnięciu, które będą uruchamiać testy jednostkowe przed zezwoleniem na połączenie określonego zatwierdzenia ze zdalną domyślną gałęzią.
Moje pytanie brzmi - czy lepiej jest utrzymywać testy jednostkowe w potoku kompilacji (w ten sposób wprowadzając uszkodzone commits do repo) czy lepiej po prostu nie dopuścić do wystąpienia „złych” commits.
Zdaję sobie sprawę, że nie ograniczam się do tych dwóch opcji. Na przykład mogę zezwolić wszystkim zatwierdzeniom na rozgałęzienie i przetestowanie przed wypchnięciem scalenia zatwierdzenia do repo. Ale jeśli musisz wybierać między dokładnie tymi dwoma rozwiązaniami, które wybierzesz i z jakich dokładnie powodów?
Odpowiedzi:
Nie, nie z dwóch powodów:
Prędkość
Zatwierdzenia powinny być szybkie. Na przykład zatwierdzenie, które zajmuje 500 ms., Jest zbyt wolne i zachęci programistów do dokonywania go oszczędniej. Biorąc pod uwagę, że w każdym projekcie większym niż Hello World będziesz mieć dziesiątki lub setki testów, uruchomienie ich podczas wstępnego zatwierdzenia potrwa zbyt długo.
Oczywiście sytuacja się pogarsza w przypadku większych projektów z tysiącami testów, które trwają kilka minut na architekturze rozproszonej lub tygodnie lub miesiące na jednej maszynie.
Najgorsze jest to, że niewiele można zrobić, aby przyspieszyć. Małe projekty w języku Python, które, powiedzmy, setki testów jednostkowych, trwają co najmniej sekundę na przeciętnym serwerze, ale często znacznie dłużej. W przypadku aplikacji C # będzie to średnio cztery-pięć sekund ze względu na czas kompilacji.
Od tego momentu możesz albo zapłacić dodatkowe 10 000 USD za lepszy serwer, co skróci czas, ale niewiele, albo uruchomić testy na wielu serwerach, co tylko spowolni.
Obie opłacają się dobrze, gdy masz tysiące testów (a także testów funkcjonalnych, systemowych i integracyjnych), co pozwala uruchomić je w ciągu kilku minut zamiast tygodni, ale to nie pomoże ci w przypadku małych projektów.
Zamiast tego możesz:
Zachęć deweloperów do przeprowadzenia testów silnie związanych z kodem, który zmodyfikowali lokalnie przed zatwierdzeniem. Prawdopodobnie nie mogą przeprowadzić tysięcy testów jednostkowych, ale mogą przeprowadzić pięć-dziesięć z nich.
Upewnij się, że znalezienie odpowiednich testów i ich uruchomienie jest w rzeczywistości łatwe (i szybkie). Na przykład program Visual Studio jest w stanie wykryć, na które testy mogą mieć wpływ zmiany wprowadzone od czasu ostatniego uruchomienia. Inne IDE / platformy / języki / frameworki mogą mieć podobną funkcjonalność.
Zachowaj zatwierdzenie tak szybko, jak to możliwe. Egzekwowanie reguł stylu jest OK, ponieważ często jest to jedyne miejsce, aby to zrobić, a ponieważ takie kontrole są często niezwykle szybkie. Wykonywanie analizy statycznej jest prawidłowe, gdy tylko będzie działać szybko, co rzadko się zdarza. Uruchomienie testów jednostkowych jest nieprawidłowe.
Przeprowadź testy jednostkowe na serwerze Continuous Integration.
Upewnij się, że programiści są automatycznie informowani, kiedy zepsują kompilację (lub gdy testy jednostkowe się nie powiodą, co jest praktycznie tym samym, jeśli weźmiesz pod uwagę kompilator jako narzędzie sprawdzające niektóre z możliwych błędów, które możesz wprowadzić do kodu).
Na przykład przejście do strony internetowej w celu sprawdzenia ostatnich kompilacji nie jest rozwiązaniem. Powinny być one automatycznie informowane . Wyświetlanie wyskakującego okienka lub wysyłanie wiadomości SMS to dwa przykłady tego, w jaki sposób mogą zostać poinformowani.
Upewnij się, że programiści rozumieją, że przerwanie kompilacji (lub nieudane testy regresji) nie jest w porządku, a jak tylko to się stanie, ich najwyższym priorytetem jest naprawa. Nie ma znaczenia, czy pracują nad funkcją o wysokim priorytecie, którą ich szef poprosił o dostarczenie na jutro: kompilacja się nie powiodła, powinni ją naprawić.
Bezpieczeństwo
Serwer hostujący repozytorium nie powinien uruchamiać niestandardowego kodu, takiego jak testy jednostkowe, szczególnie ze względów bezpieczeństwa. Czy te powody zostały już wyjaśnione w module CI na tym samym serwerze GitLab?
Z drugiej strony, jeśli twoim pomysłem jest uruchomienie procesu na serwerze kompilacji z haka przed zatwierdzeniem, spowolni to jeszcze bardziej zatwierdzenia.
źródło
Pozwól mi być tym, który nie zgadza się z moimi kolegami.
Jest to znane jako Gated Check-in w świecie TFS i spodziewam się gdzie indziej. Podczas próby odprawy do oddziału z bramkowanym odprawą zestaw półek jest wysyłany do serwera, co zapewnia, że zmiany zostaną skompilowane, a testy jednostkowe określone (czytaj: wszystkie) przejdą pomyślnie. Jeśli nie, informuje cię, że jesteś złą małpką, która złamała kompilację. Jeśli tak, zmiany przechodzą w kontrolę źródła (tak!).
Z mojego doświadczenia wynika, że odprawy bramkowe są jednym z najważniejszych procesów udanego testowania jednostkowego - a co za tym idzie - jakości oprogramowania.
Dlaczego?
I oczywiście jest taka korzyść, jaką przedstawiłeś pierwotnie - kiedy masz bramę odpraw i solidny zestaw testów, każdy zestaw zmian jest „stabilny”. Zapisujesz cały ten narzut (i potencjalny błąd) „kiedy była ostatnia dobra wersja?” - wszystkie kompilacje są wystarczająco dobre, aby się rozwijać.
Tak, zbudowanie i uruchomienie testów zajmuje trochę czasu. Z mojego doświadczenia wynika, że 5-10 minut na dobrą aplikację C # i ~ 5k testów jednostkowych. I nie obchodzi mnie to. Tak, ludzie powinni często się zameldować. Ale powinni również często aktualizować swoje zadania, sprawdzać pocztę elektroniczną lub napić się kawy lub dziesiątek innych „niedziałających nad kodem” rzeczy, które składają się na pracę inżyniera oprogramowania. Sprawdzanie złego kodu jest znacznie droższe niż 5-10 minut.
źródło
Zatwierdzenia powinny działać szybko. Kiedy zatwierdzam jakiś kod, chcę, aby został przekazany na serwer. Nie chcę czekać kilka minut na uruchomienie zestawu testów. Jestem odpowiedzialny za to, co pcham na serwer i nie potrzebuję nikogo, kto opiekowałby się mną przy pomocy haków zatwierdzania.
To powiedziawszy, kiedy dostanie się na serwer, należy go przeanalizować, przetestować i zbudować natychmiast (lub w krótkim czasie). Ostrzegłoby mnie to o tym, że testy jednostkowe są zepsute lub nie zostały skompilowane, albo zrobiłem bałagan pokazany przez dostępne narzędzia analizy statycznej. Im szybciej to się dzieje (kompilacja i analiza), tym szybciej moja informacja zwrotna i tym szybciej jestem w stanie to naprawić (myśli nie wyszły całkowicie z mojego mózgu).
Więc nie, nie umieszczaj testów i tym podobnych w hakach zatwierdzania na kliencie. Jeśli musisz, umieść je na serwerze po zatwierdzeniu (ponieważ nie masz serwera CI) lub na serwerze kompilacji CI i odpowiednio ostrzeż mnie o problemach z kodem. Ale nie blokuj przede wszystkim dokonywania zmian.
Powinienem również zauważyć, że przy niektórych interpretacjach Test Driven Development należy sprawdzić test jednostkowy, który najpierw się psuje . Pokazuje to i dokumentuje występowanie błędu. Późniejszym meldowaniem będzie kod, który naprawia test jednostkowy. Zapobieganie meldowaniu się do momentu zdania testów jednostkowych zmniejszyłoby efektywną wartość sprawdzania w teście jednostkowym, który nie udokumentuje problemu.
Powiązane: Czy powinienem mieć testy jednostkowe znanych usterek? i Jaka jest wartość sprawdzania w nieudanych testach jednostkowych?
źródło
Commits should run fast.
jakie są z tego korzyści? Jestem ciekawy, ponieważ obecnie używamy bramkowanych czeków. Zazwyczaj moje meldowanie to kumulacja około godziny pracy, więc 5-minutowe oczekiwanie nie jest wielką sprawą. W rzeczywistości odkryłem, że jego zestyk czasy, kiedy jestem w pośpiechu, że build walidacji jest najbardziej przydatna do połowu głupie błędy (wskutek pośpiechu)catching silly mistakes (as a result of rushing)
dokładnie. Pośpiech w ogóle jest złą praktyką w inżynierii oprogramowania. Robert C. Martin zaleca pisanie kodu takiego jak operacja youtube.com/watch?v=p0O1VVqRSK0Zasadniczo uważam, że sensowne jest zapobieganie wprowadzaniu zmian w głównej linii, które przerywają kompilację. Oznacza to, że proces wprowadzania zmian w głównej gałęzi repozytorium powinien wymagać upewnienia się, że wszystkie testy nadal przebiegają pomyślnie. Przerwanie kompilacji jest po prostu zbyt kosztowne ze względu na stracony czas, aby wszyscy inżynierowie w projekcie mogli zrobić cokolwiek innego.
Jednak szczególne rozwiązanie haków zatwierdzających nie jest dobrym planem.
źródło
Breaking the build is simply too costly in terms of lost time for all engineers on the project
Sugerowałbym użycie pewnego rodzaju narzędzia do powiadamiania o kompilacji, aby uniknąć sytuacji, w której wszyscy inżynierowie tracą czas na każdą zepsutą kompilacjęNie, nie powinieneś, jak zauważyły inne odpowiedzi.
Jeśli chcesz mieć bazę kodu, która gwarantuje brak nieudanych testów, możesz zamiast tego rozwijać się w gałęziach funkcji i pobierać żądania do master. Następnie możesz zdefiniować warunki wstępne dla akceptacji tych żądań ściągania. Zaletą jest to, że możesz naciskać naprawdę szybko, a testy działają w tle.
źródło
Konieczność oczekiwania na udaną kompilację i testy przy każdym zatwierdzeniu do głównej gałęzi jest naprawdę okropna, myślę, że wszyscy się z tym zgadzają.
Istnieją jednak inne sposoby osiągnięcia spójnej gałęzi głównej. Oto jedna sugestia, nieco podobna do bramkowanych odpraw w TFS, ale którą można uogólnić do dowolnego systemu kontroli wersji z rozgałęzieniami, chociaż najczęściej używam terminów git:
Posiadaj gałąź pomostową, do której możesz jedynie zatwierdzać połączenia między gałęziami programistów i gałęziami głównymi
Skonfiguruj hook, który uruchamia lub umieszcza w kolejce kompilację i testy zatwierdzeń wykonanych w gałęzi pomostowej, ale nie powoduje to oczekiwania
Po udanej kompilacji i testach automatycznie uruchom główną gałąź , jeśli jest aktualna
Uwaga: nie scalaj automatycznie z gałęzią główną, ponieważ testowane scalanie, jeśli nie scalanie do przodu z punktu widzenia gałęzi głównej, może się nie powieść po scaleniu z gałęzią główną z zatwierdzeniami pomiędzy
W konsekwencji:
Zabroń ludziom angażowania się w główny oddział, automatycznie, jeśli możesz, ale także w ramach oficjalnego procesu, jeśli istnieje luka lub jeśli nie jest to technicznie wykonalne
Przynajmniej możesz upewnić się, że nikt nie zrobi tego przypadkowo lub bez złośliwości, gdy będzie to podstawowa zasada. Nigdy nie powinieneś próbować tego robić.
Będziesz musiał wybrać między:
Pojedyncza gałąź przemieszczania, która w przeciwnym razie spowoduje udane scalenie, faktycznie się nie powiedzie, jeśli poprzednie, jeszcze nieskompilowane i nie przetestowane scalenie nie powiedzie się
Przynajmniej będziesz wiedział, które scalenie nie powiodło się, i ktoś może to poprawić, ale połączenia między nimi nie są łatwo identyfikowalne (przez system kontroli wersji) wyników dalszych kompilacji i testów.
Możesz spojrzeć na adnotację pliku (lub obwinianie), ale czasami zmiana pliku (np. Konfiguracji) spowoduje błędy w nieoczekiwanych miejscach. Jest to jednak dość rzadkie wydarzenie.
Wiele gałęzi pomostowych, które pozwolą na bezproblemowe pomyślne scalanie, aby dostać się do gałęzi głównej
Nawet w przypadku, gdy w jakiejś innej gałęzi pomostowej nie występują sprzeczne ze sobą scalenia. Identyfikowalność jest nieco lepsza, przynajmniej w przypadku, gdy jedno połączenie nie spodziewało się wpływającej zmiany od innego połączenia. Ale znowu jest to wystarczająco rzadkie, aby nie martwić się o to codziennie lub co tydzień.
Aby przez większość czasu mieć nieskonfliktowe połączenia, ważne jest rozsądne rozdzielenie gałęzi pomostowych, np. Na zespół, na warstwę lub na komponent / projekt / system / rozwiązanie (jakkolwiek to nazwiesz).
Jeśli główna gałąź została w międzyczasie przekazana do innego scalenia, musisz scalić ponownie. Mamy nadzieję, że nie jest to problem z połączeniami nie powodującymi konfliktów lub z bardzo niewielką liczbą konfliktów.
W porównaniu z bramkowanymi odprawami, zaletą jest to, że masz gwarancję działającego oddziału głównego, ponieważ główny oddział może tylko iść do przodu, a nie automatycznie łączyć zmiany z tym, co zostało popełnione pomiędzy. Zatem trzecia kwestia to zasadnicza różnica.
źródło
Wolę, aby „zdane testy jednostkowe” były bramą do przesyłania kodu. Aby jednak zadziałało, będziesz potrzebować kilku rzeczy.
Będziesz potrzebował struktury kompilacji, która buforuje artefakty.
Będziesz potrzebował środowiska testowego, które buforuje status testu z (udanych) uruchomień testowych, z dowolnym danym artefaktem (ami).
W ten sposób zameldowania z pozytywnymi testami jednostkowymi będą szybkie (kontrola krzyżowa ze źródła do artefaktu, który został zbudowany, gdy programista sprawdził testy przed odprawą), osoby z nieudanymi testami jednostkowymi zostaną zablokowane, a programiści, którzy wygodnie zapomnieć o sprawdzeniu kompilacji przed zatwierdzeniem. Zachęcamy do zrobienia tego następnym razem, ponieważ cykl kompilacji i testowania jest długi.
źródło
Powiedziałbym, że zależy to od projektu i zakresu automatycznych testów przeprowadzanych na „zatwierdzeniu”.
Jeśli testy, które chcesz uruchomić w wyzwalaczu odprawy, są naprawdę szybkie lub jeśli przepływ pracy programisty i tak wymusi trochę pracy administracyjnej, myślę, że nie powinno to mieć większego znaczenia i zmusić programistów do sprawdzania w rzeczach, które absolutnie uruchamiają najbardziej podstawowe testy. (Zakładam, że przeprowadzałbyś tylko najbardziej podstawowe testy z takim wyzwalaczem).
I myślę, że jeśli pozwala na to szybkość / przepływ pracy, dobrze jest nie wypychać zmian innym programistom, którzy nie przejdą testów - i wiesz tylko, czy zawiodą, jeśli je uruchomisz.
W pytaniu piszesz „zobowiązanie ... do zdalnej gałęzi”, co sugeruje mi, że to (a) nie jest czymś, co dev robi co kilka minut, więc małe oczekiwanie może być bardzo dobrze do przyjęcia, i (b) że po takie zatwierdzenie zmiany kodu mogą mieć wpływ na innych programistów, więc mogą być wymagane dodatkowe kontrole.
Mogę zgodzić się z innymi odpowiedziami na temat: „nie zmuszaj swoich deweloperów do kiwnięcia kciukami podczas oczekiwania” na taką operację.
źródło
Złamane zatwierdzenia nie powinny być dozwolone na pniu , ponieważ pień jest tym, co może wejść do produkcji. Musisz więc upewnić się, że istnieje brama, którą muszą przejść, zanim znajdą się w bagażniku . Jednak złamane zatwierdzenia mogą być całkowicie poprawne w repo, o ile nie ma ich na pniu.
Z drugiej strony wymaganie od deweloperów czekania / naprawiania problemów przed wprowadzeniem zmian do repozytorium ma szereg wad.
Kilka przykładów:
źródło