TDD negatywne doświadczenie [zamknięte]

94

Jaka jest negatywna strona twojego doświadczenia TDD? Czy uważasz, że kroki dziecka (najprostszy sposób na zielony test) są denerwujące i bezużyteczne? Czy uważasz, że testy bez wartości (gdy test ma sens na początku, ale w końcowej implementacji sprawdza tę samą logikę co inne testy) utrzymanie krytyczne? itp.

Powyższe pytania dotyczą rzeczy, z którymi czuję się niekomfortowo podczas mojego doświadczenia TDD. Jestem więc zainteresowany, czy inni programiści mają podobne odczucia i co o nich myślą.

Byłbym wdzięczny za linki do artykułów opisujących negatywne strony TDD (Google jest wypełniony pozytywnymi i często fanatycznymi artykułami).

Idsa
źródło
10
Domyślam się, że nie usłyszysz wielu szczerych odpowiedzi na temat negatywnych doświadczeń ludzi, ponieważ TDD wciąż jest w stanie „wczesnego adopcji”, a większość ludzi, którzy są zainteresowani i zaangażowani w jego wypróbowanie, nie jest wystarczająco obiektywna, aby oceń go na podstawie jego względnych zalet. Branża zwykle zajmuje kilka lat, aby naprawdę ustalić długoterminowe skutki nowych procesów i technik, a nawet wtedy trudno jest uzyskać proste odpowiedzi z powodu braku kontroli. Niemniej jednak dobre pytanie i powodzenia w uzyskiwaniu pomocnych odpowiedzi!
Aaronaught
20
Czy masz problemy ze znalezieniem negatywnych stron w Internecie ?!
Eric Wilson,
4
@Job (i ewentualnie inne): nie zapomnij, że zapytał o TDD, a nie o testy jednostkowe. TDD! = Testowanie jednostkowe.
n1ckp
2
Kusi mnie, aby odpowiedzieć na to pytanie, ale tak naprawdę nie chcę zaczynać, ponieważ zajmie to pół dnia.
Rei Miyasaka,
2
Kiedy wydaje mi się, że spędzam wystarczająco dużo czasu na błędach, wydaje mi się, że mógłbym poświęcić mniej czasu na pisanie testów dla każdej pojedynczej rzeczy, którą piszę, zanim ją piszę, nie przyjmuję test-first-all-Things-TDD. Zamiast tego zawstydzę głowę i zacznę szukać nowej kariery. Nie o błędach, które mówisz? Projekt? Tak. Otóż ​​to. To jest dokładnie to. I nie nauczyłeś się cholernej rzeczy na temat solidnej konstrukcji, dając sobie siatkę bezpieczeństwa i licencję na dalsze głupie działanie. Odłóż IDE i spróbuj odczytać kod, jeśli chcesz odkryć prawdziwy problem.
Erik Reppen

Odpowiedzi:

94

Podobnie jak wszystko, co znajduje się pod sztandarem „Agile”, TDD jest czymś, co brzmi dobrze w teorii, ale w praktyce nie jest tak jasne, jak dobre jest (a także jak większość „Agile”, powiedziano ci, że jeśli nie lubisz to, robisz to źle).

Definicja TDD nie jest wyryta w kamieniu: faceci tacy jak Kent Beck domagają się, aby przed pojedynczą linią kodu napisano test niekompilacyjny, a każdą pojedynczą linię kodu napisać, aby pomyślnie przejść test. Projekt z przodu jest minimalny i wszystko jest napędzaneprzez testy. To po prostu nie działa. Widziałem aplikację dla dużych przedsiębiorstw opracowaną przy użyciu tej metodologii i mam nadzieję, że jest to gorszy kod, jaki widzę w mojej karierze (nie będzie to daleko; i było tak pomimo tego, że pracują nad nią utalentowani programiści). Z tego, co widziałem, wynika ogromna liczba źle przemyślanych testów, które głównie sprawdzają poprawność wywołań funkcji, wyjątki są zgłaszane, gdy zmienne są zerowe, a środowisko próbne przechodzi dokładny trening (whoop-de-whoop); Twój kod produkcyjny jest mocno powiązany z tymi testami i nie pojawia się marzenie o ciągłym i łatwym refaktoryzowaniu - w rzeczywistości ludzie są jeszcze mniej podatni na naprawienie złego kodu z powodu wszystkich testów, które złamie.

I odwrotnie, słyszałem, jak ludzie twierdzą, że TDD oznacza zaprojektowanie testów z góry na wysokim poziomie w ramach fazy planowania - obok projektu architektonicznego. Testy te mogą ulec zmianie podczas opracowywania, gdy dostępnych jest więcej informacji, ale zostały one starannie przemyślane i stanowią dobry przewodnik na temat tego, co powinien zrobić kod. Dla mnie to ma sens.

23157
źródło
7
+1 „projektowanie testów z góry na wysokim poziomie w ramach fazy planowania - obok projektu architektonicznego” Brzmi również bardziej rozsądnie.
Steven Jeuris,
11
@Aaronaught Agile nie oznacza braku planowania, oznacza tylko planowanie czasu .
Adam Jaskiewicz
25
@Adam Jaskiewicz: Uwielbiam rzecz „bez planowania z góry”. No dalej, planowanie jest z definicji z góry . Jeśli nie planujesz wcześniej, ale podczas imprezy wcale nie planujesz; improwizujesz. ;-)
CesarGon
34
@Adam - „Czy ludzie naprawdę wskakują na kodowanie pierwszego dnia iteracji?” tak. To jest „zwinny” mężczyzna. Ostatnie miejsce, w którym pracowałem (i wyrzucono mnie z pracy za to, że nie było „zwinne”), wykonali cały 3-miesięczny cykl wydawniczy bez planowania ani jednej linii kodu ani robienia jednej strony dokumentacji. I tak, kod był okropny i tak, oprogramowanie było powolne, niezgrabne i zawierało błędy. W dniu, w którym dołączyłem, kierownik powiedział mi z dumą, że są „najbardziej zwinnym sklepem w Londynie”. Z pewnością tak było.
7
Można dodać kolejny problem: tak długo, jak przejdzie test, musi być dobry. Nieważne, że sam test może być wadliwy, a zatem powoduje fałszywe negatywy i / lub fałszywie dodatnie. Oczywiście wymaganie „100% pokrycia testowego” i wszystko, co ma taki zakres, jest z definicji idealne, co powoduje, że bezużyteczne testy, które w rzeczywistości niczego nie testują, ale są napisane wyłącznie w celu osiągnięcia tego pokrycia w 100%, kod nieudokumentowany, ponieważ licznik pokrycia liczy komentarze jako nieosłonięty kod itp. itd.
jwenting
66

Ten wywiad ( autor Clojure ) Rich Hickey zawiera następujące informacje. Czuję się w 100% współczujący:

Życie jest krótkie i dziennie jest tylko skończona liczba godzin. Musimy więc dokonywać wyborów dotyczących sposobu spędzania czasu. Jeśli spędzamy to na pisaniu testów, to nie spędzamy czasu na robieniu czegoś innego. Każdy z nas musi ocenić, jak najlepiej spędzić czas, aby zmaksymalizować wyniki, zarówno pod względem ilości, jak i jakości. Jeśli ludzie myślą, że spędzanie pięćdziesięciu procent czasu na pisaniu testów maksymalizuje ich wyniki - w porządku dla nich. Jestem pewien, że to nie jest prawda - wolałbym spędzać ten czas na myśleniu o moim problemie. Jestem pewien, że dla mnie daje to lepsze rozwiązania, z mniejszą liczbą wad, niż jakikolwiek inny sposób wykorzystania mojego czasu. Zły projekt z kompletnym zestawem testów jest nadal złym projektem.

Kolejne podobne oświadczenie Donalda Knutha w wywiadzie książkowym Coders at Work , skopiowane z tego miejsca :

Seibel: Mówiąc o pracy praktycznej, w trakcie pracy nad sztuką programowania komputerowego napisałeś swój system składu TeX, który przerodził się w dziesięcioletnią przerwę. Rozumiem, że pierwszą wersję TeX-a napisałeś całkowicie z dala od komputera.

Knuth: Kiedy pisałem TeXa w 1977 i 78, oczywiście nie miałem umiejętności programowania, ale miałem programowanie strukturalne. Napisałem to w dużym zeszycie, długopisem, ołówkiem. Sześć miesięcy później, po przejściu całego projektu, zacząłem pisać na komputerze. Debugowałem w marcu 1978 roku, kiedy zacząłem pisać program w październiku 1977 roku. Kod do tego znajduje się w archiwach Stanforda - wszystko jest napisane ołówkiem - i oczywiście wrócę i zmienię podprogram, gdy się dowiem, co to powinno być. Był to system pierwszej generacji, więc możliwe było wiele różnych architektur i musiałem je odrzucić, dopóki nie zamieszkałem z nim przez jakiś czas i nie wiedziałem, co tam jest. I to był problem z kurczakiem i jajkiem - nie można było pisać, dopóki nie ma się czcionek, ale wtedy nie można było mieć czcionek, dopóki nie można było pisać. Ale programowanie strukturalne dało mi pomysł na niezmienniki i umiejętność tworzenia czarnych skrzynek, które mogłem zrozumieć. Miałem więc pewność, że kod zadziała, kiedy w końcu go debuguję. Czułem, że zaoszczędzę dużo czasu, jeśli zaczekam sześć miesięcy, zanim cokolwiek przetestuję. Miałem dość pewności, że kod jest w przybliżeniu poprawny.

Seibel: A oszczędność czasu polegałaby na tym, że nie spędzałbyś czasu na budowaniu rusztowań i kodów pośredniczących do testowania niepełnego kodu?

Knuth: Racja.

Joonas Pulakka
źródło
24
Myślę, że musisz spojrzeć na rodzaj pracy, którą wykonujesz. Knuth i Hickey rozmawiają o projektowaniu nowych (innowacyjnych) aplikacji. Jeśli spojrzysz na popularność TDD (szeroka generalizacja), dojdziesz do wniosku, że większość aplikacji napisanych w sposób TDD ma już dobrze znaną architekturę.
sebastiangeiger
4
Rozumiem, co oznacza Rich Hickey, ale chciałbym dodać: moje doświadczenie polega na tym, że pisząc testy, musisz naprawdę pomyśleć o swoim projekcie i pomyśleć o tym, w jaki sposób uczynisz swój kod możliwym do przetestowania, co moim zdaniem doświadczenie, powoduje lepszy projekt.
Niklas H
3
Widząc, że OP prosi o negatywne doświadczenia z TDD, żaden z twoich przykładów nie wydaje się mieć związku z tym pytaniem, ponieważ żaden z nich nie pokazuje przykładu TDD w akcji.
Winston Ewert
5
@Michael Borgwardt: Stosunkowo łatwo jest dodać testy do istniejącego, dobrego projektu, aby pozbyć się błędów we wdrażaniu. Ale pozbycie się złego projektu często oznacza całkowite przepisanie. Zatem głównym celem powinno być poprawne zaprojektowanie ; wykonanie jest łatwiejsze do późniejszego naprawienia.
Joonas Pulakka
4
Większość aplikacji biznesowych nie ma zalet pisania i / lub obsługi przez Donalda Knutha. Żywotność aplikacji jest zwykle DUŻO dłuższa niż jej pierwotna wersja. Chciałbym, żeby ludzie napisali więcej testów z góry na temat mojego obecnego projektu. Teraz utrzymanie jest jak pole minowe nieskończonych regresji.
Matt H
58

Moje negatywne doświadczenia z TDD były moje pierwsze. TDD brzmiało dla mnie wspaniale, robiłem kontrolę jakości przez lata i nadal miałem w głowie nowe horrory. Chciałem zmiażdżyć każdy błąd, zanim przekształci się on w kompilację. Niestety użycie TDD nie gwarantuje, że napiszesz dobre testy. W rzeczywistości moją początkową predyspozycją było pisanie prostych testów, które generowały prosty kod. Naprawdę prosty kod, który zawierał kilka abstrakcji. Naprawdę proste testy, które były powiązane z wewnętrznymi elementami klasy. A kiedy masz już kilka tysięcy bitowych testów, na pewno nie czujesz, że poruszasz się szybciej, gdy musisz zmienić ich setkę, aby zmienić kod w celu wykorzystania bardzo ważnej koncepcji domeny X.

Zapaliło się dla mnie światło - TDD nie jest umiejętnością testową. To umiejętność projektowania. Może tylko prowadzić cię do dobrego, prostego, wykonalnego kodu, ćwicząc i stale zdając sobie sprawę z kierunków projektowania, w które cię poprowadzi. Jeśli piszesz testy dla pokrycia kodu, stworzysz kruche testy. Jeśli piszesz testy, które pomogą Ci zaprojektować swoje abstrakcje, jest to po prostu bardziej rygorystyczny sposób pisania odgórnego kodu. Najpierw zobaczysz kod z perspektywy dzwoniącego, który zachęca cię do ułatwienia mu życia, zamiast odzwierciedlać wewnętrzne elementy klasy na zewnątrz.

Myślę, że TDD jest przydatne, ale nie jestem do tego dogmatyczny. Jeśli te „testy bez wartości” utrudniają konserwację - usuń je! Testy traktuję tak samo jak resztę kodu. Jeśli można go zrefaktoryzować i uprościć, zrób to!

Nie widziałem tego osobiście, ale słyszałem, że niektóre miejsca śledzą zasięg kodu i testy się liczą. Więc jeśli zbieranie danych jest efektem ubocznym TDD, to mogę to również postrzegać jako negatywne. Z entuzjazmem usunę 1000 linii kodu, a jeśli to zdezaktualizuje 20 testów i porzuci mój procent pokrycia kodu, cóż.

Steve Jackson
źródło
7
Przybiliście
4
„Nie widziałem tego osobiście, ale słyszałem, że niektóre miejsca śledzą pokrycie kodu i testy się liczą”. Mieszkałem w takim środowisku i faktycznie żaden kod nigdy nie został wyrzucony, ponieważ spowodowałoby to niepowodzenie testu. Dopóki nie zacząłem debugować rzeczywistych testów, i znalazłem wiele z nich, które miały tak poważne wady, zmuszały kod do generowania niepoprawnych wyników w celu zaliczenia testów. Właśnie wtedy wymyśliłem pytanie: „kto testuje testy”, na które do tej pory nigdy nie miałem zadowalającej odpowiedzi ze strony społeczności TDD. Testy jednostkowe do testów jednostkowych, ktoś?
jwenting
@jwenting - A ta anegdota dość ładnie popiera argument Rei. Odkryłem, że aspekt ochrony przed regresją w TDD jest przesadzony w praktyce, nawet jeśli jest to solidny pomysł w teorii. Testy muszą być utrzymywane na tym samym poziomie co kod produkcyjny, aby działało, i jest to trochę nienaturalne, aby traktować kod nieprodukcyjny w ten sposób - widzę tę samą „zgniliznę kodu” z symulatorami sprzętowymi, generatorami kodów, itd. przez cały czas.
Steve Jackson,
„Naprawdę proste testy, które były powiązane z wewnętrznymi elementami klasy” <- tam jest twój problem. Testuj tylko na interfejsach publicznych. TDD! = UT
Steven A. Lowe 10.02
2
@ StevenA.Lowe - Wiem to teraz, ale 9 lat temu nie było tak jasne :) „TDD nie jest umiejętnością testowania”
Steve Jackson
41

Mam zamiar wyjść tutaj na całość i z brutalną szczerością oświadczam, że to dosłownie rytualna strata czasu. (W większości sytuacji.)

Kupiłem książkę o testowaniu jednostkowym, która również omawiała TDD i chociaż zgadzam się z korzyściami UT, po około stu godzinach próbowania TDD zrezygnowałem z niej z wielu powodów. W pewnym sensie jestem tutaj, ale TDD:

  1. To nie jest lepsza dokumentacja niż prawdziwa dokumentacja.
  2. Nie łapie błędów ani regresji .
  3. Tak naprawdę to nie czyni moich projektów lepszymi niż są, jeśli zastosuję pewne koncepcje programowania funkcjonalnego i kompozycyjności .
  4. To czas, który można lepiej spędzić na przeglądaniu kodu lub polerowaniu dokumentacji i specyfikacji.
  5. Daje menedżerom fałszywe poczucie bezpieczeństwa, gdy widzą listę setek zielonych ikon.
  6. Poprawia wydajność implementacji algorytmów z ograniczonymi mapowaniami wejścia-wyjścia.
  7. Jest niezręczny, ponieważ możesz wiedzieć, co robisz w wyniku TDD, ale nie rozumiesz, dlaczego działa tak dobrze, dlaczego twoje projekty wychodzą tak, jak robią.

Innym problemem jest dyskutowany stopień doskonałości, do którego należy zrobić TDD, aby zrobić to z powodzeniem. Niektórzy twierdzą, że jeśli TDD nie będzie wytrwale wykonywany przez wszystkich w zespole od początku projektu, tylko cierpisz. Inni twierdzą, że nikt nigdy nie robi TDD według książki. Jeśli oba są prawdziwe, oznacza to, że praktykujący TDD cierpią, niezależnie od tego, czy zdają sobie z tego sprawę, czy nie.

Oczywiście, jeśli argumentuje się, że robiąc rzeczy w sposób podobny do TDD, dojdziesz do projektów, które mogą łatwo współpracować z TDD, cóż, istnieją znacznie szybsze sposoby na osiągnięcie tego - a mianowicie poprzez studiowanie koncepcji składalność. Istnieje wiele zasobów, nawet rygorystycznych teorii matematycznych (głównie w programowaniu funkcjonalnym, ale także w innych dziedzinach). Dlaczego nie poświęcić całego czasu na naukę TDD ?

Kulturowo, TDD wykazuje objawy bycia praktyką rytualną. Jeździ na poczuciu winy; zachęca do procedury ponad zrozumienie; zawiera mnóstwo doktryn i haseł („sfałszuj go, dopóki go nie sprawisz” jest naprawdę dość niepokojący, jeśli spojrzysz na to obiektywnie). Definicja słowa „rytuał” w Wikipedii jest dość trafna:

W psychologii termin rytuał jest czasem używany w sensie technicznym dla powtarzającego się zachowania systematycznie stosowanego przez osobę w celu zneutralizowania lub zapobiegania lękowi; jest to objaw zaburzenia obsesyjno-kompulsyjnego.

Rei Miyasaka
źródło
Bardzo interesująca perspektywa dotycząca rytuału. W niektórych kręgach można również odnieść wrażenie, że zaangażowanie programisty w jego rzemiosło ocenia się wyłącznie jako proporcjonalne do jego przestrzegania TDD.
yalestar
Powiedziałbym, że w niektórych sytuacjach może poprawić projekt, ale głównie wtedy projekt musi być bardzo modułowy z bardzo dobrze zdefiniowanym i łatwym w użyciu interfejsem publicznym. W takich przypadkach napisanie testów przed wdrożeniem samej biblioteki może pomóc w wyeliminowaniu błędów w interfejsie publicznym, a także wymusić tę modułowość.
jwenting
8
@jwenting Ludzie robią TDD, ponieważ nie wiedzą, co sprawia, że ​​konstrukcja jest modułowa, więc nigdy nie mogą zdjąć 35-calowych kół treningowych ze swoich 40-calowych motocykli. Wykonanie projektu modułowego jest zawsze wykonalnym zadaniem, jeśli rozumiesz pojęcia, ponieważ każdy dylemat w twoim projekcie będzie miał rozsądny rozmiar ze względu na fakt, że w swojej koncepcji jest w trakcie przekształcania się w modułowy. Nie zgadzam się, że TDD skutecznie wymusza modułowość, ale nie zgadzam się, że trzeba zmusić do tworzenia projektów modułowych. Modułowa konstrukcja to doskonała umiejętność do nauczenia się.
Rei Miyasaka,
@jwenting Jeśli chodzi o użyteczność interfejsów publicznych, istnieją dwie szkoły myślenia wśród praktyków TDD w tej sprawie, z których obie są niepożądane: upublicznij wszystko, aby można je było przetestować lub pozostaw rzeczy prywatne, jeśli i tak nie powinny być testowane . Pierwsze z nich wymusza ujawnianie niepotrzebnych szczegółów implementacji użytkownikom końcowym (które potencjalnie mogą być niewłaściwie wykorzystywane lub wykorzystywane), a drugie wymusza testy jednostkowe bliżej testów systemowych. Oczywiście możesz użyć narzędzi do testowania jednostek, aby uzyskać dostęp do szeregów prywatnych, ale nie ma to większego sensu w TDD.
Rei Miyasaka,
1
@Kall W tym wywiadzie mówi „około 15 do 35% więcej czasu” - nie tylko 15%, jak go zacytowałeś. Badanie obejmuje również tylko Java / C ++ / C # (prawdopodobnie C # 2, biorąc pod uwagę datę) - wszystkie języki tego samego imperatywnego paradygmatu OOP. Z pewnością jestem o ponad 15% i prawdopodobnie o ponad 35% bardziej produktywny w języku funkcjonalnym (a nawet w języku C # 3), i produkuję znacznie mniej błędów, pisząc bezstanowy, składalny kod - te same rodzaje błędów, które poprawia testowanie, ponieważ obie rzeczy rozwiązują dokładnie te same typy problemów. Innymi słowy, oczywiście, 60–90% redukcja błędów, ale w porównaniu z czym ?
Rei Miyasaka,
18

Aby dodać, innym problemem związanym z TDD, który zauważyłem, jest:

TDD powoduje niezamierzone przesunięcie uwagi zespołu programistów z Kodeksu Jakości na Przypadki Testowe i Pokrycie Kodu! Osobiście nie lubiłem TDD, ponieważ czyni mnie mniej kreatywnym i sprawia, że ​​tworzenie oprogramowania jest nudnym procesem mechanicznym ! Testy jednostkowe są przydatne, gdy są rozsądnie stosowane, ale stają się ciężarem, gdy traktuje się cel rozwoju oprogramowania.

Znam faceta, który jest menedżerem i jest technicznie nudny, gdy miał obsesję na punkcie TDD. Było to dla niego tak magiczne, że wierzył, że przyniesie magiczne rozwiązania wszystkich problemów w jego słabo skonstruowanym oprogramowaniu z najmniejszym możliwym do utrzymania kodem. Nie mówiąc już o tym, co się stało z tym projektem - poniósł porażkę w jego rękach, podczas gdy wszystkie jego testy były zielone. Wydaje mi się, że TDD pomógł mu uzyskać jakieś informacje statystyczne, takie jak „99/100 moich przypadków jest zielonych” itp. To był powód jego obsesji, ponieważ nigdy nie byłby w stanie ocenić jakości ani zaproponować ulepszeń w projekcie.

Kiran Ravindranathan
źródło
2
Brzmi jak piekło PHB! Przypomina mi to firmy, które wprowadzają schematy premiowe - oczywiście dzieje się tak, że programiści zamiast skupiać się na kodzie jakości, koncentrują się na spełnianiu wymagań premii. Nieuchronnie dostajesz gorszy kod. (Jest tu również analogia do obecnego kryzysu bankowego :-))
TrojanName
TDD nie jest techniką zarządzania projektami, więc nic dziwnego, że twój niedoszły menedżer zawiódł. Z drugiej strony nie czuję się mniej kreatywny, a nawet bardziej kreatywny, ponieważ opracowywanie testów automatycznie daje mi inne spojrzenie na mój kod. Zgadzam się jednak, że głównym celem musi być kod produkcyjny, a testy nie powinny popsuć dobrej architektury oprogramowania.
Alex
Zakres kodu jest przedmiotem testów jednostkowych, a nie TDD. TDD dba tylko o funkcje i testy za pośrednictwem publicznych interfejsów.
Steven A. Lowe,
14

Moje główne negatywne doświadczenia to próba użycia TDD do edycji kodu innego programisty, który nie ma żadnych testów lub bardzo, bardzo podstawowych testów integracyjnych. Kiedy idę dodać funkcję lub naprawić problem z tym kodem; Wolałbym najpierw napisać test (metoda TDD). Niestety kod jest ściśle powiązany i nie mogę niczego przetestować bez dużej ilości refaktoryzacji.

Refaktoryzacja i tak jest świetnym ćwiczeniem, ale jest wymagane, aby wprowadzić kod w stan testowalny. Po tym kroku nie mam czeków i sald, aby sprawdzić, czy moje zmiany coś zepsuły; po uruchomieniu aplikacji i sprawdzeniu każdego przypadku użycia.

Z drugiej strony dodawanie funkcji / naprawianie błędów do projektu TDD staje się bardzo proste. Z natury kod napisany za pomocą TDD jest zwykle dość oddzielony od małych kawałków do pracy.

W każdym razie TDD jest wytyczną. Postępuj zgodnie z nim, aż osiągniesz maksymalną skuteczność. Przyzwoity zasięg testu i oddzielony kod, dobrze napisany kod.

Sheldon Warkentin
źródło
1
Jeśli trudno jest napisać testy jednostkowe, ogólnie występują problemy z rozdzieleniem problemów. Nie uważam tego za winę TDD, jeśli cokolwiek to szybko uwidacznia te problemy.
Tom Kerr
7
To nie jest negatywne doświadczenie z TDD, to negatywne doświadczenie z kiepskim kodem.
Rei Miyasaka,
13

Doświadczyłem, że czasami polegam zbytnio na moich testach, jeśli chodzi o konstrukcję systemu. W zasadzie mam zbyt mało szczegółów na temat drobiazgowej implementacji, aby cofnąć się o krok i spojrzeć na większy obraz. Często skutkuje to niepotrzebnie złożonym projektem. Wiem, że powinienem zmienić kod, ale czasami mam wrażenie, że mogę zaoszczędzić dużo czasu, robiąc krok wstecz.

Biorąc to pod uwagę, jeśli masz ramy takie jak szyny, gdzie twoje decyzje architektoniczne są bardzo ograniczone, problemy te w zasadzie nie istnieją.

Innym problemem jest to, gdy ślepo ufasz swoim testom. Prawda jest - jak każdy inny kod - twoje testy również mogą zawierać błędy. Dlatego bądź tak krytyczny wobec swoich testów, jak i wobec implementacji.

sebastiangeiger
źródło
2
Może powinieneś napisać kilka testów do swoich testów! : p ...... I Kid, I Kid
Aren
+1 +1 +1 +1 (gdybym miał 3 konta zastępcze). Zdanie nr 2 jest bardzo wnikliwe i wolne od uprzedzeń potwierdzających TDD, które jest zdecydowanie zbyt powszechne.
tgm1024
11

Jako wielki fan TDD czasami dostrzegam te wady

  • Pokusa, by napisać zbyt wiele testów ze względu na prawie 100% pokrycia kodu. Moim zdaniem pisanie testów nie jest konieczne
    • dla prostych pobierających / ustawiających właściwości
    • w każdym przypadku zgłoszenia wyjątku
    • który sprawdza tę samą funkcjonalność na różnych warstwach. (Przykład: jeśli masz najmniejszą możliwość sprawdzenia poprawności danych wejściowych dla każdego parametru, nie jest konieczne powtarzanie wszystkich tych testów również przez test integracji)
  • Koszty utrzymania kodu testowego dla podobnych testów, które różnią się tylko nieznacznie (utworzone przez duplikację kodu (inaczej dziedziczenie kopiuj-wklej-wklej)). Jeśli już go masz, możesz łatwo stworzyć podobny. Ale jeśli nie przefakturujesz kodu testowego, eliminując duplikację kodu do metod pomocniczych, możesz potrzebować trochę czasu na naprawę testów, jeśli zmienią się szczegóły implementacji twojego kodu biznesowego.

  • Jeśli jesteś pod presją czasu, możesz ulec pokusie wyeliminowania zepsutych testów (lub ich skomentowania) zamiast ich naprawiania . W ten sposób tracisz inwestycję w testy

k3b
źródło
2
+1: „Pokusa, by napisać zbyt wiele testów ze względu na prawie 100% ochronę kodową.”: Raz wpadłem w tę pułapkę i po spędzeniu tylu godzin na pisaniu wszystkich testów jednostkowych, jedynymi trzema błędami, które znalazłem w moim kodzie były nie jest objęty testami jednostkowymi i można go łatwo znaleźć, debugując kod krok po kroku.
Giorgio
9

Jeszcze nie spotkałem się z więcej niż jednym scenariuszem jako twórca gier, w którym warto było TDD. I w tym przypadku był to fragment kodu, który miał charakter czysto matematyczny i wymagał solidnego podejścia do testowania ogromnej liczby przypadków skrajnych jednocześnie - rzadka potrzeba.

Być może coś kiedyś zmieni zdanie, ale wśród praktyk XP pomysł bezlitosnego refaktoryzowania i rozwijania własnej formy kodu jest o wiele ważniejszy i prowadzi do największej wydajności dla mnie, por. cytat z artykułu Jamesa Newkirka :

Prostota - „Jaka jest najprostsza rzecz, która może działać?”
Wiadomość jest bardzo jasna. Biorąc pod uwagę dzisiejsze wymagania, zaprojektuj i napisz swoje oprogramowanie. Nie próbuj przewidywać przyszłości, pozwól jej się rozwijać. Często robi to w bardzo nieprzewidywalny sposób, czyniąc przewidywanie kosztem, który często jest zbyt drogi, aby na to pozwolić ”.

Wspomniane przeze mnie koncepcje odwagi i zacieśniania pętli informacji zwrotnej są również, moim zdaniem, kluczowe dla wydajności.

Inżynier
źródło
9
Problem polega na tym, że bez testów jednostkowych skąd wiesz, że bezlitosne refaktoryzowanie skutkuje kodem, który robi to samo? Z mojego doświadczenia wynika, że ​​w zależności od problemu napisanie testu + kodu może zająć mi mniej czasu niż samo napisanie kodu! Powód sprowadza się głównie do tego, że w przypadku niektórych problemów mogę wypróbować ponownie czynnik i przetestować automatycznie znacznie szybciej niż mógłbym przetestować go ręcznie, co może znacznie zwiększyć prędkość iteracji.
Mark Booth,
6
W przypadku gier bardzo często można zobaczyć wyniki. Jeśli można je zobaczyć i wyglądać wystarczająco dobrze, zostaną zaakceptowane, ponieważ gra ma być subiektywnym doświadczeniem. Z drugiej strony biorąc np. Diablo 2 jako przykład, liczba błędów we wzorach bojowych pokazała, gdzie TDD przyniósłoby ogromną wartość i zaoszczędziłoby im ogromnej ilości pracy na łatach. W przypadku bardzo dobrze zdefiniowanych problemów, takich jak rozwiązywanie równań i gdy nie można ich ocenić na podstawie wyników wizualnych w czasie wykonywania, TDD jest koniecznością, aby zapewnić poprawność. Ale to niewielka część kodu w większości gier.
Inżynier
Warto również wspomnieć, że ze względu na szybkość wykonywania symulacji lepiej jest oglądać zmienne w czasie rzeczywistym, na ekranie, gdy gra się w symulacji, niż siedzieć z milionowymi wierszami plików logów, aby przejrzeć fakt.
Inżynier
3
Z mojego doświadczenia wynika, że ​​testy jednostkowe znacznie ułatwiają refaktoryzację .
Tom Kerr
1
@Nick Dużym problemem w branży gier są terminy, które zawsze są - „musieliśmy dostarczyć pół roku temu”. Myślę, że czas gra przeciwko testom jednostkowym w środowiskach o ograniczonym czasie. W niektórych przypadkach decyzja nie jest poprawna, ale w większości przypadków wysyłka bez testu jest szybsza. Zależy, naprawdę zależy ...
Koder
7

Moje negatywne doświadczenia TDD, choć mogą być ograniczone, po prostu wiem, od czego zacząć! Na przykład postaram się zrobić coś TDD i albo nie mam pojęcia, od czego zacząć testowanie trywialnych rzeczy (czy mogę nowy Fooobiekt, przekazać go Quuxdo Bazitp.) Testy, które niczego nie testują ) lub jeśli próbuję zaimplementować go w istniejącym projekcie, stwierdzę, że musiałbym przepisać różne klasy, aby móc z nich korzystać w TDD. Efektem końcowym jest to, że szybko porzucam całkowicie to pojęcie.

Prawdopodobnie nie pomaga to tak często, że jestem jedyną osobą w całej firmie, która wie, co to jest testowanie jednostkowe (TDD lub inne) i dlaczego jest to dobra rzecz.

Wayne Molina
źródło
1
To gdzie ramy drwiące przyjść. Utwórz wystąpienie Fooz Mock obiektów zamiast Quuxi Bazbezpośrednio, można wywołać funkcję chcesz przetestować, a następnie sprawdzić, czy mocks nazywano z funkcjami można się spodziewać. Obiekty pozorne to technologia aktywująca, która pomaga rozdzielić jednostki i umożliwić ich testowanie. Dlatego singletony są złe, ponieważ często nie można ich po prostu wyśmiewać . * 8 ')
Mark Booth,
7

Fanatycy TDD.

Dla mnie to tylko jedna z długiej linii religijnych wariatów pukających do moich drzwi, próbujących udowodnić, że mój sposób robienia rzeczy jest nieodwracalnie zepsuty, a jedyną drogą do zbawienia jest Jezus, Powrót Kenta lub Testowanie Jednostek.

IMO, ich największym kłamstwem jest to, że TDD doprowadzi cię do zbawienia lepszego projektu algorytmu. Zobacz słynny solver Soduku napisany w TDD: tutaj , tutaj , tutaj , tutaj i tutaj

I porównaj to solver sudoku Peter Norvig wykonany nie przy użyciu TDD, ale przy użyciu staromodnej inżynierii: http://norvig.com/sudoku.html

Cesar Canassa
źródło
Słuchaj, moglibyśmy się o to kłócić. Ale mam o wiele za dużo pracy, odkąd ukończyłem uniwersytet Fullsail z dyplomem z projektowania gier. Na podstawie moich kursów i mojej bardzo wymagającej pracy mogę powiedzieć, że TDD naprawdę przebija szalony rozwój line-by-line (brak projektu) leniwych programistów. Posłuchaj, nie powiedziałbym tego, ale to prawda: większość programistów, którzy wybrali się na normalny program CS na uniwersytet, przeważnie nie ukończyła studiów, niewielu, którzy w przeważającej części nie przestawili się na tworzenie oprogramowania, a na dodatek wielu z nich ledwo sobie radzi , linia po linii. Uniwersytet Fullsail ma
Zombie
kompletny kurs samego programowania opartego na testach, który naprawdę prowadzi programistów na właściwą ścieżkę (w przeciwieństwie do implementacji listy połączonej w c ++).
Zombie
Linki są zepsute, koleś!
lmiguelvargasf
To wiele lat później, ale @Zombies zajrzyj do „Stronniczości bierzmowania”. Wiele z tego, czego wszyscy uczymy w CS na studiach, należy właśnie do tej kategorii. Rzuć okiem na odrzucenie „magicznych liczb” i szalone
walenie
Lol, człowieku, trollowałem ... Napisałem to tak dawno temu, że zapomniałem o tym małym klejnocie.
Zombie
5

Jeśli użyjesz TDD z tych „fanatycznych” artykułów, błędnie poczujesz, że w twoim oprogramowaniu nie ma błędów.

Dainius
źródło
1
Czy możesz poczuć coś innego niż świadomość, że dla danego zestawu danych wejściowych oprogramowanie zwraca dany zestaw danych wyjściowych?
tak długo, jak rozumiesz, że tdd jest procesem rozwoju, a nie złotą regułą do rozwiązywania jakichkolwiek problemów, jest OK. Ale większość ludzi, którzy proponują użycie tego procesu, zapomniała, że ​​jest to proces rozwoju i jak każdy inny proces ma jasną i ciemną stronę. Mówią wszystkim, że jeśli będziesz korzystać z TDD, będziesz mieć wolne oprogramowanie od błędów, ponieważ użyjesz testu, aby objąć każdą funkcję. I zwykle nie jest to właściwe. Najlepszym sposobem będzie test dla każdego przypadku (lub przynajmniej funkcji), ale testy to programy (które mają błędy) i to tylko testy czarnej skrzynki.
Dainius
4

TDD ma pewne zalety:

  • Skoncentruj się na tym, jak wywołać swój kod i czego się spodziewać w pierwszej kolejności (pisząc najpierw test), zamiast skupiać się na rozwiązaniu problemu, a następnie wkleić połączenie z aplikacji. Modułowość ułatwia kpiny i zawijanie.
  • Testy zapewniają, że Twój program działa tak samo przed refaktoryzacją i po nim. Nie oznacza to, że twój program jest wolny od błędów, ale że działa w ten sam sposób.

TDD dotyczy inwestycji długoterminowych. Wysiłek opłaca się, gdy przejdziesz do trybu konserwacji aplikacji, a jeśli aplikacja nie planuje osiągnąć tego punktu, możesz nigdy nie odzyskać inwestycji.

Uważam cykl TDD czerwono-zielony z krokami dziecka podobnymi do listy kontrolnej samolotu. Sprawdzanie wszystkich rzeczy w samolocie przed startem jest denerwujące i żmudne, zwłaszcza jeśli jest to banalnie proste (kroki dziecka TDD), ale stwierdzono, że zwiększa bezpieczeństwo. Oprócz sprawdzenia, czy wszystko działa, zasadniczo resetuje płaszczyznę . Innymi słowy, samolot jest restartowany przed każdym startem.

1249
źródło
3
Punkt 2 korzyści można również osiągnąć za pomocą prostych testów jednostkowych bez podejścia TDD. Korzyść 1, którą powinieneś zrobić. (Koncentrując się na interfejsie API) Nadal całkowicie możliwe jest utworzenie kiepskiego interfejsu API za pomocą TDD, ale tak, masz gwarancję, że będzie on działał (w przypadku testów pisemnych).
Steven Jeuris,
2
Pytanie nie dotyczyło korzyści płynących z TDD. Jest już wiele innych pytań na ten temat.
Aaronaught
1
@aronaught, zwracam się do jego punktów bólowych.
Odpowiedzi powinny odpowiedzieć na pytanie .
Aaronaught
1
@aronaught, a następnie napisz niektóre z nich.
3

Moje negatywne doświadczenia związane z TDD są czymś, co odczuwam w przypadku wielu nowych i hiper-rzeczy. W rzeczywistości podoba mi się TDD, ponieważ zapewnia on poprawność mojego kodu, a co ważniejsze: mogę rozpoznać testy zakończone niepowodzeniem po dodaniu nowego kodu lub dowolnego rodzaju refaktoryzacji.

W TDD denerwuje mnie fakt, że istnieje wiele zasad lub wytycznych na ten temat. Ponieważ jest to wciąż dość nowe zjawisko, większość z nas ma doświadczenie jako początkujący w TDD. Więc to, co działa dobrze dla niektórych z nas, może nie działać dla innych. Chcę powiedzieć, że nie ma prawdziwego „niewłaściwego lub właściwego” sposobu wykonania TDD: Jest taki sposób, który działa dla mnie - i dla mojego zespołu, jeśli go mam.

Tak długo, jak piszesz testy - przed kodem produkcyjnym lub po nim tak naprawdę nie ma znaczenia IMHO - nie jestem pewien, czy testowanie naprawdę oznacza, że ​​musisz przestrzegać wszystkich wytycznych, które są teraz podane, ponieważ nie zostały jeszcze udowodnione idealne rozwiązanie do codziennej pracy. Jeśli znajdziesz lepszy sposób na pisanie testów, powinieneś opublikować go na blogu, przedyskutować tutaj lub napisać o nim artykuł. Więc za około dziesięć lat moglibyśmy podzielić się wystarczającym doświadczeniem, aby móc stwierdzić, która reguła TDD może być uznana za dobrą, czy nie w określonej sytuacji.

Alex
źródło
+1 Doskonały komentarz. To naprawdę nie musi być ani jeden prawdziwy sposób, ani żaden sposób.
niepythonic
3

Nieraz napisałem kod, który odrzuciłem następnego dnia, ponieważ był niezdarny. Uruchomiłem ponownie z TDD i rozwiązanie było lepsze. Więc nie miałem zbyt wiele na linii negatywnego doświadczenia TDD. Jednak powiedziawszy to, spędziłem czas zastanawiając się nad problemem i wymyślając lepsze rozwiązanie poza przestrzenią TDD.

użytkownik23356
źródło
1
Zwykle druga próba daje więcej wglądu w problem niż pierwsza próba, TDD lub nie.
wobbily_col
3

Odkryłem, że TDD działa słabo, jeśli chodzi o systemy wschodzące. Jestem programistą gier wideo, a ostatnio wykorzystałem TDD do stworzenia systemu, który wykorzystuje wiele prostych zachowań do stworzenia realistycznie wyglądającego ruchu dla bytu.

Na przykład istnieją zachowania odpowiedzialne za odsuwanie cię od niebezpiecznych obszarów różnego rodzaju i takie, które są odpowiedzialne za przenoszenie cię w interesujące obszary różnych typów. Połączenie wyników każdego zachowania tworzy końcowy ruch.

Elementy systemu zostały zaimplementowane z łatwością, a TDD przydał się tutaj do określenia, za co powinien odpowiadać każdy podsystem.

Miałem jednak problemy, gdy chodziło o określenie interakcji między zachowaniami, a co ważniejsze, w jaki sposób zachodzą one w czasie. Często nie było właściwej odpowiedzi i chociaż moje wstępne testy zakończyły się pomyślnie, QA mogła nadal znajdować przypadki, w których system nie działał. Aby znaleźć właściwe rozwiązanie, musiałem powtarzać kilka różnych zachowań, a jeśli za każdym razem aktualizowałem testy, aby odzwierciedlić nowe zachowania, zanim sprawdziłem, czy działają w grze, być może raz po raz wyrzucałem testy. Więc usunąłem te testy.

Powinienem być może mieć silniejsze testy, które uchwyciły odkryte przypadki QA, ale kiedy masz taki system, który opiera się na wielu systemach fizyki i rozgrywki, a masz do czynienia z zachowaniami z czasem, staje się to trochę koszmar dokładnie sprecyzować, co się dzieje.

Niemal na pewno popełniłem błędy w moim podejściu i, jak powiedziałem, dla wnętrzności systemu TDD działało znakomicie, a nawet wspierało kilka optymalizujących refaktorów.

tenpn
źródło