Czy nie byłoby korzystne pisać testy podczas przeglądania kodu?

24

Mój kolega wpadł na pomysł, który uznałem za interesujący.

Czy nie byłoby korzystne pisać testy podczas przeglądania kodu przez osobę, która dokonuje przeglądu, zakładając, że nie robimy TDD?

W przypadku tego pytania załóżmy, że jest to projekt czysto akademicki, więc nie ma mowy o życiu. Ponadto zespół składa się z 4 osób. Każdy zna język i zna wszystkie używane narzędzia / biblioteki / frameworki i potrafi pisać testy. Więc w zasadzie ludzie, którzy nie są starszymi fullstackami, prowadzą inżynierów ninja, ale porządnych programistów.

Plusy znalazłem:

  1. Zachęca do głębszego zrozumienia kodu podczas recenzji, aby pisać sensowne testy.
  2. Następnie można dodać przegląd kodu tych testów wykonanych przez autora testowanego kodu.

Wady znalazłem:

  1. Wzrasta pętla sprzężenia zwrotnego między pisaniem kodu a testowaniem.

EDYCJA: Wiem, że nie będzie działać dobrze w „normalnych” aplikacjach internetowych. Miałem na myśli przypadek narożny, w którym wdrażasz złożone algorytmy naukowe, które wymagają dbałości o szczegóły. Załóżmy coś w rodzaju implementacji własnej biblioteki grafów, NLP itp. Zastanawiam się, czy kod, który piszemy, jest odizolowany od baz danych i taki bardzo trudny do zrozumienia nie byłby dodatkowy poziom kontroli, druga osoba, która musi zrozumieć źródło kod i wykonaj sensowny test, czy cały proces będzie mniej podatny na mniej oczywiste błędy, które nie powodują awarii aplikacji, ale ostatecznie powodują marnotrawstwo wyników?

Sok Pomaranczowy
źródło
3
Nie wspominasz, czy ta seria testów byłaby ponad testami, które powinny wystąpić podczas opracowywania, czy zamiast.
Robbie Dee,
3
Byłoby korzystne, ale raczej utrudnione pisanie najtrudniejszych (test-in isolotaion), jeśli „nie robimy TDD”, ponieważ kod inny niż tdd jest zwykle trudny do wyizolowania. Pisanie testów akceptacyjnych i / lub testu integracyjnego będzie również utrudnione i / lub kruche, jeśli nie posiadasz warstwy abstrakcji bazy danych (repozytorium API), która pozwala zdefiniować odtwarzalne, niestabilne warunki wstępne.
k3b
4
@JoulinRouge: TDD pomaga w tym. Ponieważ nie ma kodu, nie można dostosować testu do swojego kodu.
Jörg W Mittag
6
To brzmi jak NAPRAWDĘ długi przegląd kodu.
David mówi Przywróć Monikę
2
Pracowałem w miejscach, w których w recenzjach uczestniczył inny programista przeglądający każdą napisaną linię, sprawdzając je pod kątem stylów i najlepszych praktyk oraz pisząc testy jednostkowe, o których nie pisałeś.
candied_orange

Odpowiedzi:

7

Czy pisanie testów podczas przeglądu kodu przez użytkownika nie byłoby korzystne?

Przekonałem się, że dobry moment na pisanie testów to takie, w których zdajesz sobie sprawę, że potrzebujesz testu na sytuację.

Przełączanie zadań dla komputerów jest drogie - a nawet bardziej dla ludzi.

W tym momencie na ogół dobrze rozumiesz wymagania i zależności dotyczące testu. Wykorzystaj więc zaangażowanie swojego zespołu w problem. Jeśli chcesz udoskonalić swój nowy test w przyszłości, świetnie, masz już gotową platformę testową / urządzenia, a wszystko, co musisz zrobić, to zmienić część, która wymaga ulepszenia.

Jeśli tak się stanie podczas przeglądu kodu, dlaczego nie zrobić tego? Zrobiłem to wcześniej. Przekonałem się, że jest to lepsze niż nie, szczególnie jeśli możesz to zrobić szybko, a nawet lepiej, jeśli nie zrobiłbyś tego inaczej.

Zakładając, że nie zajmujemy się TDD?

Nawet jeśli ćwiczysz TDD, jeśli zdasz sobie sprawę, że potrzebujesz testu podczas przeglądu kodu, którego nie masz, dlaczego nie napisać testu tu i tam?

Plusy

  • Skupiasz się na analizowanym kodzie.
  • Czasami sprawdzanie kodu staje się czasem spędzania czasu i czatem, gdy ludzie nie są w to zaangażowani. Napisanie testu zachęca wszystkich do bardziej aktywnego zastanowienia się nad recenzowanym kodem.
  • Więcej młodszych członków zespołu będzie miało okazję uczyć się na podstawie pisania testu.
  • Możesz zidentyfikować talent w swoim zespole, o którym nie wiedziałeś, że go masz.

Czy to naprawdę wada, że ​​więcej testów może prowadzić do większej ilości kodu? Jeśli test był potrzebny, a kod był potrzebny do testu, a teraz go masz, to dobrze .

Ostrzeżenia

Może część zespołu musi skupić się na innych rzeczach. Jeśli powoduje to odwrócenie uwagi od priorytetów lub przegląd kodu przebiega zgodnie z harmonogramem, musisz ograniczyć lub wyciąć faktyczne pisanie testu. Jednak przegląd kodu może z pewnością zidentyfikować testy, które należy napisać, i być może można je przynajmniej wyeliminować, aby autor mógł ukończyć później.

Aaron Hall
źródło
22

To wspaniały pomysł z jednym zastrzeżeniem. Nie zastępuj pisemnych testów programistów testami pisemnymi recenzentów. Poproś recenzentów o sprawdzenie przypadków narożnych i danych wejściowych, które złamią kod. Innymi słowy, poproś, aby spróbowali napisać nowe testy , których pierwotny programista nie chciał napisać.

Pisanie testów charakteryzujących jest absolutnie cudownym sposobem na zrozumienie fragmentu kodu, którego nie napisałeś. Poproś recenzentów o przeprowadzenie dodatkowych testów kodu, dzięki czemu będą mogli lepiej zrozumieć, jak działa kod, jak można go złamać i jak go ulepszyć. Cały czas zwiększając zasięg kodu.

To wszystko wygrane w mojej książce.

Gumowa kaczuszka
źródło
5
To prawie tak, jakbyś miał doświadczenie w sprawdzaniu kodu ...
syb0rg
Nie mam pojęcia o czym mówisz @ syb0rg ... Nie możesz tego udowodnić. =;) -
RubberDuck
2
kaszel ;-)
Mathieu Guindon
2
Również przypadek testowy jest najmniej dwuznacznym sposobem opisania usterki odkrytej w recenzji :-)
Steve Jessop
1
@ syb0rg Rubber Duck pomógł tysiącom lub milionom programistów naprawić swój kod . Kto jest lepiej wykwalifikowany do przeglądu kodu niż ten, który tyle widział?
jpmc26
18

Nie sądzę, aby pomysł był całkowicie bezzasadny - jednak główną zaletą TDD i innych jest to, że problemy pojawiają się wcześnie . Deweloper jest również najlepiej umiejscowiony, aby zauważyć, które przypadki narożne mogą wymagać szczególnej uwagi. Jeśli pozostanie to do czasu przeglądu kodu, istnieje ryzyko, że ta wiedza może zostać utracona.

Pisanie testów podczas przeglądu kodu napotkałoby ten sam problem, co tradycyjne testowanie ręczne - rozumienie reguł biznesowych może być różne dla różnych programistów, podobnie jak staranność.

Odwieczna dyskusja będzie przebiegać i sprawdzać, czy programiści tak dobrze przetestowaliby swój kod, gdyby wiedzieli, że istnieje funkcja testowania, która powinna wychwycić poważniejsze błędy.

Robbie Dee
źródło
Świetna odpowiedź. Ale co, jeśli nie zrobimy TDD, ponieważ ludzie nie chcą i nie mam nad nimi żadnej dźwigni, ale musimy upewnić się, że otrzymany wynik nie jest fałszywie pozytywny, ponieważ błąd wypaczył nasze wyniki? Głównym ryzykiem jest to, że ludzie mogą spieszyć się z wdrożeniem czegoś bez odpowiedniego zrozumienia, pisz testy z takim niewłaściwym zrozumieniem, mając na uwadze, że testy są udane, ale ostatecznie produkują zły kod. Może programowanie parami rozwiązałoby problem? Ale z drugiej strony łatwo jest zmusić kogoś do zrozumienia czegoś.
Sok Pomaranczowy
Myślę, że być może równie dobrze jak ktoś inny piszący testy, mogą one być uruchamiane przeciwko kodowi programistycznemu podczas opracowywania. Deweloperzy, o których mowa, musieliby znajdować się na tej samej stronie, pod którym znajduje się kod, w przeciwnym razie programista piszący kod mógłby nieustannie przechodzić nieudane testy przeciwpożarowe zamiast faktycznie działać.
Robbie Dee,
Problem nazywa się „uprzedzeniem konformacyjnym”.
ArTs,
W rzeczywistości powiedziałbym to, odwracając uwagę od procesu sprawdzania kodu, a kod miałby wpływ na proces testowania, co nie jest tym, czego chcesz, pozbawiając kluczową zaletę posiadania osobnego testera i kodera.
ArTs
1
@RobbieDee Jeśli odbiorca winy ma znaczenie, masz niezdrowe środowisko programistyczne. Jest to o wiele gorsze niż pominięcie kilku testów, które byłyby przydatne.
jpmc26
5

Zgadzam się z odpowiedzią @ RobbieDee, ale mam jeszcze coś do dodania.

Jeśli naprawdę podoba ci się ten pomysł, dlaczego te same osoby nie napisały testów przed kodem jako wykonalnych kryteriów akceptacji historii użytkownika?

To zrobiłoby to samo, nadal utrzymywałoby krótką informację zwrotną i zachęcało wszystkich do dyskusji na temat historii, która moim zdaniem miałaby większą wartość.

Wadami jest niebezpieczeństwo, że spełnienie niekończących się kryteriów akceptacji :-( i myślę, że próbujesz zachęcić ludzi do przeglądu kodu, aby spojrzeli na kod implementacyjny, ale sugerowałbym parowanie programowania i rotację par jako lepsze rozwiązanie ten problem.

OP dodał edycję, w której ułożyli dalsze szczegóły na temat tego, że jest to trudna lub obciążająca algorytm funkcja.

W odpowiedzi dodam, że twój instynkt zdobywania większej uwagi na problem i rozwiązanie jest dobry. Może sparuj z wieloma osobami jeden na jednego, dopóki wszyscy nie zobaczą naprawdę trudnego kodu implementacyjnego i testów. Każdy z nich rzuca nowe pomysły i dodaje więcej wartości.

Czasami pojawia się pomysł nazywania programowania moba, np. Parowania, ale z większą liczbą osób. To jest prawie to, o czym mówisz, ale pomagają one w momencie pisania, a nie w formalnej recenzji później. To nie jest dla wszystkich i może wymagać silnego kierowcy (lidera), aby działał, lub zespołu, który jest bardzo wygodny w stosunku do siebie i procesu.

Robiąc to po tym, jak programowanie mobów, miałbym wiele takich samych zalet, jak wiele oczu widziało problem i sugerowało ulepszenia, a jeśli w ten sposób twój zespół czuje się komfortowo, to może pomóc, ale naprawdę postaram się zachować niezbędne występowanie tego do minimum, ponieważ myślę, że może to spowolnić zespół.

Encaitar
źródło
Być może programiści powinni pisać testy według własnego uznania, przesyłać je do repozytorium, ale osoba dokonująca przeglądu powinna pisać własne testy i nigdy nie patrzeć na testy napisane przez programistów. Jeśli oba zestawy testów przejdą pomyślnie, ale jeśli testy recenzenta zakończą się niepowodzeniem, może to oznaczać problem?
Sok Pomaranczowy
1
@SokPomaranczowy dodawanie redundancji w pisaniu testów od różnych osób było próbowane w przeszłości. Myślę, że jeśli nie tworzysz oprogramowania o krytycznym znaczeniu dla życia, to marnujesz wysiłek, a zamiast tego powinieneś skoncentrować się na tym, gdzie najlepiej spędzić czas (nigdy nie napiszesz WSZYSTKICH testów) i przy dobrej komunikacji w zespole myślę, że jest znacznie lepszym podejściem.
Encaitar,
@Encaitar Zgadzam się, to po prostu brzmi jak ogromne pochłanianie czasu, które prawdopodobnie nie poprawi sytuacji. RoI i tak dalej ...
sara
3

Jak mówisz, jeśli prowadzisz zespół TDD, to jest to kwestia sporna, ponieważ kod powinien już zostać przetestowany.

Ogólnie rzecz biorąc, nie sądzę, że to świetny pomysł, ale zależy to od twojego obecnego podejścia i tego, co działa dla Ciebie. Zasadniczo problem, jaki widzę, polega na tym, że tracisz przewagę wynikającą z „krótkiej pętli sprzężenia zwrotnego” testów. Otrzymywanie natychmiastowych powiadomień w momencie, gdy coś zepsujesz, nawet gdy piszesz nowy kod, jest miejscem, w którym testy naprawdę świecą. Jeśli odłożysz testowanie do czasu przeglądu kodu, w zasadzie mówisz „dobrze, MOGŁEM naprawić ten problem wcześniej w krótszym czasie i przy mniejszej liczbie zaangażowanych osób, ale przynajmniej wszyscy się czegoś nauczyliśmy (może)”. Wolę po prostu upewnić się, że ludzie przesyłają przetestowany kod do sprawdzenia, a następnie ocenisz poprawność i łatwość konserwacji testów. W końcu przegląd kodu służy do recenzji, a nie do pisania kodu.

Z drugiej strony, polecam FIDDLE z testami / kodem podczas przeglądu. Spróbuj coś zepsuć. Skomentuj warunek if. zamień wartość logiczną na literalną wartość prawda / fałsz. Sprawdź, czy testy się nie powiodły.

Ale tak, w sumie, polecam napisać testy razem z kodem, a następnie przejrzeć je wszystkie naraz.

sara
źródło
2

To zależy od tego, co robisz podczas przeglądu kodu. Myślę, że istnieją dwa główne powody pisania testów na tym etapie:

  • po pierwsze, jeśli dokonujesz również refaktoryzacji podczas przeglądania kodu i zauważysz, że nie ma wystarczającej liczby testów jednostkowych, aby pokryć rodzaj refaktoryzacji, który chcesz zastosować, dodaj takie testy

  • po drugie, jeśli kod wygląda na to, że może zawierać błąd i chcesz go udowodnić (lub obalić), napisz test

Oba przypadki wyrażają potrzebę testów, których obecnie nie ma, ale powinny. Oczywiście, może zależeć od kultury twojego zespołu, czy tego rodzaju testy powinny być napisane przez recenzenta lub oryginalnego autora, ale ktoś powinien napisać testy.

Właściwie nie sądzę, że jest to „przypadek narożny” odpowiedni tylko do „złożonych, naukowych algorytmów” - wręcz przeciwnie, jest odpowiedni dla każdego rodzaju oprogramowania, od którego oczekuje się określonego poziomu jakości.

Doktor Brown
źródło
2

Nie rób tego. Sprawisz, że będą myśleć, że TDD jest okropny.

Myślę, że @ k3b ma rację w komentarzach do pytania. Kod napisany w procesie TDD ma tendencję do wyglądania i interakcji, zupełnie inaczej niż kod napisany bez testów. Dodanie (dobrych) testów do nieprzetestowanego kodu zwykle wymaga dużo refaktoryzacji kodu w celu wyjaśnienia jego zamiarów i ruchomych części.

Dodając testy po napisaniu kodu, tracisz architektoniczne aspekty korzyści TDD (które moim zdaniem są jedną z głównych korzyści). Mało tego, prosisz kogoś innego, kto nie jest tak dobrze zaznajomiony z kodem, aby spróbował dodać testy, które już są trudne do dodania.

Albo osoba dodająca testy będzie musiała znacznie przefaktoryzować kod, albo będzie musiała bardzo ciężko pracować, aby przetestować kod nie do przetestowania. Tak czy inaczej, nie będą cieszyć się tym doświadczeniem. Chociaż może to nie być klasyczny TDD, nie zobaczą go w ten sposób i możesz odłożyć je na zawsze.

(Jeśli już śledzisz proces TDD, pisanie dodatkowych testów podczas przeglądania kodu byłoby mniej szkodliwe, chociaż z mojego doświadczenia wynika, że ​​jeśli testy są już dobrze napisane, równie łatwo wyjaśnić dodatkowy test osobie składającej kod do recenzji i poproś o ich napisanie).

Andy Mortimer
źródło
1

Testy jednostkowe podczas przeglądania kodu są słabym zamiennikiem testów jednostkowych podczas programowania.

To, co sugerujesz, ma sens, intuicyjnie. Do czego służy opinia? Aby sprawdzić, czy kod jest dobry. Do czego służą testy? Aby sprawdzić, czy kod jest dobry. Dlaczego więc nie połączyć tych dwóch elementów?

Dlatego.

Testowanie kodu to ciężka praca. Pisanie kodu, który działa tylko w jednym celu, to jedna rzecz; pisanie kodu, który można skutecznie i wydajnie przetestować, to kolejne. Sam fakt, że kod działa teraz w dwóch scenariuszach - „prawdziwej pracy” i „testowaniu” - wymaga znacznie większej elastyczności, wymaga od tego, aby kod mógł samodzielnie działać w znaczący sposób.

Pisanie kodu w celu jego przetestowania to dodatkowa praca i umiejętności. Refaktoryzacja kodu innej osoby pod kątem testowalności, jeśli nie została napisana z myślą o testowaniu na początku, może być dużym zadaniem.

Dublujesz wysiłek programisty i recenzenta. Można przypuszczać, że programista nie podając swój kod do sprawdzenia bez przynajmniej pewnym poziomem ufności, że to działa. On już musi przetestować kod. Teraz istnieją różne poziomy i zakresy testowania. Kontrola jakości testuje kod po programiście i recenzencie. Ale niezależnie od tego, jaki zakres uważasz za odpowiedni dla programisty i recenzenta, nie ma sensu, aby programista raz testował kod na tym poziomie , ale sprawiał, że jego testy były niepotrzebne i trudne do odtworzenia, a następnie doprowadził recenzenta do opracuj test ponownie, tym razem zautomatyzowane i odtwarzalne. Wystarczy, że oboje zainwestują czas w pisanie tych samych testów - raz źle, raz dobrze.

Zmieniasz recenzję w znacznie dłuższy i bardziej pracochłonny krok. Jeśli testowanie jest główną częścią procesu przeglądu, co się stanie, gdy niektóre testy się nie powiodą ? Czy recenzent jest odpowiedzialny za uruchomienie testów, więc musi również debugować kod? A może będzie ping-pong w jedną i drugą stronę, jeden test pisania, a drugi sprawi, że zdadzą egzamin?

Czasami możesz napisać całą serię testów, które są do siebie prostopadłe, więc nie musisz ping-ponga. Recenzent pisze kilkanaście testów, połowa z nich kończy się niepowodzeniem, programista naprawia błędy, a wszystkie testy pozostają ważne i przechodzą teraz. Ale ... dużo czasu masz błędy blokujące lub błędy wymagające przeprojektowania i zmian interfejsu API, czy coś w tym rodzaju. Jeśli podrzucasz odpowiedzialność za przekazywanie testów tam iz powrotem między recenzentem a programistą, to tak naprawdę nie jesteś na etapie recenzji. Nadal się rozwijasz.

Konieczność napisania testów nie zachęca do dokładniejszego przeglądu. Zasadniczo oznacza to, że im głębiej idziesz, tym więcej testów musisz napisać, i prawdopodobnie będą to trudne testy, które muszą wejść głęboko w system.

Porównaj z programistą piszącym testy, gdzie jego motywacją jest: jeśli nie piszę ważnych testów, recenzent zwróci na to uwagę w recenzji.

Nawet recenzent będzie miał znacznie lepsze zrozumienie systemu, jeśli będzie musiała przejść dokładne testy kodu , a następnie, jeśli będzie musiała sama zdecydować, kiedy może przestać pisać test głębokiego wyszukiwania i po prostu OK recenzję kodu.

Jeśli programista nie pisze testów jednostkowych, recenzent też tego nie zrobi. Istnieje wiele przeszkód w przyjmowaniu testów jako powszechnej praktyki. Może jesteś pod zbyt dużą presją, a twoja baza kodu jest trudna do przetestowania. Być może nie masz zbyt dużego doświadczenia w testowaniu i masz wrażenie, że nie stać Cię na naukę. Może masz mordercę siekiery wysyłającego groźne notatki do ludzi, którzy piszą testy. Nie wiem!

Ale bez względu na przyczynę można bezpiecznie założyć, że dotyczy to zarówno recenzenta, jak i programisty. Jeśli zespół jest zestresowany, recenzent nie ma więcej czasu niż programista (jeśli tak, rozdziel pracę, aby ludzie nie byli tak zestresowani ). Jeśli nikt nie wie, jak dobrze pisać testy jednostkowe, recenzent prawdopodobnie również nie (jeśli tak, powinna usiąść i uczyć swoich kolegów z drużyny ).

Ta sugestia brzmi jak próba przekazania złotówki od jednego kolegi do drugiego. I po prostu nie widzę żadnego sposobu, aby to dobrze zadziałało, przede wszystkim dlatego, że naprawdę ciężko (i niezdrowo) jest stworzyć sytuację, w której jedna osoba jest jedyną, która może wykonywać testy, a inna nie może jakiekolwiek testy w ogóle.


Co robi pracy jest posiadanie testy pokrywy ocena również. Jeśli programista napisał już dziesięć testów, jest o wiele bardziej prawdopodobne, że recenzent może zasugerować kolejną dziesięć, niż gdyby programista nie napisał żadnego.

A jeśli testowanie narożnych przypadków jest poważnym zadaniem, sensowniejsze może być rozpowszechnianie tego w całym zespole. ** Kiedy kod jest w pierwszej kolejności testowalny, pisanie kolejnych testów staje się znacznie łatwiejsze. **

Recenzja to świetny czas na wykrycie narożnych skrzynek. A jeśli recenzent może wskoczyć i napisać test dla narożnych skrzynek, które znajdzie, to hej - tym lepiej! Ale ogólnie mówiąc, zakładając, że recenzent może napisać testy, w których programista nie brzmi jak bardzo kiepski pomysł.

Cofnij się
źródło