Wady rozwoju opartego na testach? [Zamknięte]


192

Co stracę, przyjmując projektowanie testowe?

Wymień tylko negatywy; nie wymieniaj świadczeń napisanych w formie negatywnej.


Dodałem odpowiedź stwierdzającą, że BDD może złagodzić niektóre z tych negatywów. Wzywam cię, abyś wziął pod uwagę ten czynnik przy zbieraniu negatywnych danych wejściowych, ponieważ niektóre z nich można wyeliminować i przestać być uważane za negatywne.
Kilhoffer,

25
Dla wyjaśnienia, nie jestem przeciw ani za. Staram się podjąć świadomą decyzję w tej sprawie, ale większość osób, które opowiadają się za TDD, nie rozumie lub nie przyzna negatywów.
IanL

1
W tytule wspomniano o „Test Driven Development”, ale w treści pytania wspomniano o „Test Driven Design”. Które z nich dotyczy tego pytania? Istnieją ważne, ale subtelne różnice między nimi. Projekt sterowany testem polega na umożliwieniu testom napędzania projektu oprogramowania. Rozwój oparty na testach jest zwykle związany z pisaniem testów przed kodem produkcyjnym (ale niekoniecznie pozwala testom wpływać na projekt).
Jim Hurne,

3
TDD to klatka, która zatrzymuje kreatywność programistów.
Lewis,

13
proszę przestańcie zamykać ważne pytania, djesus
Casper Leon Nielsen

Odpowiedzi:


129

Kilka wad (i nie twierdzę, że nie ma żadnych korzyści - szczególnie przy pisaniu podstaw projektu - na koniec zaoszczędziłoby to dużo czasu):

  • Wielka inwestycja. W prostym przypadku tracisz około 20% faktycznej implementacji, ale w skomplikowanych przypadkach tracisz znacznie więcej.
  • Dodatkowa złożoność. W przypadku skomplikowanych przypadków twoje przypadki testowe są trudniejsze do obliczenia, sugeruję w takich przypadkach, aby spróbować użyć automatycznego kodu referencyjnego, który będzie działał równolegle w wersji debugowania / przebiegu testowym, zamiast testu jednostkowego najprostszych przypadków.
  • Wpływ na projekt. Czasami projekt nie jest przejrzysty na początku i ewoluuje wraz z upływem czasu - to zmusi cię do ponownego wykonania testu, co wygeneruje dużą stratę czasu. Sugerowałbym odroczenie testów jednostkowych w tym przypadku, dopóki nie zrozumiesz trochę projektu.
  • Ciągłe poprawianie. W przypadku struktur danych i algorytmów czarnej skrzynki testy jednostkowe byłyby idealne, ale w przypadku algorytmów, które zwykle się zmieniają, dostosowują lub dostosowują, może to powodować dużą inwestycję, o której można by sądzić, że nie jest uzasadniona. Dlatego używaj go, gdy uważasz, że rzeczywiście pasuje do systemu i nie zmuszaj projektu do dopasowania do TDD.

7
Głównym punktem (4) jest - każdy system, który nie jest dobrze zdefiniowany i prawdopodobnie będzie się zmieniać, aby dopasować się do ewoluujących zachowań wizualnych, różnych specyfikacji AI, algorytmów behawioralnych itp. Spowoduje duże inwestycje w powtarzane definicje testów, ponieważ utrzymujemy po zmianie pożądanych wyników testu.
Adi

12
To prawda, ale czy nie byłoby tak samo bez TDD? Bez tego musiałbyś wykonać więcej testów ręcznych, co spotkałoby ten sam problem.
sleske

50
Czy „wielka inwestycja” nie pozwoli Ci zaoszczędzić czasu podczas opracowywania rozwiązania? Zwłaszcza ze złożonym? Myślę, że powinno to zaoszczędzić czas. Nie wspominając o fazie konserwacji, w której niewielkie zmiany mogą z łatwością zepsuć system. ( a może po prostu jestem naiwny co do testów jednostkowych + regresji zapobiegających przyszłym błędom )
Robert Koritnik,

6
Sergio / Robert, jestem zdecydowanie za przeprowadzeniem testów jednostkowych dla systemów ogólnych i zdecydowanie dla komponentów, które stanowią podstawę systemu. Powiedziawszy to, dodam, że należy rozróżnić te przypadki i uprościć rzeczywiste życie, próbując twierdzić, że każdy system można traktować w ten sposób. Nie wszystkie systemy można uogólnić i uprościć do testowania jednostkowego, a jeśli spróbujesz wymusić charakter testów jednostkowych na takich systemach, możesz łatwo poświęcić znacznie więcej czasu na poprawianie testów jednostkowych niż na testowanie rzeczywistych wyników.
Adi

3
@Adi: Myślę, że się mylisz. Moim zdaniem każdy system można przetestować w ten sposób, to tylko kwestia samodyscypliny.
BlueLettuce16

189

Jeśli chcesz wykonać „rzeczywistą” TDD (czytaj: najpierw przetestuj za pomocą czerwonych, zielonych, refaktoryzujących kroków), musisz także zacząć używać makiet / kodów pośredniczących, gdy chcesz przetestować punkty integracji.

Kiedy zaczniesz używać prób, po chwili będziesz chciał zacząć używać Dependency Injection (DI) i kontenera Inversion of Control (IoC). Aby to zrobić, musisz używać interfejsów do wszystkiego (które same mają wiele pułapek).

Pod koniec dnia musisz napisać o wiele więcej kodu, niż gdybyś zrobił to po prostu „po prostu starą drogą”. Zamiast tylko klasy klienta, musisz także napisać interfejs, próbną klasę, trochę konfiguracji IoC i kilka testów.

I pamiętaj, że kod testowy powinien być również utrzymywany i pielęgnowany. Testy powinny być tak czytelne jak wszystko inne i napisanie dobrego kodu zajmuje dużo czasu.

Wielu programistów nie do końca rozumie, jak zrobić to wszystko „we właściwy sposób”. Ale ponieważ wszyscy mówią im, że TDD jest jedynym prawdziwym sposobem na tworzenie oprogramowania, po prostu starają się jak mogą.

Jest to o wiele trudniejsze niż mogłoby się wydawać. Często projekty wykonane przy użyciu TDD kończą się kodem, którego nikt tak naprawdę nie rozumie. Testy jednostkowe często sprawdzają niewłaściwy sposób. I nikt nie zgadza się, jak powinien wyglądać dobry test, nawet tak zwani guru.

Wszystkie te testy znacznie utrudniają „zmianę” (w przeciwieństwie do refaktoryzacji) zachowania systemu, a proste zmiany stają się zbyt trudne i czasochłonne.

Jeśli czytasz literaturę TDD, zawsze znajdziesz kilka bardzo dobrych przykładów, ale często w rzeczywistych aplikacjach musisz mieć interfejs użytkownika i bazę danych. Tutaj TDD staje się naprawdę trudne, a większość źródeł nie oferuje dobrych odpowiedzi. A jeśli tak, zawsze wymaga to więcej abstrakcji: próbnych obiektów, programowania interfejsu, wzorców MVC / MVP itp., Które znów wymagają dużej wiedzy i ... musisz napisać jeszcze więcej kodu.

Więc bądź ostrożny ... jeśli nie masz entuzjastycznego zespołu i przynajmniej jednego doświadczonego programisty, który umie pisać dobre testy, a także wie kilka rzeczy o dobrej architekturze, naprawdę musisz pomyśleć dwa razy, zanim zejdziesz drogą TDD .


7
Korzystając z narzędzi takich jak Pex & Moles , możesz dość łatwo uniknąć pisania interfejsów dla każdej małej, cholernej rzeczy. Mole bardzo Ci w tym pomogą.
Robert Koritnik

24
Wygląda na to krytykę testów jednostkowych i programowania obiektowego, a nie TDD.
plmaheu

5
Właściwie poprawne ** testowanie jednostkowe ** - nie tylko TDD - wymaga próbnych / odcinków. A programowanie w oparciu o interfejs jest często dobrym pomysłem, to samo dotyczy wzorców. Jeśli połączysz interfejs użytkownika z logiką, będziesz miał zły czas. Jeśli musisz przetestować interakcję z DB, nadal możesz wyśmiewać DAO z testów jednostkowych i użyć prawdziwej rzeczy do testu integracji.
TheMorph

1
Zgadzam się z faktem, że jedna mgła ma wiedzę na temat projektowania i testowania przed przejściem do TDD. Ma to kluczowe znaczenie w projektach z nowym zatrudnieniem, ponieważ są one nowe w obu.
Hitesh Sahu

głosuj na Mądrość
sabsab

66

Gdy dojdziesz do miejsca, w którym masz dużą liczbę testów, zmiana systemu może wymagać ponownego napisania niektórych lub wszystkich testów, w zależności od tego, które zostały unieważnione przez zmiany. Może to zmienić stosunkowo szybką modyfikację w bardzo czasochłonną.

Ponadto możesz zacząć podejmować decyzje projektowe bardziej w oparciu o TDD niż w rzeczywistości dobrych projektantów. Chociaż mogłeś mieć bardzo proste i łatwe rozwiązanie, które nie jest w stanie przetestować wymagań TDD, masz teraz znacznie bardziej złożony system, który jest bardziej podatny na błędy.


3
Zdecydowanie może to stanowić problem, jednak widzę zauważalną różnicę w tym, jak bardzo na mnie to wpływa. Wszystko sprowadza się do „pisania testowalnego kodu”.
Rob Cooper

2
Scott, przykładem, który zwykle daję, jest SqlDataSource osadzony na stronie ASPX. Nie można zautomatyzować testu w tym celu. To proste i wykonuje zadanie, mając tylko 1 plik. Komponentem do testowania jest obiekt SqlDataSource firmy MSFT, i jest to już zrobione dla nas. Nie musimy robić więcej.
Eric Z Beard

8
+1 „możesz zacząć podejmować decyzje projektowe bardziej w oparciu o TDD niż w rzeczywistości dobrych projektantów” - największy pułapek TDD IMHO.
András Szepesházi 27.04.11

2
@ScottSaad problemem IMO jest to, że projekt powinien być najpierw zarysowany, a następnie sprawdzony przez napisanie testów i poprawiony w razie potrzeby. Widziałem wiele przypadków, w których ludzie narażali na szwank dobry projekt, aby móc napisać test. W rezultacie - większość systemu została poddana testom, ale konstrukcja była naprawdę brzydka. Myślę, że dzieje się tak dlatego TDD jest popychany do mas, jak bardzo prostego z następującą metodologią nieporozumieniem : if part of the system is covered by tests and they pass, then everything is fine (including design).
Yuriy Nakonechnyy

3
@Yura: Interesujące jest to, co mówisz, że ludzie narażali dobry projekt tylko po to, by móc pisać testy. Moim zdaniem, gdyby istniał dobry projekt, nie byłoby potrzeby narażania go na niebezpieczeństwo. Kiedyś widziałem taki projekt i podstawa kodu była koszmarem, ale ludzie myśleli tak samo - że projekt jest świetny. Zgadzam się tylko z tą częścią, że TDD jest przekazywany masom jako bardzo prosta metodologia, jednak jest dokładnie odwrotnie. Moim zdaniem, kiedy kod jest dobrze zaprojektowany, to po wprowadzeniu jednej małej zmiany nie ma szans na zahamowanie wszystkich testów lub ich dużej liczby.
BlueLettuce16

54

Myślę, że największym problemem jest dla mnie OGROMNA strata czasu potrzebna na „wejście w to”. Nadal jestem bardzo na początku mojej podróży z TDD (zobacz mój blog, aby uzyskać informacje o moich testowych przygodach, jeśli jesteś zainteresowany) i dosłownie spędziłem godziny na rozpoczęciu.

Przejście twojego mózgu w „tryb testowania” zajmuje dużo czasu, a pisanie „testowalnego kodu” jest umiejętnością samą w sobie.

TBH, z szacunkiem nie zgadzam się z komentarzami Jasona Cohena dotyczącymi upublicznienia prywatnych metod, nie o to chodzi. W moim nowym sposobie pracy nie uczyniłem więcej metod publicznych niż wcześniej . Wiąże się to jednak ze zmianami architektonicznymi i pozwala na „podłączenie” modułów kodu, aby wszystko inne było łatwiejsze do przetestowania. W tym celu nie powinieneś zwiększać dostępności wewnętrznych elementów kodu. W przeciwnym razie wracamy do punktu wyjścia, gdy wszystko jest publiczne, gdzie jest w tym enkapsulacja?

Tak więc (IMO) w skrócie:

  • Czas poświęcony na przemyślenie (tj. Testowanie grok'ingu ).
  • Nowa wiedza wymagała znajomości pisania kodu testowalnego.
  • Zrozumienie zmian architektonicznych wymaganych do przetestowania kodu.
  • Zwiększenie umiejętności „TDD-Coder” przy jednoczesnym ulepszaniu wszystkich innych umiejętności wymaganych dla naszego wspaniałego rzemiosła programistycznego :)
  • Zorganizowanie bazy kodu w celu włączenia kodu testowego bez wkręcania kodu produkcyjnego.

PS: Jeśli chcesz uzyskać linki do pozytywów, zadałem i odpowiedziałem na kilka pytań na ten temat, sprawdź mój profil .


1
Niestety pierwszą rozsądną odpowiedź, jaką zobaczyłem ...
Daniel C. Sobral

5
Dość praktyczna i prosta odpowiedź - +1 za część „Umysłowe ustawienie”
ha9u63ar

50

W ciągu kilku lat, w których ćwiczę Test Driven Development, muszę powiedzieć, że największe wady to:

Sprzedaż do zarządzania

TDD najlepiej wykonywać parami. Po pierwsze, trudno oprzeć się pokusie, aby po prostu napisać implementację, gdy WIESZ, jak napisać instrukcję if / else . Ale para sprawi, że wykonasz zadanie, ponieważ ty będziesz go wykonywać. Niestety wiele firm / menedżerów nie uważa, że ​​jest to dobre wykorzystanie zasobów. Po co płacić, aby dwie osoby napisały jedną funkcję, skoro mam dwie funkcje, które należy wykonać w tym samym czasie?

Sprzedawanie go innym programistom

Niektóre osoby po prostu nie mają cierpliwości do pisania testów jednostkowych. Niektórzy są bardzo dumni ze swojej pracy. Lub niektórzy po prostu widzą, jak zawiłe metody / funkcje spadają z końca ekranu. TDD nie jest dla wszystkich, ale naprawdę tego chciałbym. Ułatwiłoby to utrzymanie rzeczy tym biednym duszom, które odziedziczą kod.

Utrzymanie kodu testowego wraz z kodem produkcyjnym

Idealnie byłoby, gdyby testy zakończyły się niepowodzeniem tylko w przypadku podjęcia złej decyzji dotyczącej kodu. To znaczy, myślałeś, że system działał w jedną stronę i okazało się, że tak nie było. Przerwanie testu lub (małego) zestawu testów to właściwie dobra wiadomość. Wiesz dokładnie, jak twój nowy kod wpłynie na system. Jeśli jednak twoje testy są źle napisane, ściśle powiązane lub, co gorsza, wygenerowane ( test VS kaszel ), to utrzymanie testów może szybko stać się chórem. A gdy wystarczająca liczba testów zacznie powodować więcej pracy niż postrzegana wartość, którą tworzą, wówczas testy będą pierwszą rzeczą, która zostanie usunięta, gdy harmonogramy zostaną skompresowane (np. Dojdzie do awarii)

Pisanie testów, abyś obejmował wszystko (100% pokrycia kodu)

Idealnie, jeśli zastosujesz metodologię, twój kod zostanie domyślnie w 100% przetestowany. Zazwyczaj myślę, że kończę na pokryciu kodu w górę o 90%. Zwykle dzieje się tak, gdy mam architekturę stylu szablonu, a baza jest testowana, a ja próbuję wyciąć rogi, a nie przetestować dostosowania szablonu. Odkryłem również, że kiedy napotykam nową barierę, której wcześniej nie spotkałem, mam krzywą uczenia się podczas jej testowania. Przyznaję się do pisania niektórych wierszy kodu starym sposobem skool, ale naprawdę lubię mieć to w 100%. (Chyba skończyłem szkołę, er skool).

Powiedziałbym jednak, że korzyści wynikające z TDD znacznie przewyższają negatywy dla prostego pomysłu, że jeśli uda ci się uzyskać dobry zestaw testów obejmujących twoje zastosowanie, ale nie są tak delikatne, że jedna zmiana psuje je wszystkie, być w stanie dodawać nowe funkcje w dniu 300 projektu, tak jak w dniu 1. Nie dzieje się tak w przypadku wszystkich osób, które próbują TDD, uważając, że to magiczna kula dla całego ich błędnego kodu, więc myślą, że może to praca, kropka.

Osobiście przekonałem się, że dzięki TDD piszę prostszy kod, spędzam mniej czasu na debatowaniu, czy dane rozwiązanie kodu działa, czy nie, i nie boję się zmienić żadnej linii kodu, która nie spełnia kryteriów określonych przez drużyna.

TDD to trudna dyscyplina do opanowania, którą stosuję od kilku lat i wciąż uczę się nowych technik testowania. To z góry ogromna inwestycja czasowa, ale w dłuższej perspektywie trwałość będzie znacznie większa niż w przypadku braku automatycznych testów jednostkowych. Teraz, gdyby tylko moi szefowie potrafili to rozgryźć.


7
Jaka była reszta zdania kończąca się na „(kaszel VS Test), a potem główny”?
Andrew Grimm

+1 za problem ze sprzedażą. :) Jestem teraz w nowej firmie i zastanawiam się, jak stworzyć kulturę, która pozwoliłaby na swobodne rozprzestrzenianie się umiejętności.
Esko Luontola,

2
Uważam, że niektóre firmy konsultingowe korzystają z programowania w parach i TDD, aby uzyskać więcej pieniędzy od swoich klientów. To dość rozczarowujące, jak ci klienci płacą za pomysły, które na pierwszy rzut oka wydają się rozsądne, np. Dwie osoby myślą o wiele lepiej niż 2 lub że TDD zapewnia, że ​​każda linia kodu jest testowana, ale w końcu są tylko wymówką, aby klient zapłacił więcej za coś, co może zrobić tylko jedna osoba.
lmiguelvargasf

24

W twoim pierwszym projekcie TDD są dwie duże straty, czas i wolność osobista

Tracisz czas, ponieważ:

  • Stworzenie kompleksowego, przebudowanego, możliwego do utrzymania pakietu testów jednostkowych i akceptacyjnych znacznie wydłuża czas pierwszej iteracji projektu. Może to zaoszczędzić czas na dłuższą metę, ale równie dobrze może to być czas, którego nie musisz tracić.
  • Musisz wybrać i stać się ekspertem w zakresie podstawowego zestawu narzędzi. Narzędzie do testowania jednostkowego musi być uzupełnione jakimś szkieletem próbnym i oba muszą stać się częścią zautomatyzowanego systemu kompilacji. Chcesz również wybrać i wygenerować odpowiednie dane.

Tracisz wolność osobistą, ponieważ:

  • TDD to bardzo zdyscyplinowany sposób pisania kodu, który często ociera się o te na górze i na dole skali umiejętności. Zawsze pisząc kod produkcyjny w określony sposób i poddając swoją pracę ciągłemu recenzowaniu, możesz przerazić swoich najgorszych i najlepszych programistów, a nawet doprowadzić do utraty zatrudnienia.
  • Większość zwinnych metod osadzania TDD wymaga ciągłego rozmawiania z klientem na temat tego, co zamierzasz osiągnąć (w tej historii / dniu / czymkolwiek) i jakie są kompromisy. Po raz kolejny nie jest to filiżanka herbaty dla wszystkich, zarówno po stronie programistów ogrodzenia, jak i klientów.

Mam nadzieję że to pomoże


1
Nie wiem, czy to dlatego, że jestem najgorszy czy najlepszy ... ale TDD trąca mnie w niewłaściwy sposób. Jest tak, ponieważ zbyt wcześnie zmusza mnie do przejścia w tryb podwójnej konserwacji. Za każdym razem, gdy zmieniam projekt klasy, teraz muszę również zmieniać przypadki testowe. Oczekuję i akceptuję to od dojrzałej klasy, ale nie od klasy, którą właśnie napisałem w zeszłym tygodniu! Mogę również powiedzieć, że DI i TDD niedobrze obsługiwane przez języki takie jak Java i C #. Ktoś naprawdę musi stworzyć nowy język, aby koszt TDD i DI był dosłownie zerowy . W takim razie nie będziemy już rozmawiać.
John Henckel

14

TDD wymaga zaplanowania sposobu działania klas przed napisaniem kodu, który przejdzie te testy. Jest to zarówno plus, jak i minus.

Trudno mi pisać testy w „próżni” - przed napisaniem jakiegokolwiek kodu. Z mojego doświadczenia mam tendencję do potykania się o swoje testy, ilekroć nieuchronnie myślę o czymś podczas pisania moich zajęć, o których zapomniałem podczas pisania pierwszych testów. Potem nadszedł czas, aby nie tylko refaktoryzować moje zajęcia, ale także MOJE testy. Powtórz to trzy lub cztery razy i może to być frustrujące.

Wolę najpierw napisać szkic moich zajęć, a następnie napisać (i utrzymać) zestaw testów jednostkowych. Po otrzymaniu wersji roboczej TDD działa dla mnie dobrze. Na przykład, jeśli zgłoszony zostanie błąd, napiszę test, aby go wykorzystać, a następnie naprawię kod, aby test się powiódł.


1
Chociaż powinieneś mieć pojęcie o tym, jak będzie wyglądać architektura twojego systemu, nie musisz wiedzieć dużo wcześniej, robiąc TDD. TDD oznacza, że ​​testy NAPĘDZAJ projekt, więc zmieni się on w miarę wdrażania kolejnych scenariuszy testowych
casademora,

4
Zgadzam się z próżnią. Oryginalne samouczki TDD, w których napiszesz test bez ŻADNEGO kodu - i otrzymasz błąd kompilacji - są szalone.
mparaz

Błędne jest założenie, że możesz napisać testy raz i nie zmieniać ich. Są to kod i każdy kod wymaga ewentualnego refaktoryzacji po wprowadzeniu zmian. Testy nie są wyjątkiem. Testy refaktoryzacyjne są koniecznością, jeśli chcesz je utrzymać.
Roman Konoval,

12

Prototypowanie może być bardzo trudne z TDD - gdy nie jesteś pewien, jaką drogę zamierzasz rozwiązać, pisanie testów z góry może być trudne (inne niż bardzo szerokie). To może być ból.

Szczerze mówiąc, nie sądzę, aby w przypadku „podstawowego rozwoju” znacznej większości projektów istniały jakieś realne minusy; jest omawiany o wiele bardziej niż powinien, zwykle przez ludzi, którzy uważają, że ich kod jest wystarczająco dobry, aby nie potrzebowali testów (nigdy tak nie jest), a ludzie, którzy po prostu nie mogą zadać sobie trudu, aby je napisać.


9

Cóż, a to rozciąganie wymaga debugowania testów. Czas na napisanie testów wiąże się również z pewnym kosztem, choć większość ludzi zgadza się, że jest to inwestycja wstępna, która opłaca się przez cały okres użytkowania aplikacji zarówno w czasie oszczędzania czasu na debugowaniu, jak i stabilności.

Największym problemem, jaki osobiście z tym miałem jednak do czynienia, jest zebranie dyscypliny w pisaniu testów. W zespole, szczególnie w zespole o ustalonej pozycji, może być trudno przekonać ich, że spędzony czas jest opłacalny.


13
Aha - ale tam właśnie pojawia się TDTDD. Test Driven Test Driven Development.
Snowcrash

3
Nadal czasami znajduję błędy w testach testowych. Więc teraz ćwiczę TDTDTDD.
HorseloverFat

@SnowCrash +1 Rozglądałem się po Google, aby zobaczyć, ile czasu ludzie spędzają na testowaniu swoich testów, a potem zobaczyłem tę odpowiedź. Oficjalnie to znalazłem, ponieważ zastanawiałem się nad TDTDTDD.
BalinKingOfMoria Reinstate CMs

1
Wierzę, że przyszłość to (TD) <sup> ∞ </sup> TDD. Mam do tej pory jeden plik: zawiera on literę „x”.
Mike Rodent

Zgadzam się z @Tim. Przekonanie członków do przyjęcia jest najtrudniejsze.
Olu Smith

7

Jeśli twoje testy nie są bardzo dokładne, możesz wpaść w fałszywe poczucie „wszystko działa” tylko dlatego, że zdałeś testy. Teoretycznie, jeśli testy przejdą pomyślnie, kod działa; ale gdybyśmy mogli napisać kod idealnie za pierwszym razem, nie potrzebowalibyśmy testów. Morał polega na tym, aby samodzielnie sprawdzić poprawność psychiczną przed uznaniem czegoś za kompletne, nie polegaj tylko na testach.

W tej notatce, jeśli twój test poczytalności znajdzie coś, co nie jest testowane, koniecznie wróć i napisz test.


Nie wierzę w żadną klauzulę rozsądku, odkąd dorosłem.
Mike Gryzonie

7

Wadą TDD jest to, że zwykle jest ściśle związane z metodologią „Agile”, która nie przywiązuje wagi do dokumentacji systemu, a raczej zrozumienie, dlaczego test „powinien” zwrócić jedną konkretną wartość, a nie jakąkolwiek inną rezyduje tylko w deweloperze głowa.

Gdy tylko programista opuści lub zapomni powód, dla którego test zwraca jedną konkretną wartość, a nie inną, jesteś wkręcony. TDD jest w porządku, JEŚLI jest odpowiednio udokumentowane i otoczone czytelną dla człowieka (tj. Pointy-managera) dokumentacją, do której można się odwołać za 5 lat, gdy zmieni się świat i twoja aplikacja również musi.

Kiedy mówię o dokumentacji, nie jest to nieporozumienie w kodzie, to jest oficjalne pismo, które istnieje poza aplikacją, takie jak przypadki użycia i informacje ogólne, do których mogą się odwołać menadżerowie, prawnicy i biedny sap, który musi zaktualizować twój kod w 2011 roku.


1
Idealnie ułożone. Nie mogłem się więcej zgodzić. Dla mnie testy z pewnością nie pomagają opisać rzeczywistych definicji problemów wyższego poziomu. Dobra dokumentacja dowiodła swojej wartości raz po raz. Jako technika. w branży, pojęcia sprawdzone w czasie należy zrezygnować z coraz większej ostrożności. Samodokumentujący się kod jest absurdalnym pojęciem. Wierzę w prototypowanie, refaktoryzację i zwinność wynikającą z nieokreślonego problemu na początku. Jednak, jak na ironię, brak zbytniego zdefiniowania problemu na początku powoduje, że odgałęzienie dla TDD jest polem minowym.
wax_lyrical

1
Myślę, że to niesprawiedliwe. Dobre praktyki TDD potępiają magiczne liczby i niejasne testy. Testy powinny być proste i bardziej czytelne niż sam kod produkcyjny. twoje testy są dokumentacją. upewnij się, że tak wyglądają. ta odpowiedź przypomina trochę powiedzenie „dokumentacja jest zła, ponieważ czasami ludzie piszą naprawdę złą dokumentację” lub „klasy są złe, ponieważ widziałem niektóre klasy boskie, z którymi trudno było sobie poradzić”.
sara

6

Spotkałem kilka sytuacji, w których TDD doprowadza mnie do szału. Aby wymienić niektóre:

  • Możliwość utrzymania przypadku testowego:

    Jeśli jesteś w dużym przedsiębiorstwie, istnieje duża szansa, że ​​nie musisz samodzielnie pisać przypadków testowych lub przynajmniej większość z nich została napisana przez kogoś innego, kiedy wchodzisz do firmy. Funkcje aplikacji zmieniają się od czasu do czasu, a jeśli nie masz zainstalowanego systemu, takiego jak HP Quality Center, do ich śledzenia, szybko oszalejesz.

    Oznacza to również, że nowym członkom zespołu zajmie sporo czasu, aby zrozumieć, co się dzieje z przypadkami testowymi. To z kolei może przełożyć się na więcej potrzebnych pieniędzy.

  • Złożoność automatyzacji testów:

    Jeśli zautomatyzujesz niektóre lub wszystkie przypadki testowe w skrypty testowe uruchamiane maszynowo, będziesz musiał upewnić się, że te skrypty testowe są zsynchronizowane z odpowiadającymi im ręcznymi testami i zgodne ze zmianami aplikacji.

    Ponadto poświęcisz czas na debugowanie kodów, które pomogą Ci wykryć błędy. Moim zdaniem większość tych błędów wynika z tego, że zespół testujący nie odzwierciedlił zmian aplikacji w skrypcie testu automatyzacji. Zmiany w logice biznesowej, graficznym interfejsie użytkownika i innych wewnętrznych elementach mogą spowodować, że skrypty przestaną działać lub nie będą działać poprawnie. Czasami zmiany są bardzo subtelne i trudne do wykrycia. Kiedyś wszystkie moje skrypty zgłaszały awarię, ponieważ oparły swoje obliczenia na informacjach z tabeli 1, podczas gdy tabela 1 była teraz tabelą 2 (ponieważ ktoś zamienił nazwę obiektów tabeli w kodzie aplikacji).


To wcale nie dotyczy TDD. Jeśli ktoś z innego działu pisze twoje przypadki testowe, nie robisz TDD. Jeśli masz ręczne przypadki testowe, nie wykonujesz TDD. Jeśli kod biblioteki się zepsuje, a testy nie powiodą się z powodu zmian w GUI, najprawdopodobniej też nie robisz TDD. To bardziej przypomina argumenty przeciwko dużym, nieefektywnym działom kontroli jakości w przedsiębiorstwach.
sara,

5

Największym problemem są ludzie, którzy nie wiedzą, jak napisać odpowiednie testy jednostkowe. Piszą testy, które są od siebie zależne (i działają świetnie z Antem, ale potem nagle się nie udają, gdy uruchamiam je z Eclipse, tylko dlatego, że działają w innej kolejności). Piszą testy, które nie testują niczego konkretnego - po prostu debugują kod, sprawdzają wynik i zmieniają go w test, nazywając go „test1”. Rozszerzają zakres klas i metod tylko dlatego, że łatwiej będzie dla nich pisać testy jednostkowe. Kod testów jednostkowych jest okropny, ze wszystkimi klasycznymi problemami programistycznymi (ciężkie sprzęganie, metody o długości 500 linii, wartości zakodowane na stałe, powielanie kodu) i jest piekielnie trudny do utrzymania. Z jakiegoś dziwnego powodu ludzie traktują testy jednostkowe jako coś gorszego od „prawdziwego” kodu i nie w ogóle dbają o ich jakość. :-(


4

Tracisz dużo czasu na pisanie testów. Oczywiście można to zapisać do końca projektu, szybciej wychwytując błędy.


Czy to naprawdę negatywny lub chytry sposób wyrażenia pozytywnego.
IanL

3

Największym minusem jest to, że jeśli naprawdę chcesz właściwie wykonywać TDD, będziesz musiał dużo zawieść, zanim odniesiesz sukces. Biorąc pod uwagę, ile firm produkujących oprogramowanie (dolar za KLOC) w końcu zostaniesz zwolniony. Nawet jeśli Twój kod jest szybszy, czystszy, łatwiejszy w utrzymaniu i zawiera mniej błędów.

Jeśli pracujesz w firmie, która płaci Ci przez KLOC (lub zaimplementowane wymagania - nawet jeśli nie zostały przetestowane), trzymaj się z dala od TDD (lub recenzji kodu, programowania w parach, ciągłej integracji itp. Itp.).


3

Tracisz możliwość stwierdzenia, że ​​jesteś „skończony” przed przetestowaniem całego kodu.

Tracisz możliwość pisania setek lub tysięcy wierszy kodu przed jego uruchomieniem.

Tracisz możliwość uczenia się przez debugowanie.

Tracisz elastyczność wysyłania kodu, którego nie jesteś pewien.

Tracisz swobodę ścisłego łączenia modułów.

Tracisz opcję pomijania pisania dokumentacji projektowej niskiego poziomu.

Tracisz stabilność kodu, którą wszyscy boją się zmienić.


1
Zależy od twojej definicji „dostarczać rozwiązanie na czas” - to, że „każde stare, częściowo zepsute rozwiązanie na czas” lub „dostarczać działające rozwiązania na czas”. Z pewnością tracisz możliwość dostarczania częściowo uszkodzonych rozwiązań na czas. Jeśli chodzi o szybkość tworzenia - podoba mi się metryka „czas, jaki upłynął od rozpoczęcia tworzenia do tygodnia bezbłędnego wdrażania na żywo”. Jeśli zmierzysz go rzetelnie, trudno nawet w ogóle zatrzymać zegar na kawałku copmlex pracy innej niż TDD.
Dafydd Rees

47
-1, dokładnie to powiedział OP, że nie chce.
erikkallen

1
Wiele prawdziwych stwierdzeń, ale: co powiedział Erikkallen. -1.
j_random_hacker

@ j_random_hacker mówi haker ... LOL
Dan

tylko trzeci stwierdzenie jest legit „nauka poprzez debugowanie jest stracone”
YEH

2

Popieram odpowiedź na temat początkowego czasu rozwoju. Tracisz także możliwość komfortowej pracy bez bezpieczeństwa testów. Zostałem też opisany jako głupek TDD, więc możesz stracić kilku przyjaciół;)


2

Jest postrzegany jako wolniejszy. Długoterminowe, co nie jest prawdą w odniesieniu do smutku, uratuje cię w dalszej drodze, ale ostatecznie skończysz pisać więcej kodu, więc prawdopodobnie spędzasz czas na „testowaniu, a nie kodowaniu”. To błędny argument, ale zapytałeś!


2

Ponowne skoncentrowanie się na trudnych, nieprzewidzianych wymaganiach jest stałą zmorą programisty. Rozwój oparty na testach zmusza Cię do skupienia się na znanych już, przyziemnych wymaganiach i ogranicza rozwój do tego, co już sobie wyobrażałeś.

Pomyśl o tym, prawdopodobnie skończysz na projektowaniu do konkretnych przypadków testowych, więc nie będziesz kreatywny i zaczniesz myśleć: „byłoby fajnie, gdyby użytkownik mógł zrobić X, Y i Z”. Dlatego gdy ten użytkownik zacznie się ekscytować potencjalnymi fajnymi wymaganiami X, Y i Z, Twój projekt może być zbyt sztywno skoncentrowany na już określonych przypadkach testowych i trudno będzie go dostosować.

To oczywiście miecz obosieczny. Jeśli poświęcisz cały swój czas na projektowanie każdego wyobrażalnego, możliwego do wyobrażenia, X, Y i Z, jakiego użytkownik może kiedykolwiek chcieć, nieuchronnie nigdy niczego nie ukończysz. Jeśli coś zrobisz, nikt (łącznie z tobą) nie będzie miał pojęcia, co robisz w kodzie / projekcie.


Pomyśl o tym, prawdopodobnie skończysz na projektowaniu do konkretnych przypadków testowych, więc nie będziesz kreatywny i zaczniesz myśleć: „byłoby fajnie, gdyby użytkownik mógł zrobić X, Y i Z”. - Moim zdaniem jest dokładnie odwrotnie. Pisząc testy jednostkowe, zastanawiasz się nad różnymi przypadkami biznesowymi, a to oznacza, że ​​jesteś kreatywny i pozwala przewidzieć coś nieprzewidzianego. Cała ta kreatywność nie jest jednak ważna, jeśli Twoja implementacja zawiera błędy.
BlueLettuce16

1

Pisanie testów „losowych” danych, takich jak kanały XML i bazy danych (może nie być trudne), może być trudne i czasochłonne. Ostatnio spędziłem trochę czasu, pracując z kanałami danych pogodowych. To dość mylące testy pisania, przynajmniej dlatego, że nie mam zbyt dużego doświadczenia z TDD.


To jest powszechny problem. Zwykle kpię z nich zakodowanymi obiektami, a następnie osobno testuję bazę danych. Twoja warstwa biznesowa powinna wtedy pracować tylko z danymi statycznymi, wtedy DAL zostanie przetestowany w kontrolowanym środowisku (w którym możesz w nim skrypty dane itp.)
Rob Cooper

1

Stracisz duże klasy z wieloma obowiązkami. Prawdopodobnie stracisz także duże metody z wieloma obowiązkami. Możesz stracić zdolność do refaktoryzacji, ale stracisz także część konieczności refaktoryzacji.

Jason Cohen powiedział coś w stylu: TDD wymaga pewnej organizacji twojego kodu. Może to być niepoprawne architektonicznie; na przykład, ponieważ metod prywatnych nie można wywoływać poza klasą, należy uczynić metody nieprywatnymi, aby można je było przetestować.

Mówię, że oznacza to pominięcie abstrakcji - jeśli kod prywatny naprawdę wymaga przetestowania, prawdopodobnie powinien być w osobnej klasie.

Dave Mann


1

Musisz pisać aplikacje w inny sposób: taki, który umożliwia ich testowanie. Byłbyś zaskoczony, jak trudne jest to na początku.

Niektórzy ludzie uważają, że myślenie o tym, co zamierzają napisać, zanim będą zbyt trudne. Pojęcia takie jak drwiny mogą być dla niektórych trudne. TDD w starszych aplikacjach może być bardzo trudne, jeśli nie zostały zaprojektowane do testowania. TDD wokół frameworków, które nie są przyjazne TDD, może być również walką.

TDD jest umiejętnością, więc młodsi deweloperzy mogą początkowo walczyć (głównie dlatego, że nie nauczono ich, aby działali w ten sposób).

Ogólnie rzecz biorąc, wady są rozwiązywane, gdy ludzie stają się wykwalifikowani, a ty w końcu wyodrębniasz „śmierdzący” kod i masz bardziej stabilny system.


1

Zajmuje to trochę czasu, aby zacząć robić to w projekcie, ale ... Zawsze żałuję, że nie zastosowałem podejścia opartego na testach, kiedy znajduję głupie błędy, które automatyczny test mógł znaleźć bardzo szybko. Ponadto TDD poprawia jakość kodu.


1
  • Testy jednostkowe wymagają więcej kodu do napisania, a tym samym wyższych kosztów początkowych rozwoju
  • to więcej kodu do utrzymania
  • wymagana dodatkowa nauka

1

Wszystkie dobre odpowiedzi. Dodałbym kilka sposobów na uniknięcie ciemnej strony TDD:

  • Napisałem aplikacje do zrobienia ich losowego autotestu. Problem z pisaniem konkretnych testów jest taki, że nawet jeśli piszesz ich dużo, dotyczą one tylko tych przypadków, o których myślisz. Generatory losowych testów znajdują problemy, o których nie pomyślałeś.

  • Cała koncepcja wielu testów jednostkowych sugeruje, że masz komponenty, które mogą dostać się do nieprawidłowych stanów, takie jak złożone struktury danych. Jeśli trzymasz się z dala od skomplikowanych struktur danych, jest o wiele mniej do przetestowania.

  • W zakresie, w jakim pozwala na to Twoja aplikacja, nie wstydź się projektu, który opiera się na właściwej kolejności powiadomień, zdarzeń i skutków ubocznych. Można je łatwo upuścić lub zakodować, więc wymagają wielu testów.


Losowe testy mogą sporadycznie zawieść i utrudnić ich powtarzanie
David Sykes

@DavidSykes: Za każdym razem, gdy przeprowadzasz losowy test, zapisujesz parametry, aby w razie niepowodzenia można go powtórzyć lub powtórzyć później, nawet jeśli się nie powiedzie. Chodzi o to, że nie od ciebie zależy wymyślenie przypadków testowych. Jeśli jesteś podobny do mnie, instynktownie dążysz do bezpiecznych przypadków testowych.
Mike Dunlavey

0

TDD wymaga pewnej organizacji dla twojego kodu. Może to być nieefektywne lub trudne do odczytania. Lub nawet architektonicznie niewłaściwy; na przykład, ponieważ privatemetod nie można wywoływać poza klasą, należy uczynić metody nieprywatnymi, aby można je było przetestować, co jest po prostu błędne.

Kiedy kod się zmienia, musisz również zmienić testy. Przy refaktoryzacji może to być dużo dodatkowej pracy.


9
Wszystkie metody prywatne powinny zostać przetestowane za pomocą metod publicznych, które i tak by istniały.
Garry Shutler

Nie jest to możliwe we wszystkich klasach. Czasami nie chcesz wyśmiewać wszystkich zależności itp., A po prostu chcesz przetestować metodę narzędzia.
Jason Cohen,

+1, więc prawda. Dodaj do tego wymóg, aby czasami dodawać metody pobierające / ustawiające do pól prywatnych, aby móc poprawnie skonfigurować i odczytać stan dla testu jednostkowego, nawet jeśli stan powinien być prywatny dla klasy.
erikkallen

Zastanów się nad napisaniem testów tak, jakby to był dokument dotyczący wymagań życiowych. Wtedy zobaczysz światło. Przeczytaj także Wzorce testowe XUnit.
Scott Nimrod,

0

Dodam, że jeśli zastosujesz zasady BDD do projektu TDD, możesz złagodzić kilka głównych wad wymienionych tutaj (zamieszanie, nieporozumienia itp.). Jeśli nie znasz BDD, zapoznaj się ze wstępem Dana Northa. Wymyślił tę koncepcję w odpowiedzi na niektóre problemy wynikające z zastosowania TDD w miejscu pracy. Intro Dana do BDD można znaleźć tutaj .

Sugeruję tylko tę sugestię, ponieważ BDD rozwiązuje niektóre z tych negatywów i działa jak przerwa. Zastanów się nad tym, zbierając opinie.


Absolutnie. Podczas oceny TDD należy wziąć pod uwagę BDD.
user9991,

Wygląda na to, że BDD = rozwój oparty na zachowaniu
hayalci

0

Musisz upewnić się, że twoje testy są zawsze aktualne, moment, w którym zaczniesz ignorować czerwone światła, jest momentem, w którym testy stają się bez znaczenia.

Musisz także upewnić się, że testy są kompleksowe, lub w momencie pojawienia się dużego błędu, duszny typ zarządzania, który ostatecznie przekonałeś, abyś spędził czas na pisaniu większej ilości kodu, będzie narzekał.


0

Osoba, która nauczyła mojego zespołu zwinnego rozwoju, nie wierzyła w planowanie, napisałeś tyle samo dla najmniejszych wymagań.

Jego motto to: refaktor, refaktor, refaktor. Zrozumiałem, że refaktor oznacza „nie planować z wyprzedzeniem”.


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.