Czy powinienem celowo przerywać kompilację, gdy w produkcji zostanie wykryty błąd?

410

Wydaje mi się rozsądne, że jeśli poważny błąd zostanie wykryty przez użytkowników końcowych, należy dodać test jednostkowy, który go nie obejmuje, celowo przerywając kompilację, dopóki błąd nie zostanie naprawiony. Moim uzasadnieniem jest to, że kompilacja powinna była zawieść przez cały czas , ale nie było to spowodowane nieodpowiednim automatycznym zasięgiem testów.

Kilku moich kolegów nie zgodziło się ze stwierdzeniem, że nie powiodło się sprawdzenie testu jednostkowego. Zgadzam się z tym punktem widzenia w zakresie normalnych praktyk TDD, ale uważam, że błędy produkcyjne powinny być traktowane inaczej - w końcu dlaczego chcesz pozwolić kompilacja pozwalająca odnieść sukces ze znanymi wadami?

Czy ktoś jeszcze sprawdził strategie radzenia sobie z tym scenariuszem? Rozumiem, że celowe przerwanie kompilacji może być szkodliwe dla innych członków zespołu, ale to całkowicie zależy od tego, jak korzystasz z gałęzi.

MattDavey
źródło
75
+1; bardzo prowokujące pytanie. Widzę obie strony.
Carl Manaster,
28
Używasz terminu „kompilacja”, aby uwzględnić „testy”, co nie jest uniwersalnym rozumieniem.
Jay Bazuzi,
19
Jeśli robisz TDD, napiszesz test zakończony niepowodzeniem, a następnie naprawisz kod, a następnie zameldujesz się . W ten sposób unikniesz zepsutej wersji.
dietbuddha
7
Zgodnie z tą samą logiką należy zamknąć instancje na żywo klientów, dopóki problem nie zostanie rozwiązany. Nie, nie powinieneś przerywać kompilacji. Pozwól programistom obsługującym błąd dodać test jednostkowy i kod zmienia się razem. Nie ma potrzeby wyłączania całego procesu.
Thanos Papathanasiou

Odpowiedzi:

412

Nasza strategia to:

Sprawdź test zakończony niepowodzeniem, ale opatrz go adnotacją @Ignore("fails because of Bug #1234").

W ten sposób test jest gotowy, ale kompilacja się nie psuje.

Oczywiście zanotowano ignorowany test w db db, więc @Ignorejest on usuwany po naprawieniu testu. Służy to również jako łatwe sprawdzenie poprawki błędu.

Celem przełamania kompilacji po nieudanych testach nie jest jakoś wywarcie presji na zespole - to ostrzeżenie go o problemie. Gdy problem zostanie zidentyfikowany i zapisany w bazie danych błędów, nie ma sensu uruchamiać testu dla każdej kompilacji - wiesz, że zakończy się niepowodzeniem.

Oczywiście błąd powinien zostać naprawiony. Ale zaplanowanie poprawki jest decyzją biznesową, a więc tak naprawdę nie jest troską dewelopera ... Dla mnie, gdy błąd zostanie zgłoszony w DB błędu, nie jest to już mój problem, dopóki klient / właściciel produktu nie powie mi, że chce go naprawić .

Śleske
źródło
150
+1 Wydaje mi się, że trafiłeś w sedno słowem „planowanie poprawki jest decyzją biznesową” - jako programista nie jest moim osądem decydowanie, czy błąd psuje kompilację.
MattDavey,
22
Myślę, że to bardzo rozsądne rozwiązanie. Zwłaszcza jeśli następny facet, który sprawdzi jakiś drobny kod, nagle otrzyma powiadomienie o „nieudanym teście” i myśli, że to zrobił.
Holger
14
„Dla mnie, gdy błąd zostanie zgłoszony w bazie danych błędów, nie jest to już mój problem” ... +1
Jake Berger,
20
@anon Exept w Toyota. Pracownik linii widzi defekt, a następnie naciąga przewód andonowy i cała instalacja zatrzymuje się, następuje zarządzanie i linia nie jest restartowana, dopóki problem nie zostanie rozwiązany. Google Andon Cord. To nie jest nowa koncepcja. patrz: startuplessonslearned.com/2008/09/…
Christopher Mahan
4
@AndresJaanTack: Oczywiście będzie to zależeć od twojej metodologii, ale ogólnie nie zgadzam się. Przynajmniej w otoczeniu biznesowym planowanie pracy jest decyzją biznesową - i obejmuje naprawianie błędów . Czasami nowa funkcja (lub wydanie w określonym dniu) może być bardziej wartościowa niż naprawienie (mniejszego) błędu - w takim przypadku poprawka musi zostać odroczona. „Naprawianie błędu teraz” byłoby niewłaściwe w tej sytuacji, ponieważ opóźnia ważniejszą pracę.
śleske,
106

Dlaczego chcesz pozwolić kompilacji na powodzenie ze znanymi defektami?

Ponieważ czasami masz ograniczenia czasowe. Lub błąd jest tak niewielki, że tak naprawdę nie warto opóźniać wysyłki produktu na kilka dni, aby przeprowadzić test jednostkowy i naprawić.

Jaki jest sens celowego przerywania kompilacji za każdym razem, gdy znajdziesz błąd? Jeśli go znalazłeś, napraw go (lub przypisz to osobie, która go naprawi), nie przeszkadzając całemu zespołowi. Jeśli chcesz pamiętać o naprawieniu błędu, musisz oznaczyć go jako bardzo ważny w systemie śledzenia błędów.

Arseni Mourzenko
źródło
Rozumiem twój punkt widzenia i ogólnie się zgadzam - ale w tym przypadku mówimy o poważnym błędzie, który wszedł do produkcji i został napotkany przez użytkowników końcowych: s
MattDavey
3
Zobacz drugi akapit mojej odpowiedzi.
Arseni Mourzenko,
8
Rozumiem, myślę, że punkt ten został podsumowany w twoim pierwszym akapicie - to nie do dewelopera należy ocena powagi błędu ani tego, czy jest to show-stopper, to decyzja dla szerszego biznesu.
MattDavey,
4
Pytanie brzmi, jaki jest priorytet tego błędu? To może być OMG FIX IT NOW, to może być tak, denerwujące, że powinniśmy to naprawić w pewnym momencie, może to być coś pośrodku. Ale nie wszystkie błędy trafią w to samo miejsce w tym spektrum.
Zachary K
55

Istnieją testy, aby upewnić się, że nie (ponownie) wprowadzasz problemów. Lista nieudanych testów nie zastępuje systemu śledzenia błędów. W POV istnieje pewna poprawność, że nieudane testy nie tylko wskazują na błędy, ale także wskazują na niepowodzenie procesu rozwoju (od nieostrożności do źle zidentyfikowanej zależności).

AProgrammer
źródło
20
„lista nieudanych testów nie zastępuje systemu śledzenia błędów” +1, również bardzo dobry punkt :)
MattDavey
1
Sugerowałbym, aby testy jednostkowe regresji wprowadzały bazę kodu jako część poprawki błędu, nie wcześniej.
jer
6
@yarek: Testy regresji mogą przejść do bazy kodu w dowolnym momencie, należy je tylko zignorować, aż błąd zostanie naprawiony. Zwykle rozwijam je podczas diagnozowania problemu, ponieważ mogą one następnie służyć jako pomoc przy debugowaniu.
śleske,
Jest to dobry przykład tego, dlaczego „przełamanie kompilacji” staje się toksyczną częścią miejsca pracy, w którym CI przekształca się w „rozwój oparty na winie”. Siedziałem na wielu spotkaniach, na których PHB zaczyna narzekać na „niedbalstwo”, jakby to dlatego załamała się kompilacja. W takim środowisku z trudem celowo nie sprawdzałeś czegoś, co popsuło kompilację. W przeciwnym razie PHB się zdenerwuje. Zerwij kompilację, noś stożek wstydu. Co za kiepska praktyka.
Warren P,
@WarrenP, są czasem inne problemy, ale bądźmy szczerzy, niedbalstwo jest pierwszym powodem, dla którego kompilacje się psują. Jeśli wiesz, że coś psuje kompilację, po co to sprawdzać?
AProgrammer
23

„Przerwij kompilację” oznacza zapobieganie pomyślnemu ukończeniu kompilacji . Niepowodzenie testu tego nie robi. Wskazuje to, że kompilacja ma znane wady, co jest dokładnie poprawne.

Większość serwerów kompilacji śledzi status testów w czasie i przypisuje inną klasyfikację testowi, który nie powiódł się, ponieważ został dodany w porównaniu z regresją (test, który przeszedł pomyślnie i już go nie robi), a także wykrywa wersję, w której nastąpiła regresja.

Ben Voigt
źródło
12
Nie zawsze jest to poprawne, często zespoły uważają nieudany test za zepsuty build - w rzeczywistości większość zespołów, które ostatnio widziałem (to typowa zwinna praktyka). W przypadku większości zwinnych zespołów nieudanym testem jest zatrzymanie linii - cały zespół atakuje problem i rozwiązuje go. Podejrzewam, że mógłbym przyjąć twój post, co oznacza, że ​​odpowiedź musi opierać się na twoich praktykach, w którym to przypadku jest całkowicie dokładna.
Bill K
2
Zawsze uważam, że test zakończony niepowodzeniem oznacza, że ​​kompilacja zakończyła się niepowodzeniem.
John Saunders,
@JohnSaunders: Ale to nie to oznacza. Jak powiedziałem w mojej odpowiedzi, oznacza to, że „kompilacja znała wady”.
Ben Voigt,
1
@ho powiedział, że nie było testów? Skąd to masz? Mam na myśli, że moim pierwszym krokiem po znalezieniu błędu nie jest uniemożliwienie kompilacji, ale stworzenie szczegółowego raportu o błędzie. Gdy błąd zostanie naprawiony, najpierw powinien zostać przeprowadzony test jednostkowy zakończony niepowodzeniem.
John Saunders,
1
Nie mam problemu z natychmiastowym utworzeniem testu zakończonego niepowodzeniem. Po prostu nie chcę, aby zostało zarejestrowane w zestawie testów, które będą działać podczas kompilacji. Chcę też, aby programista, który naprawi błąd, mógł zignorować ten test. W większości miejsc, w których pracowałem, osoby, które utworzą raport o błędach, nie będą tworzyć testów jednostkowych.
John Saunders,
16

Argumentowałbym, że test negatywny powinien zostać dodany, ale nie jawnie jako „test negatywny”.

Jak podkreśla @BenVoigt w swojej odpowiedzi , nieudany test niekoniecznie „psuje kompilację”. Wydaje mi się, że terminologia może się różnić w zależności od zespołu, ale kod nadal się kompiluje, a produkt może zostać dostarczony z testem zakończonym niepowodzeniem.

W tej sytuacji powinieneś zadać sobie pytanie:

Jakie testy mają zostać wykonane?

Jeśli testy są po to, aby wszyscy czuli się dobrze z kodem, wówczas dodanie testu zakończonego niepowodzeniem tylko po to, aby wszyscy poczuli się źle z powodu kodu, nie wydaje się produktywne. Ale w takim razie, jak wydajne są testy?

Twierdzę, że testy powinny odzwierciedlać wymagania biznesowe . Jeśli więc zostanie znaleziony „błąd” wskazujący, że wymaganie nie jest właściwie spełnione, oznacza to również , że testy nie odzwierciedlają poprawnie lub w pełni wymagań biznesowych.

To jest błąd, który należy naprawić w pierwszej kolejności. Nie dodajesz „testu zakończonego niepowodzeniem”. Jesteś poprawiania testów aby być bardziej dokładnym odzwierciedleniem wymagań biznesowych. Jeśli kod nie przejdzie tych testów, to dobrze. Oznacza to, że testy wykonują swoją pracę.

Priorytet ustalenia kodu ma zostać określony przez firmę. Ale czy dopóki testy nie zostaną naprawione, czy rzeczywiście można ustalić ten priorytet? Firma powinna być uzbrojona w wiedzę na temat tego, co dokładnie zawodzi, jak się zawodzi i dlaczego zawodzi, aby podejmować decyzje dotyczące priorytetów. Testy powinny to wskazać.

Posiadanie testów, które nie są w pełni zaliczone, nie jest złą rzeczą. Tworzy wielki artefakt znanych problemów, które należy traktować priorytetowo i odpowiednio nimi traktować. Problemem są jednak testy, które nie są w pełni testowane . Podważa wartość samych testów.

Mówiąc inaczej: kompilacja jest już zepsuta. Ty decydujesz tylko, czy zwrócić uwagę na ten fakt.

David
źródło
1
Twoje twierdzenie jest błędne, testy jednostkowe niekoniecznie muszą być mapowane bezpośrednio na wymagania biznesowe, podczas gdy testy funkcjonalne lub kompleksowe prawdopodobnie tak, ale OP mówił o testach jednostkowych / TDD.
John Buchanan,
@JohnBuchanan: Jakie testy mają na celu sprawdzenie poprawności, jeśli nie to, że oprogramowanie robi to, co powinno? (To znaczy, że spełnia wymagania.) Istnieją, jak twierdzisz, inne formy testów poza testami jednostkowymi. Ale nie dostrzegam wartości w testach jednostkowych, które nie potwierdzają, że to oprogramowanie spełnia potrzeby firmy.
David
1
@JohnBuchanan - nie powiedział „testy są odzwierciedleniem wymagań biznesowych”, powiedział „POWINIEN BYĆ”. Co prawda, ale dyskusyjne. Masz rację, twierdząc, że nie zawsze tak jest - niektóre osoby piszą testy jednostkowe, które nie są dostosowane do wymagań biznesowych - chociaż (moim zdaniem) są w błędzie. Jeśli chcesz twierdzić, że twierdzenie Dawida jest błędne, możesz powiedzieć coś o tym, dlaczego tak uważasz.
Dawood ibn Kareem
13

W naszym zespole ds. Automatyzacji testów sprawdzamy testy zakończone niepowodzeniem, pod warunkiem, że zakończą się one niepowodzeniem z powodu wady produktu, a nie wady testu. W ten sposób mamy dowód dla zespołu programistów, że hej, oni go złamali. Zerwanie z kompilacją jest bardzo rozczarowane, ale to nie to samo, co sprawdzanie w doskonale kompilowalnych, ale nieudanych testach.

Yamikuronue
źródło
4
Myślę, że pomysł @ MattDavey jest doskonały, i opowiadałem się za nim w przeszłości. Zawsze spotkałem kamienny mur oporu - „nigdy nie powinieneś łamać kompilacji!”. Pomysł, że kompilacja jest już zepsuta w tej sytuacji, wydaje się niemożliwy do zrozumienia dla ludzi. Niestety, jest to tylko kolejny przypadek, w którym dobry pomysł (automatyczne testowanie i czyste kompilacje) przekształcił się w praktykę kultu ładunków, której wyznawcy znają regułę, ale nie powód.
Tom Anderson
3
Jednym z pomysłów, które wpadłem na pomysł, jest to, że zespół QA (jeśli jest wystarczająco techniczny, aby pisać testy) powinien mieć możliwość pisania testów nieudanych pod kątem błędów i sprawdzania ich. Obsesja programistów na punkcie zielonego paska doprowadziłaby wówczas do pierwszeństwo naprawiania błędów przed dodawaniem funkcji, co jest prawidłowym sposobem programowania.
Tom Anderson
Ale nie powinny to być testy jednostkowe, które będą przeprowadzane podczas kompilacji. Jeśli twoje środowisko zawiera system zarządzania testami do kontroli jakości (np. Microsoft Test Manager), to z pewnością należy dodać jeden lub więcej przypadków testowych i połączyć je z błędem, ale to nie przeszkodzi w pomyślnej kompilacji - będzie to po prostu test sprawa, która musi przejść, zanim błąd zostanie uznany za „Gotowy”.
John Saunders,
7

Pisanie testu, o którym wiesz, że się nie powiedzie, dopóki błąd nie zostanie naprawiony, to dobry pomysł, jest to podstawa TDD.

Złamanie kompilacji to zły pomysł. Dlaczego? Ponieważ oznacza to, że nic nie może się poruszać, dopóki nie zostanie naprawione. Zasadniczo blokuje wszystkie inne aspekty rozwoju.

Przykład 1
Co zrobić, jeśli twoja aplikacja jest bardzo duża i zawiera wiele składników? Co się stanie, jeśli nad tymi komponentami pracują inne zespoły z własnym cyklem wydawniczym? Twardy! Muszą czekać na naprawę błędu!

Przykład 2
Co zrobić, jeśli pierwszy błąd jest trudny do naprawienia, a znajdziesz inny błąd o wyższym priorytecie? Czy również przerywasz kompilację drugiego błędu? Teraz nie możesz budować, dopóki oba nie zostaną naprawione. Stworzyłeś sztuczną zależność.

Nie ma logicznego powodu, dla którego niepowodzenie testu powinno zatrzymać kompilację. Jest to decyzja, którą zespół deweloperów musi podjąć (być może podczas dyskusji zarządczej), wyważając zalety i wady wydania kompilacji ze znanymi błędami. Jest to bardzo powszechne w rozwoju oprogramowania, prawie całe główne oprogramowanie jest wydawane z przynajmniej niektórymi znanymi problemami.

Qwerky
źródło
5

Zależy to od roli, jaką mają odgrywać testy i jaki wpływ mają ich wyniki na przyjęty system / proces kompilacji. Moje rozumienie łamania kompilacji jest takie samo jak Bena, a jednocześnie nie powinniśmy świadomie sprawdzać kodu, który psuje istniejące testy. Jeśli te testy pojawią się „później”, może być „w porządku” ich zignorowanie, aby uczynić je mniej niepotrzebnie szkodliwymi dla innych, ale uważam, że taka praktyka ignorowania nieudanych testów (tak, aby zdawały się zdać) jest raczej niepokojąca (szczególnie w przypadku testów jednostkowych), chyba że istnieje sposób wskazania takich testów jako czerwonego ani zielonego.

prusswan
źródło
„chyba że istnieje sposób wskazania takich testów, jak ani czerwony, ani zielony”. Dla przypomnienia: większość platform testowania jednostkowego rozróżnia testy czerwony, zielony i ignorowane. Robią to przynajmniej JUnit i TestNG (zgłaszają „xx test, x nie powiodło się, x zignorowano”).
śleske,
@sleske, który byłby idealny, chcę tylko mieć pewność, że ignorowanie awarii nie zamieni się automatycznie w sukces
prusswan
Czy nie ma ŻÓŁTYCH wersji? (Czerwony / Zielony / Żółty) w Hudson / Jenkins, Cruise Control i wszystkich innych biggies?
Warren P,
@Warren P działa, gdy ludzie poprawnie ignorują testy, ale niektóre ignorują testy, zmieniając je na zielone
prusswan
5

Zależy to oczywiście od błędu, ale ogólnie, jeśli coś poszło nie tak, co nie zostało wykryte podczas testowania ręcznego lub automatycznego, oznacza to, że masz lukę w zasięgu. Zdecydowanie zachęciłbym do znalezienia głównej przyczyny i umieszczenia jednostkowego przypadku testowego nad problemem.

Jeśli jest to problem produkcyjny, który jest planowany dla poprawki z gałęzi serwisowej, musisz także upewnić się, że poprawka działa na linii głównej i że programista nie może omyłkowo usunąć poprawki z nadgorliwym rozwiązaniem konfliktu scalania .

Ponadto, w zależności od polityki wersji, obecność nowo zaktualizowanych testów jednostkowych może pomóc potwierdzić, że programista naprawił problem, a nie tylko go zmienić [(problem czy testy?)], Chociaż zależy to od zakodowania poprawne wymagania w nowych testach jednostkowych.

Keith przynosi
źródło
5

Jednym z problemów związanych z dodawaniem testu kompilacji „know-to-fail” jest to, że Twój zespół może mieć zwyczaj ignorowania testów zakończonych niepowodzeniem, ponieważ oczekuje, że kompilacja się nie powiedzie. Zależy to od systemu kompilacji, ale jeśli test zakończony niepowodzeniem nie zawsze oznacza „coś się właśnie zepsuło”, łatwo jest poświęcić mniej uwagi testom zakończonym niepowodzeniem.

Nie chcesz pomagać swojemu zespołowi w tym sposobie myślenia.

Zgadzam się więc z sleske, że powinieneś dodać test, ale zaznacz go jako „zignorowany” na potrzeby automatycznej kompilacji, dopóki błąd nie zostanie naprawiony.

Wilka
źródło
1
Twoje oprogramowanie testowe powinno poinformować cię, gdy coś się zepsuło, a test, który wcześniej nie powiódł się.
Ben Voigt,
4

Chociaż uważam, że powinieneś w jakiś sposób „sprawdzić” błąd jako test, aby po jego naprawieniu nie powtórzył się on i w jakiś sposób nadać mu priorytet, myślę, że najlepiej nie przerywać kompilacji (/ testów) . Powodem jest to, że późniejsze zobowiązania do rozbijania kompilacji zostaną ukryte za zepsutym testem. Dlatego sprawdzając uszkodzony test pod kątem tego błędu, żądasz, aby cały zespół odłożył na bok swoją pracę, aby naprawić ten błąd. Jeśli tak się nie stanie, możesz skończyć z łamaniem zatwierdzeń, których nie da się prześledzić.

Dlatego powiedziałbym, że lepiej jest wykonać go jako test w toku, a priorytetem w twoim zespole jest brak testów w toku.

markijbema
źródło
4

Inną opcją jest sprawdzenie testu zakończonego niepowodzeniem w oddzielnej gałęzi w systemie kontroli źródła. W zależności od praktyk może to być wykonalne lub nie. Czasami otwieramy nowy oddział do bieżącej pracy, na przykład naprawiania błędu, który nie jest trywialny.

Ola Eldøy
źródło