Jest ich sporo, ale zalety zdecydowanie przewyższają wady.
Istnieje stroma krzywa uczenia się.
Wydaje się, że wielu programistów spodziewa się, że od pierwszego dnia będą mogli efektywnie programować od pierwszego testu. Niestety zdobycie doświadczenia i programowanie z taką samą prędkością jak wcześniej zajmuje dużo czasu. Nie da się tego obejść.
Mówiąc ściślej, bardzo łatwo się pomylić. Możesz bardzo łatwo (z bardzo dobrymi intencjami) napisać całą masę testów, które albo są trudne do utrzymania, albo testować niewłaściwe rzeczy. Trudno tu podać przykłady - tego rodzaju problemy wymagają doświadczenia. Musisz dobrze rozdzielić problemy i zaprojektować testowalność. Moja najlepsza rada tutaj to programowanie parami z kimś, kto naprawdę dobrze zna TDD.
Robisz więcej kodowania z góry.
Test-first oznacza, że nie możesz pominąć testów (co jest dobre) i oznacza, że skończysz pisać więcej kodu z góry. To oznacza więcej czasu. Znów nie da się tego obejść. Otrzymujesz nagrodę za kod, który jest łatwiejszy w utrzymaniu, rozszerzaniu i generalnie mniej błędów, ale zajmuje to trochę czasu.
Może być trudną sprzedażą dla menedżerów.
Menedżerowie oprogramowania zazwyczaj zajmują się tylko osiami czasu. Jeśli przejdziesz do programowania pierwszego testu i nagle poświęcasz 2 tygodnie na ukończenie funkcji zamiast jednej, nie spodoba im się to. To zdecydowanie bitwa, którą warto stoczyć, a wielu menedżerów jest wystarczająco oświeconych, aby ją zdobyć, ale może to być trudna sprzedaż.
Może być trudną sprzedażą dla innych programistów.
Ponieważ istnieje stroma krzywa uczenia się, nie wszyscy programiści lubią programować w pierwszej kolejności. W rzeczywistości zgaduję, że na początku większość programistów tego nie lubi. Możesz robić rzeczy takie jak programowanie parami, aby pomóc im nabierać prędkości, ale może to być trudna sprzedaż.
W końcu zalety przeważają nad wadami, ale nie pomaga, jeśli po prostu zignorujesz wady. Wiedza o tym, z czym masz do czynienia od samego początku, pomaga ci pokonać niektóre, jeśli nie wszystkie, wady.
Test-first zakłada, że piszesz kod, który jest:
Jeśli twój projekt nie spełnia tych wymagań, będziesz miał trudności. Organizatorzy TDD nie mają dobrych odpowiedzi na to pytanie, sugerując, że przeprojektowałeś swój produkt, aby lepiej mieścił się w tych liniach. Są sytuacje, w których jest to niemożliwe lub niepożądane.
W praktyce może też istnieć ogromny problem z ludźmi myślącymi, że testy w pierwszej kolejności faktycznie dowodzą cokolwiek na temat poprawnego działania programu. W wielu przypadkach nie jest to prawdą, ale nawet w przypadkach, w których jest to prawdą, daleki jest od pełnego obrazu poprawności. Ludzie widzą setki pozytywnych testów i zakładają, że bezpieczniej jest testować mniej, ponieważ przed TDD i tak zrobili tylko kilkaset przypadków testowych. Z mojego doświadczenia wynika, że TDD oznacza, że musisz mieć jeszcze więcej testów integracyjnych, ponieważ programiści będą mieli fałszywe zabezpieczenia, a ból związany ze zmianą wszystkich testów w celu przeprowadzenia dużego reduktora może skłonić programistów do ciekawych obejść.
Przykłady:
Mój osobisty najlepszy przykład to pisanie kodu bezpieczeństwa dla asp.net. Jeśli mają działać w nieprzyjaznym środowisku z konfiguracji maszyny, są otrzymywane, podpisywane i zapieczętowane, a ponieważ działają przeciwko obiektom boga IIS, bardzo trudno jest z nich kpić poprawnie. Dodaj pewne ograniczenia dotyczące wydajności i wykorzystania pamięci, a bardzo szybko stracisz elastyczność korzystania z obiektów zastępczych w pozostałych obszarach.
Jakikolwiek mikrokontroler lub inny kod środowiska o niskim poziomie zasobów może nie być w stanie wykonać projektu w stylu OO, ponieważ abstrakcje nie są optymalizowane i masz niskie limity zasobów. To samo można powiedzieć o procedurach o wysokiej wydajności w wielu przypadkach.
źródło
Największą wadą, jaką widziałem, nie jest z samym TDD, ale z praktykami. Przyjmują podejście dogmatyczne i gorliwe, w którym wszystko musi zostać przetestowane . Czasami (to znaczy wiele razy) nie jest to konieczne. Może to również nie być praktyczne (np. Wprowadzenie organizacji do TDD).
Dobry inżynier znajduje kompromisy i stosuje właściwą równowagę pomiędzy tym, kiedy / gdzie / jak zastosować najpierw test. Ponadto, jeśli ciągle spędzasz dużo więcej czasu na rozwijaniu testów zamiast rzeczywistego kodu (2-3 razy lub więcej), masz kłopoty.
Innymi słowy, bądź pragmatyczny i rozsądny z TDD (lub cokolwiek w rozwoju oprogramowania w tym zakresie).
źródło
Zacząłem robić TDD na początku sierpnia 2009 r. I przekonałem całą moją firmę do przejścia na nią we wrześniu / październiku 2009 r. Obecnie cały zespół deweloperów jest w pełni przekształcony, a przekazywanie niepoddanego testowi kodu do repo jest uważane za złą rzecz i narzucane. Działa to dla nas świetnie i nie wyobrażam sobie powrotu do kodowania dla kowbojów.
Istnieją jednak dwa problemy, które są dość zauważalne.
Zestaw testowy musi być utrzymany
Kiedy poważnie myślisz o TDD, skończysz pisać wiele testów. Ponadto, zajmuje trochę czasu i doświadczenia, aby uświadomić sobie, co jest właściwą szczegółowości testów (przesadza jest prawie tak źle, jak underdoing go). Testy te są także kodem i są podatne na bitrot. Oznacza to, że musisz zachować je tak, jak wszystko inne: zaktualizuj je, gdy aktualizujesz biblioteki, od których są zależne, od czasu do czasu zmieniaj parametry ... Gdy wprowadzisz duże zmiany w kodzie, wiele testów nagle się zdezaktualizuje lub nawet po prostu źle. Jeśli masz szczęście, możesz je po prostu usunąć, ale często zdarza się, że wyodrębniasz przydatne bity i dostosowujesz je do nowej architektury.
Od czasu do czasu testują abstrakcje
Używamy Django, który ma całkiem niezłą platformę testową. Czasami jednak przyjmuje założenia, które są nieco sprzeczne z rzeczywistością. Na przykład niektóre oprogramowanie pośrednie może przerwać testy. Lub niektóre testy przyjmują założenia dotyczące zaplecza buforowania. Ponadto, jeśli używasz „rzeczywistej” bazy danych (nie SQLite3), przygotowanie bazy danych do testów zajmie dużo czasu. Oczywiście możesz (i powinieneś) używać SQLite3 i bazy danych w pamięci do testów wykonywanych lokalnie, ale niektóre kody będą zachowywać się inaczej w zależności od używanej bazy danych. Konieczne jest skonfigurowanie serwera ciągłej integracji działającego w realistycznej konfiguracji.
(Niektórzy powiedzą ci, że powinieneś wyśmiewać wszystkie rzeczy, takie jak baza danych, w przeciwnym razie twoje testy nie będą „czyste”, ale to tylko ideologia. Jeśli popełnisz błędy w swoim kpiącym kodzie (i uwierz mi, to zrobisz), twoje testsuite będzie bezwartościowe).
To wszystko mówi, że problemy, które opisałem, zaczynają być zauważalne dopiero, gdy jesteś dość zaawansowany w TDD ... Kiedy dopiero zaczynasz w TDD (lub pracujesz przy mniejszych projektach), refaktoryzacja testów nie będzie problemem.
źródło
Dla mnie jest jakiś głęboki problem psychologiczny z testami, ilekroć próbuję je szeroko zastosować, jak w TDD: jeśli tam są, koduję niechlujnie, ponieważ ufam, że testy wychwycą jakiekolwiek problemy. Ale jeśli nie ma testów zapewniających siatkę bezpieczeństwa, koduję ostrożnie, a wynik jest niezmiennie lepszy niż w przypadku testów.
Może to tylko ja. Ale czytałem też gdzieś, że samochody z wszelkiego rodzaju dzwonkami i gwizdkami bezpieczeństwa częściej się rozbijają (ponieważ kierowcy wiedzą, że są tam zabezpieczenia), więc może warto to uznać; TDD może być niekompatybilny z niektórymi osobami.
źródło
Jedną z sytuacji, w której naprawdę przeszkadza mi testowanie, jest to, że chcę szybko wypróbować jakiś pomysł i sprawdzić, czy może on zadziałać, zanim napiszę odpowiednią implementację.
Moje podejście to zwykle:
Czasami nie przechodzę do kroku 2.
W tym przypadku korzystanie z TDD okazało się mieć dla mnie więcej wad niż zalet:
Tak więc, kiedy muszę odkrywać nowe pomysły, nie używam TDD i wprowadzam testy jednostkowe tylko wtedy, gdy mam wrażenie, że nowy kod się gdzieś znajduje.
źródło
Wady lub koszty TDD
Uwaga: Istnieje szereg różnych rodzajów TDD. Bez względu na jednostkę, BDD, ATDD lub inne warianty wiele trudności pozostaje
Skutki uboczne
Niezależnie od tego, czy chodzi o kpiny, testy czy testy funkcjonalne, zależności od stanów zewnętrznych lub systemów są często źródłem największej złożoności testów, nieporozumień podczas testowania i największego ryzyka popełnienia błędu. Kilka problemów, które widziałem:
Będziesz musiał zmienić swoje podejście do kodowania, dla niektórych będzie to drastyczna zmiana.
Różni ludzie kodują na różne sposoby. W TDD musisz zacząć od testu, który potwierdza określone zachowanie, a następnie zaimplementować, aby test przeszedł pomyślnie. Widziałem i byłem programistą, którego programowanie nie sprzyjało TDD. Zajęło mi około 2 miesięcy, kiedy początkowo przyzwyczaiłem się do zmiany podejścia do programowania.
Zrozumienie, na czym polega testowanie, a na czym nie zależy, zajmuje trochę czasu.
Każdy zespół powinien podjąć wyraźną decyzję dotyczącą tego, gdzie chce wytyczyć linię testową. Jakie rzeczy cenią, które chcą przetestować, a czego nie. Często jest to bolesny proces uczenia się, jak pisać dobre testy i co tak naprawdę zależy Ci na testowaniu. W międzyczasie kod będzie w ciągłym przepływie, dopóki nie będzie spójny styl i podejście.
Specyficzny dla testu jednostkowego: duże reaktory
Duży lub fundamentalny reaktor znaczącej bazy kodu z dziesiątkami tysięcy testów jednostkowych wygeneruje ogromny koszt aktualizacji wszystkich testów. Przejawia się to często w wypychaniu się przeciw robieniu refaktora, nawet jeśli jest to właściwe, ponieważ koszty są związane z robieniem tego.
źródło
Moja analogia to bariery na torze Scalextric. Jeśli je założysz, będziesz o wiele mniej ostrożny.
Ludzie mają również trochę miejsca na kadet na temat swoich testów - ponieważ działają dobrze, wierzą, że kod jest w pełni przetestowany, a to dopiero początek procesu testowania.
Moim zdaniem TDD jest odskocznią dla BDD. Wiele testów, które się uruchamiają, tak naprawdę nie pomaga deweloperom, nie wiedząc, co robią testy. W przypadku BDD dane wyjściowe testu są w języku angielskim, co dokumentuje testy, a tym samym buduje zrozumienie systemu.
źródło
Zaletą TDD jest to, że zmusza cię do strzeżenia kodu przed ludźmi, którzy go nie rozumieją. Tak, często dotyczy to Ciebie. Ale co się stanie, gdy kod nie jest wart ochrony? Jest dużo kodu, którego w ogóle nie powinno być! Problem z TDD dotyczy więc programistów piszących zły kod. TDD prawdopodobnie nie pomoże im napisać dobrego kodu, jest o wiele bardziej prawdopodobne, że napiszą też okropne testy. Zatem w ich przypadku TDD doda tylko bałagan; źle napisane i / lub zbędne testy nie są bardziej zabawne niż inne formy złego kodu.
źródło