TDD a testy jednostkowe [zamknięte]

117

Moja firma jest całkiem nowa w testowaniu jednostkowym naszego kodu. Od jakiegoś czasu czytam o TDD i testach jednostkowych i jestem przekonany o ich wartości. Próbowałem przekonać nasz zespół, że TDD jest warte wysiłku uczenia się i zmiany naszego nastawienia do tego, jak programujemy, ale jest to walka. Co prowadzi mnie do moich pytań.

W społeczności TDD jest wielu, którzy są bardzo religijni w kwestii pisania testu, a następnie kodu (i jestem z nimi), ale czy kompromis nadal przynosi dodatkowe korzyści dla zespołu, który boryka się z TDD?

Prawdopodobnie uda mi się przekonać zespół do napisania testów jednostkowych po napisaniu kodu (być może jako wymaganie do sprawdzenia kodu) i moim założeniem jest, że pisanie tych testów jednostkowych nadal ma wartość.

Jaki jest najlepszy sposób na wprowadzenie zmagającej się drużyny do TDD? A jeśli to się nie powiedzie, nadal warto pisać testy jednostkowe, nawet jeśli jest to po napisaniu kodu?

EDYTOWAĆ

Odszedłem od tego, że ważne jest, abyśmy rozpoczęli testy jednostkowe gdzieś w procesie kodowania. Ci w zespole, którzy podchwycą tę koncepcję, zaczną bardziej zbliżać się do TDD i najpierw testować. Dzięki za wkład wszystkich.

ZAGRYŹĆ

Niedawno rozpoczęliśmy nowy mały projekt i niewielka część zespołu używała TDD, reszta pisała testy jednostkowe po kodzie. Po zakończeniu części projektu związanej z kodowaniem osoby piszące testy jednostkowe po kodzie były zaskoczone, widząc, że kodery TDD są już wykonane i mają bardziej solidny kod. To był dobry sposób na przekonanie sceptyków. Wciąż mamy przed sobą wiele problemów wzrostu, ale wydaje się, że bitwa woli dobiegła końca. Dziękuję wszystkim, którzy udzielili rady!

Walter
źródło
1
Ten wątek może okazać się pomocny: stackoverflow.com/questions/917334/should-i-use-tdd
Randolpho,
29
+1 za KONTROLĘ. To świetna historia.
Carl Manaster

Odpowiedzi:

76

Jeśli zespół nie radzi sobie z wdrażaniem TDD, ale wcześniej nie tworzył żadnych testów jednostkowych ... zacznij od utworzenia testów jednostkowych po napisaniu kodu. Nawet testy jednostkowe napisane po kodzie są lepsze niż brak testów jednostkowych!

Gdy będą biegli w testowaniu jednostkowym (i we wszystkim, co się z tym wiąże), możesz popracować nad tym, aby najpierw utworzyli testy ... a dopiero potem kod.

Justin Niessner
źródło
3
Zgadza się, zespół nie tworzył wcześniej żadnych testów jednostkowych. To miła odskocznia do pełnego TDD.
Walter
Nie mogę się z tym bardziej zgodzić. W rzeczywistości wydaje mi się, że kilka miesięcy temu napisałem coś podobnego na podobne pytanie. Gdzie to jest ... Ach! stackoverflow.com/questions/917334/should-i-use-tdd/…
Randolpho
27

Po napisaniu kodu absolutnie nadal warto pisać testy jednostkowe. Po prostu czasami jest to trudniejsze, ponieważ Twój kod nie został zaprojektowany do testowania i być może zbytnio go skomplikowałeś.

Myślę, że dobrym pragmatycznym sposobem wprowadzenia zespołu do TDD jest zapewnienie alternatywnej metody „testowania w trakcie rozwoju” w okresie przejściowym lub ewentualnie w perspektywie długoterminowej. Należy ich zachęcać do sekcji kodu TDD, które wydają się im naturalne. Jednak w sekcjach kodu, które wydają się trudne do wykonania w pierwszej kolejności testowej lub podczas korzystania z obiektów, które są z góry określone przez nie-zwinny proces A&D, programiści mogą mieć możliwość napisania małej sekcji kodu, a następnie napisania testów, aby to pokryć kod i powtórzenie tego procesu. Pisanie testów jednostkowych dla jakiegoś kodu natychmiast po napisaniu tego kodu jest lepsze niż nie pisać żadnych testów jednostkowych w ogóle.

Kaleb Brasee
źródło
16

Moim skromnym zdaniem lepiej jest mieć 50% pokrycia testami z "kodem najpierw, test po" i 100% ukończoną biblioteką, niż 100% pokryciem testami i 50% ukończoną biblioteką z TDD. Miejmy nadzieję, że po chwili inni programiści uznają za zabawne i edukacyjne pisanie testów dla całego napisanego przez nich publickodu, więc TDD wkradnie się do ich rutyny programistycznej.

Asbjørn Ulsberg
źródło
3
Rozumiem twój dryf, ale obawiam się „biblioteki ukończonej w 100%” z 50% pokryciem testami… tylko z mojego doświadczenia wynika, że ​​każdy fragment kodu, który nie jest objęty niektórymi testami, zawiera co najmniej jeden błąd. Innymi słowy: ludzie unikają pisania testów kodu, który naprawdę skorzystałby na kolejnym testowaniu :)
Aaron Digulla
2
Cóż, innym sposobem ujęcia tego jest błędny kod, który został wydany, jest lepszy niż doskonały kod, który marnieje na zawsze. Oczywiście istnieją wyjątki kaszel NASA kaszel , ale w przeważającej części, dostać kod tam. Po wydaniu nadal możesz dodawać testy.
jcdyer
3
Co rozumiesz przez „bibliotekę ukończoną w 100%”? Czy uważasz, że jest to kompletne, jeśli jest buggy? Czy nie włączasz testowane do definicji ukończenia?
Pascal Thivent
10
bycie testowanym nie jest wystarczającym warunkiem, aby być wolnym od błędów
fa.
2
Pokrycie testów mierzone za pomocą narzędzi pokrycia testów jest mieczem obosiecznym. Jeśli zostanie to osiągnięte poprzez wywołanie wszystkich metod w IUT, ale testy tak naprawdę nie testują zachowania, które może się zepsuć, programiści i inni interesariusze będą mieli fałszywe poczucie bezpieczeństwa. Cały ruch w kierunku TDD w Twojej organizacji może wybuchnąć ci prosto w twarz, gdy krytyczne zachowanie nie zostanie przetestowane, ale masz 100% pokrycia testowego. Najważniejsza jest nie ilość, ale jakość.
Doug Knesek
12

Po prostu przeczytałem to w kalendarzu: „Każda reguła, wykonywana na najwyższym poziomie, staje się śmieszna lub nawet niebezpieczna”. Więc moja sugestia nie jest religijna. Każdy członek Twojego zespołu musi znaleźć równowagę między tym, co uważa za „właściwe” podczas testowania. W ten sposób każdy członek Twojego zespołu będzie najbardziej produktywny (zamiast, powiedzmy, pomyśleć „po co mam pisać ten sti **** test ??”).

Więc niektóre testy są lepsze niż żadne, testy po kodzie są lepsze niż kilka testów, a testowanie przed kodem jest lepsze niż po. Ale każdy krok ma swoje zalety i nie powinieneś krzywić się nawet na małe kroki.

Aaron Digulla
źródło
„co czują” Jako programista nie przypominam sobie, żebym kiedykolwiek miał (poprawną) chęć przeprowadzania jakichkolwiek automatycznych testów jednostkowych na podstawie własnych uczuć, tylko ręcznych. Nie sądzę, żebym był sam i brakowało mi emocji związanych z testowaniem
Gennady Vanin Геннадий Ванин
@ vgv8: To znaczy, że twoje testy ci nie pomagają. Może być wiele powodów, dla których tak jest; Proponuję kopać głębiej. Każdy projekt korzysta z dobrych testów i cierpi z powodu złych. Zauważysz, kiedy zaczniesz pisać dobre testy i od tego momentu nic nie będzie w stanie powstrzymać Cię przed dalszym pisaniem.
Aaron Digulla
co wydaje mi się właściwe, to poziom testowania, który obejmuje to, co powinny robić jednostki programistyczne, a od poziomu funkcjonalnego: to, co użytkownicy robią normalnie, w tym złe wyniki, które niektórzy nazywają „zgłoszonymi błędami”. Jeśli błąd zostanie potwierdzony, co najmniej jeden test zostanie napisany! im większy projekt i większy zespół, tym ważniejsze.
DaFi4
12

TDD to projekt! Jeśli więc go użyjesz, na pewno będziesz miał testowalny projekt swojego kodu, co ułatwi pisanie testów. Jeśli piszesz testy po napisaniu kodu, nadal są one cenne, ale IMHO będziesz tracić czas, ponieważ prawdopodobnie nie będziesz mieć testowalnego projektu.

Jedną z sugestii, które mogę ci dać, aby spróbować przekonać swój zespół do przyjęcia TDD, jest użycie niektórych technik opisanych w Nieustraszona zmiana: wzorce wprowadzania nowych idei, autorstwa Mary Lynn Manns i Lindy Rising .

Diego Dias
źródło
3
+1: Rozwój sterowany testami oznacza, że ​​projekt został oparty na testach.
S.Lott,
+1. Późniejsze testy jednostkowe oczywiście Ci pomogą, ale stracisz korzyści z posiadania „testowalnego projektu”, jeśli nie napiszesz testów jednostkowych z góry.
Noufal Ibrahim
9

Jeśli są nowicjuszami w testowaniu, IMO zacznij testować kod, który został już napisany, i powoli przechodź do pisania testów. Jako ktoś, kto próbuje nauczyć się TDD i nowy w testowaniu jednostkowym, stwierdziłem, że trudno jest wykonać pełne 180 i zmienić sposób myślenia, aby pisać testy przed kodem, więc podejście, które wybieram, jest czymś w rodzaju mieszanki 50-50 ; kiedy już wiem dokładnie, jak będzie wyglądał kod, napiszę kod, a następnie napiszę test, aby go zweryfikować. W sytuacjach, w których nie jestem do końca pewien, zacznę od testu i cofnę się.

Pamiętaj też, że nie ma nic złego w pisaniu testów weryfikujących kod, zamiast pisać kod spełniający wymagania testów. Jeśli twój zespół nie chce iść trasą TDD, nie narzucaj im tego.

Wayne Molina
źródło
6

Prawdopodobnie uda mi się przekonać zespół do napisania testów jednostkowych po napisaniu kodu (być może jako wymaganie do sprawdzenia kodu) i moim założeniem jest, że pisanie tych testów jednostkowych nadal ma wartość.

Nie ma absolutnie żadnych wątpliwości co do tego, że w kodzie testowanym jednostkowo jest wartość (niezależnie od tego, kiedy testy zostały napisane), a ja umieszczam „kod jest testowany jednostkowo” w „Definicji ukończenia”. Ludzie mogą używać TDD lub nie, o ile testują.

Jeśli chodzi o kontrolę wersji, lubię używać „ gałęzi programistycznych ” z polityką testowaną jednostkowo (tj. Kod kompiluje się i buduje, wszystkie testy jednostkowe przechodzą). Po zakończeniu funkcji są one publikowane z gałęzi programistycznych do pnia. Innymi słowy, gałąź trunk to „ gałąź gotowa ” (bez śmieci w magistrali!) I ma politykę możliwą do wysłania (można ją opublikować w dowolnym momencie), która jest bardziej rygorystyczna i obejmuje więcej elementów niż „test jednostkowy”.

Pascal Thivent
źródło
4

To jest coś, w czym Twój zespół będzie musiał odnieść własne sukcesy, zanim zacznie w to wierzyć. Będę narzekać na moje objawienie nUnit dla każdego, kogo to obchodzi:

Około 5 lat temu odkryłem nUnit podczas pracy nad projektem. Prawie skończyliśmy V1.0 i stworzyłem kilka testów, aby wypróbować to nowe narzędzie. Mieliśmy dużo błędów (oczywiście!), Ponieważ byliśmy nowym zespołem, mieliśmy napięty termin, wysokie oczekiwania (brzmi znajomo?) Itp. W każdym razie dostaliśmy 1.0 i zaczęliśmy 1.1. Zmieniliśmy trochę zespół i przydzielono mi 2 deweloperów. Zrobiłem dla nich godzinne demo i powiedziałem im, że wszystko, co napisaliśmy, musi mieć z tym przypadek testowy. Ciągle pozostawaliśmy „za” resztą zespołu podczas cyklu deweloperskiego 1.1, ponieważ pisaliśmy więcej kodu, testy jednostkowe. Skończyło się na tym, że pracowaliśmy więcej, ale oto korzyści - kiedy w końcu zabraliśmy się do testów, mieliśmy dokładnie 0 błędów w naszym kodzie. Pomogliśmy wszystkim innym debugować i naprawiać ich błędy. W sekcji zwłok, gdy pojawiły się błędy,

Nie jestem na tyle głupi, by myśleć, że możesz sprawdzić swoją drogę do sukcesu, ale jestem prawdziwym zwolennikiem testów jednostkowych. Projekt przyjął nUnit i szybko rozprzestrzenił się na firmę dla wszystkich projektów .Net w wyniku 1 sukcesu. Całkowity czas dla naszego wydania V1.1 wynosił 9 tygodni deweloperskich, więc zdecydowanie NIE był to sukces z dnia na dzień. Jednak w dłuższej perspektywie okazało się to sukcesem dla naszego projektu i firmy, dla której budowaliśmy rozwiązania.

Brak zwrotów Brak zwrotów
źródło
„Projekt przyjął nUnit i szybko rozprzestrzenił się na firmę we wszystkich projektach .Net” A co zrobić, jeśli jeden produkt / projekt zawiera kod C #, Java, C ++, SQL Server?
Gennady Vanin Геннадий Ванин
Nie wiem ... Znaleźć sposób na przetestowanie wszystkich komponentów przed wdrożeniem do produkcji? Testowanie jednostkowe to tylko jeden z aspektów kompleksowego planu testów przed jego uruchomieniem. Możesz dziurawić dziury w dowolnym scenariuszu.
Brak zwrotów Brak zwrotów
4

Nie ma wątpliwości, że testowanie (First, While lub nawet After) uratuje Twój boczek i poprawi Twoją produktywność i pewność siebie. Polecam to zaadoptować!

Byłem w podobnej sytuacji, ponieważ byłem programistą "noob", często byłem sfrustrowany podczas pracy nad projektem zespołowym, ponieważ wkład zepsuł kompilację. Nie wiedziałem, czy jestem winny, a nawet w niektórych przypadkach, kogo winić. Ale bardziej martwiłem się, że robię to samo z innymi programistami. Ta świadomość zmotywowała następnie do przyjęcia pewnych strategii TDD. Nasz zespół zaczął mieć głupie gry i zasady, na przykład nie możesz wracać do domu, dopóki wszystkie testy nie przejdą, lub jeśli prześlesz coś bez testu, musisz kupić wszystkim „piwo / lunch / itp.” I sprawiło, że TDD było fajniejsze.

Dai Bok
źródło
3

Jednym z najbardziej użytecznych aspektów testów jednostkowych jest zapewnienie ciągłej poprawności już działającego kodu. Kiedy możesz dowolnie refaktoryzować, pozwól IDE przypomnieć Ci o błędach czasu kompilacji, a następnie kliknij przycisk, aby umożliwić testom wykrycie potencjalnych błędów w czasie wykonywania - czasami pojawiają się w wcześniej trywialnych blokach kodu, wtedy myślę, że znajdziesz swój zespół zaczynając doceniać TDD. Dlatego rozpoczęcie od testowania istniejącego kodu jest zdecydowanie przydatne.

Mówiąc szczerze, dowiedziałem się więcej o tym, jak pisać testowalny kod, próbując przetestować napisany kod niż zaczynając od TDD. Na początku może to być zbyt abstrakcyjne, jeśli myślisz o umowach, które zarówno osiągną cel końcowy, jak i pozwolą na testowanie. Ale kiedy patrzysz na kod i możesz powiedzieć „Ten singleton tutaj całkowicie psuje wstrzykiwanie zależności i uniemożliwia testowanie tego”, zaczynasz doceniać, jakie wzorce ułatwiają testowanie.

David Berger
źródło
3

Cóż, jeśli najpierw nie napiszesz testów, to nie jest to „Test Driven”, tylko testowanie. Ma to zalety samo w sobie i jeśli masz już bazę kodu, dodanie testów jest z pewnością przydatne, nawet jeśli nie jest to TDD, a jedynie testowanie.

Pisanie testów w pierwszej kolejności polega na skupieniu się na tym, co powinien zrobić kod przed jego napisaniem. Tak, otrzymujesz również test, który to robi i jest dobry, ale niektórzy mogą twierdzić, że nie jest to nawet najważniejszy punkt.

To co bym zrobił, to przeszkolić zespół przy projektach zabawek takich jak te (patrz Coding Dojo, Katas) z wykorzystaniem TDD (gdyby można było pozyskać doświadczonych programistów TDD do udziału w takich warsztatach, byłoby jeszcze lepiej). Kiedy zobaczą korzyści, użyją TDD w prawdziwym projekcie. Ale tymczasem nie zmuszaj ich, jeśli nie widzą korzyści, nie zrobią tego dobrze.

kriss
źródło
3

Jeśli masz sesje projektowe przed napisaniem kodu lub musisz utworzyć dokument projektowy, możesz dodać testy jednostkowe jako namacalny wynik sesji.

Może to następnie służyć jako specyfikacja tego, jak powinien działać Twój kod. Zachęcaj do parowania podczas sesji projektowej, aby ludzie rozmawiali o tym, jak coś powinno działać i co powinno robić w danych scenariuszach. Jakie są przypadki skrajne, z jawnymi przypadkami testowymi dla nich, aby każdy wiedział, co zrobi, jeśli na przykład otrzyma zerowy argument.

Na marginesie, ale BDD również może być interesujące

danswain
źródło
Nie wiedziałem o BDD. Muszę o tym przeczytać więcej.
Walter
3

Możesz znaleźć trochę trakcji, pokazując przykład lub dwa, w których TDD powoduje napisanie mniejszej ilości kodu - ponieważ piszesz tylko kod wymagany do pomyślnego przejścia testu, łatwiej jest oprzeć się pokusie złocenia lub zaangażowania się w YAGNI. Kod, którego nie piszesz, nie musi być konserwowany, refaktoryzowany itp., Więc to „prawdziwe oszczędności”, które mogą pomóc w sprzedaży koncepcji TDD.

Jeśli potrafisz jasno wykazać wartość pod względem czasu, kosztów, kodu i zapisanych błędów, może się okazać, że łatwiej jest sprzedać.

Michael Nash
źródło
2

Rozpoczęcie budowy klas testowych JUnit jest sposobem na rozpoczęcie, dla istniejącego kodu jest to jedyny sposób na rozpoczęcie. Z mojego doświadczenia wynika, że ​​tworzenie klas testowych dla istniejącego kodu jest bardzo przydatne. Jeśli kierownictwo uważa, że ​​zajmie to zbyt dużo czasu, możesz zaproponować pisanie klas testowych tylko wtedy, gdy okaże się, że odpowiednia klasa zawiera błąd lub wymaga czyszczenia.

W przypadku procesu konserwacji podejściem do przeniesienia zespołu przez linię byłoby napisanie testów JUnit w celu odtworzenia błędów przed ich naprawieniem, tj.

  • zgłoszony błąd
  • w razie potrzeby utwórz klasę testową JUnit
  • dodaj test, który odtwarza błąd
  • napraw kod
  • uruchom test, aby pokazać, że bieżący kod nie odtwarza błędu

Możesz wyjaśnić, że „dokumentowanie” błędów w ten sposób zapobiegnie ich powracaniu później. To korzyść, którą zespół może od razu odczuć.

rsp
źródło
2

Zrobiłem to w wielu organizacjach i znalazłem najlepszy sposób na rozpoczęcie i śledzenie TDD, to skonfigurowanie programowania w parach. Jeśli masz kogoś innego, na kogo możesz liczyć, znającego TDD, wtedy oboje możecie się rozdzielić i sparować z innymi programistami, aby faktycznie wykonać programowanie w parach przy użyciu TDD. Jeśli nie, wyszkoliłbym kogoś, kto pomoże ci to zrobić, zanim przedstawię to reszcie zespołu.

Jedną z głównych przeszkód związanych z testowaniem jednostkowym, a zwłaszcza TDD, jest to, że programiści nie wiedzą, jak to zrobić, więc nie widzą, jak to może być warte ich czasu. Również na początku jest znacznie wolniejszy i nie wydaje się przynosić korzyści. Zapewnia ci korzyści tylko wtedy, gdy jesteś w tym dobry. Konfigurując sparowane sesje programowania, możesz szybko skłonić programistów do szybkiego nauczenia się tego i szybszego osiągnięcia dobrych wyników. Dodatkowo będą mogli zobaczyć natychmiastowe korzyści z tego, gdy będziecie nad tym wspólnie pracować.

W przeszłości to podejście działało dla mnie wiele razy.

John Sonmez
źródło
2

Jednym z potężnych sposobów odkrywania zalet TDD jest znaczące przepisanie niektórych istniejących funkcji, być może ze względu na wydajność. Tworząc zestaw testów, które wykonują dobrą robotę, obejmując wszystkie funkcje istniejącego kodu, daje to pewność, że refaktoryzujesz się do treści z pełnym przekonaniem, że zmiany są bezpieczne.

Zauważ, że w tym przypadku mówię o testowaniu projektu lub kontraktu - testy jednostkowe, których szczegóły implementacji testów nie będą tutaj odpowiednie. Ale z drugiej strony TDD nie może testować implementacji z definicji, ponieważ mają być napisane przed implementacją.

Chris Welsh
źródło
1

TDD to narzędzie, którego programiści mogą używać do tworzenia lepszego kodu. Wydaje mi się, że pisanie testowalnego kodu jest równie wartościowe, jak same testy. Izolowanie IUT (Implementation Under Test) do celów testowych ma uboczny wpływ na oddzielenie kodu.

TDD nie jest dla wszystkich i nie ma magii, która zmusi zespół do podjęcia takiego wyboru. Istnieje ryzyko, że autorzy testów jednostkowych, którzy nie wiedzą, co warto testować, napiszą wiele testów o niskiej wartości, które będą paszą armatnią dla sceptyków TDD w Twojej organizacji.

Zwykle robię automatyczne testy akceptacji jako niepodlegające negocjacjom, ale pozwalam programistom na dostosowanie TDD do swoich potrzeb. Moi doświadczeni TDD szkolą / mentorują resztę i „udowadniają” swoją przydatność na przykładzie przez wiele miesięcy.

Jest to zarówno zmiana społeczna / kulturowa, jak i techniczna.

Doug Knesek
źródło