Myślałem o rozwoju oprogramowania i pisaniu testów jednostkowych. Mam następujący pomysł:
Załóżmy, że mamy pary programistów. Każda para odpowiada za część kodu. Jeden z pary implementuje funkcję (pisanie kodu), a drugi pisze dla niej testy jednostkowe. Testy są pisane po kodzie. Według mnie pomagają sobie nawzajem, ale działają raczej osobno. Idealnie byłoby pracować na dwóch podobnych rozmiarach, a następnie wymienić na przygotowanie do testu.
Myślę, że ten pomysł ma kilka zalet:
- testy są pisane przez kogoś, kto może zobaczyć więcej o implementacji,
- praca powinna być wykonywana niewiele szybciej niż programowanie parami (dwie funkcje jednocześnie),
- zarówno testy, jak i kod ma za to osobę odpowiedzialną,
- kod jest testowany przez co najmniej dwie osoby, oraz
- być może wyszukiwanie błędów w kodzie napisanym przez osobę, która testuje kod, dałoby specjalną motywację do pisania lepszego kodu i unikania skracania narożników.
Być może dobrym pomysłem jest dodanie kolejnego programisty do przeglądu kodu między kodem a testowaniem.
Jakie są wady tego pomysłu? Czy jest już opisana jako nieznana mi metodologia i stosowana w rozwoju oprogramowania?
PS. Nie jestem zawodowym kierownikiem projektu, ale wiem coś o procesach rozwoju projektu i znam kilka najpopularniejszych metodologii - ale ten pomysł nie wydaje mi się znajomy.
źródło
assert true
jako testy i nazywają to dniem, ponieważ każdy test mijał. Brakowało jednego ważnego kroku: testy powinny zakończyć się niepowodzeniem jako pierwsze i należy je wykonać, zmieniając kod, a nie testy.Odpowiedzi:
Ogólne podejście polegające na stosowaniu par do dzielenia wysiłków związanych z pisaniem kodu produkcyjnego i pisaniem powiązanych testów jednostkowych nie jest rzadkie. Już wcześniej osobiście sparowałem w ten sposób z dobrym skutkiem. Jednak ścisła granica między osobą piszącą kod produkcyjny a osobą piszącą kod testowy niekoniecznie musi dać wyniki.
Kiedy zastosowałem podobne podejście, para zaczyna od rozmowy i wspólnego zrozumienia problemu. Jeśli używasz TDD, możesz zacząć od kilku podstawowych testów. Jeśli nie używasz TDD, być może zaczniesz od definicji metody. Odtąd obaj członkowie pary pracują zarówno nad kodem produkcyjnym, jak i testowym, przy czym jedna osoba koncentruje się na każdym aspekcie, ale mówi o sposobach ulepszenia kodu produkcyjnego, a także kodu testowego.
Nie widzę korzyści z nadania każdej parze dwóch funkcji. To, co byś skończył, to coś, co przypomina TDD dla niektórych funkcji, a coś, co nie jest dla innych funkcji. Tracisz koncentrację. Nie zyskujesz korzyści z wzajemnej oceny w czasie rzeczywistym. Nie zyskujesz żadnej z głównych zalet parowania.
Praktyka programowania par nie polega na szybkości, ale na jakości. Więc próba użycia zmodyfikowanej techniki napędzanej szybszym biegiem jest sprzeczna z naturą. Budując oprogramowanie wyższej jakości poprzez równoległe przeglądanie kodu i opracowywanie testów, oszczędzasz czas na dalszych etapach, ponieważ co najmniej dwie osoby mają wiedzę o każdej zmianie i eliminujesz (lub redukujesz) cykle oczekiwania na przegląd i testowanie.
źródło
Głównym problemem związanym z Twoim pomysłem jest to, że nie możesz po prostu pisać testów dla dowolnego kodu. Kod musi być testowalny.
Tzn. Musisz mieć możliwość wstrzykiwania próbnych prób, oddzielić bit, który chcesz przetestować, dostęp do stanu, który został zmieniony i wymaga potwierdzenia itp.
O ile nie masz szczęścia lub nie napisasz testu jako pierwszy, szanse na napisanie testu oznaczają trochę przepisanie kodu. Co, jeśli nie jesteś osobą, która pisze kod, będzie oznaczało opóźnienie, spotkania, refaktoryzację itp.
źródło
Główny problem, który widzę tutaj, na poziomie jednostki, kiedy piszę kod, chcę go skompilować, uruchomić i natychmiast usunąć najbardziej oczywiste błędy - nawet jeśli kod jest niekompletny i wiem, że jednostka, funkcja lub funkcja to tylko częściowo wdrożony. A do uruchomienia kodu jednostki potrzebuję jakiegoś programu wywołującego implementację, zwykle test jednostkowy lub przynajmniej częściowy test jednostkowy. Niekoniecznie jest to „styl TDD według książki”, taki test można napisać przed lub przed testowanym kodem.
Gdy jedna wersja mojej jednostki jest „kompletna” i wolna od wszelkich błędów, które mogę znaleźć w ten sposób, wtedy sensowne jest przekazanie jej drugiej osobie i pozwolić jej / jej na napisanie dodatkowych testów jednostkowych lub przejrzenie mojego kodu . Ale dla mnie nie ma sensu przekazywać go, gdy tylko kompilator nie wyświetli ostrzeżeń, to zdecydowanie za wcześnie, na wypadek, gdybym wiedział, że muszę szczegółowo wyjaśnić testerowi rzeczy, które nie działają „jeszcze” lub działają inaczej za dwie godziny, odkąd wciąż pracuję nad tym fragmentem kodu. Niezbędny narzut komunikacyjny na tym poziomie szczegółowości nie przyniosłby IMHO korzyści.
Więc tak, mający drugi dev pisanie dodatkowych testów jednostkowych sens, ale nie do pisania testów jednostkowych wyłącznie .
źródło
Wydaje się, że może wystąpić jedna z następujących sytuacji - wszystkie są niepożądane:
Zamieszanie
Jak wskazał Ewan, CUT może wymagać zmiany, aby umożliwić testowanie. Powód zmiany nie zawsze jest oczywisty dla dewelopera (i może powodować nieporozumienia) i właśnie dlatego testy są pisane jako pierwsze.
Twierdzenie
Deweloper A mógł ukończyć swój kod i chcieć go przetestować. Deweloper B może również się rozwijać i dlatego może być niechętny, aby zaparkować swój kod, aby wziąć udział w testach jednostkowych.
Przełączanie kontekstu
Nawet jeśli programista B chce odłożyć programowanie na później, aby przetestować kod napisany przez programistę A - zmiana aktywności wiąże się z pewnymi kosztami.
Od dziesięcioleci przyjęto, że podwojenie siły człowieka nie skraca o połowę czasu rozwoju. Biorąc pod uwagę czynniki, które przedstawiłem powyżej, trudno jest zobaczyć, jak to ustawienie poprawiłoby sytuację.
źródło
W połączeniu z programowaniem par i TDD nazywa się to Wzorem Ping Pong :
Ale wydaje się, że proponujesz, aby oba programatory kodowały na różnych komputerach. Wykonanie tego osobno wymagałoby specyfikacji na bardzo niskim poziomie. Jest to sprzeczne z metodologiami zwinnymi. Każda zmiana wymagałaby koordynacji. W TDD wykonujesz desing na niskim poziomie w locie i nie stanowi to problemu. Zakładam, że twoje podejście wymagałoby wcześniej zakodowania szkieletów.
W każdym razie: możesz się wiele nauczyć, testując nowe sposoby robienia rzeczy, nawet jeśli nie są w 100% wydajne. Możesz to przetestować i podzielić się swoimi doświadczeniami z życia
źródło
Spóźniam się na to przyjęcie, ale myślę, że mam coś do dodania.
Opisujesz Peer kontrolne .
Ach, dobre stare programowanie par .
To nie jest programowanie w parach.
To zdecydowanie testy rówieśnicze. Oto artykuł ACM na ten temat . Zrobiłem to. Pracowałem tam, gdzie była to formalna część procesu wzajemnej oceny . Jest to pomocne, ale z pewnością nie jest pierwszą linią testów, a na pewno nie jest to klasyczne programowanie w parach.
Inną nazwą tego jest Testowanie Whitebox . Chociaż ta definicja nie dotyczy samego tego, kto przeprowadza testy, a także faktu, że tester widzi wewnętrzne funkcjonowanie testowanej rzeczy, w przeciwieństwie do testowania w Czarnej skrzynce, gdzie widzą tylko to, co wchodzi i co wychodzi Czarna skrzynka jest zwykle tym, co robi QA.
Pierwsza linia testów spoczywa mocno w rękach programisty. Jeśli nie, to prosisz mnie, abym nie testował mojego kodu, czego zdecydowanie odmawiam. Testuję swój kod, odkąd skończyłem 10 lat. Mogłem wtedy nie testować fantazyjnych testów jednostkowych, ale mój kod został przetestowany. Był testowany przy każdym uruchomieniu.
Od peer-testera oczekuję testów, które dodają się do moich testów. Testy, które w znacznym stopniu wyjaśniają problemy, które peer znalazł przy kodzie podczas jego przeglądu. Wyrażenie tych problemów za pomocą automatycznego testu ułatwia zrozumienie ich znaczenia. Rzeczywiście, przeprowadziłem techniczne rozmowy z rówieśnikami, którzy po prostu nie mogli zrozumieć, o co mi chodzi, a potem zrozumiałem, że najlepszym sposobem na pokazanie im, że jest problem, jest napisanie testu jednostkowego. To jest Peer Testing.
Teraz, jeśli chcesz dać mi testy napisane przed napisaniem mojego kodu w porządku. Nie ma to jak dokument wymagań, który jest tak formalny, że się kompiluje.
źródło
Od kilku lat wykonuję DDT (testy rozwojowe, czyli testy po kodzie), programowanie par i TDD z czerwono-zielonym refaktorem. Aby odpowiedzieć na twoje twierdzenia punkt po punkcie:
Osoba pisząca testy musi znać implementację tak dokładnie, jak to możliwe, aby pisać testy z dobrym zasięgiem bez nadmiernego testowania. Klasycznym przykładem tego jest testowanie z trzema wejściami, kiedy dwa potwierdzą to, co próbujesz przetestować. Mimo że potrafią na powierzchni zapoznać się z kodem po jego odczytaniu, nie będą w stanie zrozumieć dokładnie, przez co przeszedł pierwotny programista, aby przejść do obecnego stanu. Będą więc mieli mniej niż optymalne zrozumienie kodu.
Nie rozumiem, dlaczego tak mówisz. Podczas gdy ktoś pisze testy, nie pracuje nad nowymi funkcjami. Nie można magicznie podwoić czyjejś zdolności do pracy, dając jej dwa różne rodzaje pracy. Z mojego doświadczenia wynika, że pisanie testów jest generalnie trudniejsze niż pisanie kodu produkcyjnego, więc zdecydowanie nie można produktywnie i odpowiedzialnie pracować nad testami jakiegoś kodu podczas pisania innej funkcji.
Po pierwsze, testy są kodem. Dla kodu testu biznesowego jest prawie tak samo ważny jak kod produkcyjny, ponieważ umożliwia firmie zmianę oprogramowania bez obaw. Po drugie, nie różni się niczym od jednej osoby piszącej testy i kod produkcyjny, a nawet pary piszącej obie.
Nie, jest testowany tylko przez osobę, która pisze test. O ile nie chcesz poświęcić więcej czasu na testowanie, w takim przypadku po co zatrzymywać się na drugiej?
Programiści (nawet starsi) mają bardzo różne pomysły, co stanowi „dobry” kod. Wycinanie narożników przez jedną osobę jest jak najbardziej poprawnym sposobem na jak najszybszy dostęp do działającego kodu. To przepis na winę i na grę w system.
Refaktor TDD czerwono-zielony (w rzeczywistości pisząc pojedynczy test przed napisaniem kodu produkcyjnego, uruchamiając go, widząc, że się nie udaje, modyfikując tylko kod produkcyjny , ponownie uruchamiając test, widząc, że się powiódł, a następnie refaktoryzując, nie pomijając ani nie zamieniając żadnego z te kroki) i sprawdzanie kodu działa.
źródło
Le'ts przebiegają przez nie jeden po drugim.
Masz na myśli, że pierwszy programista poświęcił czas na napisanie implementacji, co do której nie jest pewien, czy działa. Potem przychodzi inny programista i pisze testy, opierając swoje rozumowanie na kodzie, nikt nie wie, czy jest poprawny, i ma nadzieję, że przyniesie on taktyczną przewagę w porównaniu do pisania testów tylko w odniesieniu do tego, co powinien zrobić kod. Jeśli implementacja jest niepoprawna, moim zdaniem przyniesie zerową pomoc w pisaniu testów.
Po zakończeniu początkowego rozwoju przez obu programistów nikt nie wie, czy którykolwiek z ich kodów jest poprawny. To wciąż pozostaje do sprawdzenia, nikt nie może odznaczać nikogo, jak to zrobione, i nikt nie może przewidzieć, kiedy będzie to zrobione. Porównaj to z TDD: najpierw piszesz test, potem test kończy się niepowodzeniem, a następnie przekazujesz z kodem. To kod obsługujący coraz więcej scenariuszy. To ruch do przodu.
Jeśli sprawisz, że będą postępować równolegle, kod, który może być ponownie wykorzystany w obu funkcjach, zostanie napisany dwukrotnie i będzie kosztował dwa razy więcej.
Sprawdź własność kodu zbiorowego, zgodnie z propozycją XP. Będziesz mieć jeszcze więcej osób odpowiedzialnych za kod. Jeśli Twoim celem jest dzielenie się wiedzą między programistami, dlaczego próbujesz je segregować?
Również z parą TDD. Podczas parowania obie osoby muszą uzgodnić, że napisany kod jest odpowiedni lub go nie napisać. Jeśli to doprowadzi do walki, niektórzy ludzie w zespole mają problem z niewłaściwym rozmieszczeniem ego.
Poszukiwanie błędów oznacza, że w pewnym momencie tolerowałeś ich dostanie się. Jeśli dostali się, byli niezauważeni. Odmowa najpierw napisania testu daje licencję na błędy, aby się dostać.
Cięcie narożnika może być niezamierzone. Do tego służy programowanie parowe. Każdemu członkowi pary należy pouczyć, aby obowiązek nie pozwalał drugiemu skracać narożników, bo cóż, wszyscy to robimy. Wymaga to pozostawienia dumy w szafie i zabrania jej z powrotem po wyjściu z biura. Jeśli spodziewasz się, że twoi ludzie będą niezachwianie rygorystyczni, nie bierzesz pod uwagę zwykłej sytuacji i nie przygotowuje się na porażkę.
XP mówi wprost, że wszystkie praktyki XP są wykonywane w celu wzajemnego wzmacniania się poprzez wzajemne usuwanie wad. Nie powinieneś słuchać krytyki jakiejkolwiek praktyki XP oddzielonej od innych. Żadna praktyka nie jest idealna, TDD nie jest doskonała, programowanie w parach nie jest idealne, własność wspólnego kodu nie jest doskonała, ale wszystkie one pokrywają się nawzajem.
źródło