Czy warto przeprowadzać testy jednostkowe lub rozwój oparty na testach?

48

Mój zespół w pracy przenosi się do Scrum, a inne zespoły zaczynają opracowywać testy oparte na testach jednostkowych i testach akceptacji użytkownika. Lubię UAT, ale nie sprzedaje się na testach jednostkowych do programowania testowego lub programowania testowego w ogóle.

Wygląda na to, że pisanie testów jest dodatkową pracą, daje ludziom siłę do pisania, gdy piszą prawdziwy kod, i może nie być zbyt często skuteczne.

Rozumiem, jak działają testy jednostkowe i jak je napisać, ale czy ktoś może twierdzić, że to naprawdę dobry pomysł i wart wysiłku i czasu?

Czy jest coś, co czyni TDD szczególnie dobrym dla Scrum?

Owen Johnson
źródło
27
Jeśli chcesz się upewnić, że twoje oprogramowanie często się psuje, jest mniej więcej całkowicie nie do utrzymania i należy je wymienić, zanim faktycznie będzie gotowe do produkcji; wtedy radzę zrezygnować z testów jednostkowych i nigdy nie poświęcać czasu na naukę TDD.
Dawood mówi, że przywraca Monikę
3
Pomyśl o życzeniu / potrzebie refaktora. Czy byłbyś bardziej pewny faktycznego przeprowadzania refaktoryzacji (dowolnej wielkości) z kompleksowym zestawem testów jednostkowych lub bez, aby złapać cię, gdy przypadkowo coś zepsułeś?
Marjan Venema
2
„Daje ludziom siłę, gdy piszą prawdziwy kod”? Czy nie można opisać większości najlepszych praktyk w ten sposób?
user16764
4
@DavidWallace: Jest to problem niekompetentnych programistów, a nie brak TDD. Co więcej, nawet jeśli TDD jest szeroko stosowane, daje zerową gwarancję, że dokonana zmiana niczego nie zepsuje.
Koder
6
@NimChimpsky: Nie mam negatywnego nastawienia do TDD, po prostu nie podążam za hype. Ma to swoje pozytywne i negatywne strony. Jednym z nich jest fałszywe poczucie bezpieczeństwa.
Koder

Odpowiedzi:

68

Krótka odpowiedź: absolutnie pozytywnie.

Długa odpowiedź: testy jednostkowe to jedna z najważniejszych praktyk, na które staram się wpływać w miejscu pracy (duży bank, transakcje walutowe). Tak, to dodatkowa praca, ale ta praca się zwraca. Zautomatyzowane testy jednostkowe nie tylko pomagają w rzeczywistości wykonać kod, który piszesz i oczywiście weryfikują twoje oczekiwania, ale działają również jako rodzaj psa stróżującego na przyszłe zmiany, które możesz wprowadzić ty lub ktoś inny. Awaria testowa nastąpi, gdy ktoś zmieni kod w niepożądany sposób. Myślę, że względna wartość testów jednostkowych spada w korelacji z poziomem oczekiwanej zmiany i wzrostu bazy kodu, ale wstępna weryfikacja tego, co robi kod, sprawia, że ​​warto, nawet tam, gdzie oczekiwana zmiana jest niska. Wartość testu jednostkowego zależy również od kosztu wad. Jeżeli koszt (gdzie koszt to strata czasu / pieniędzy / reputacji / przyszłego wysiłku) wady wynosi zero, wówczas względna wartość testu również wynosi zero; jednak prawie nigdy tak nie jest w środowisku komercyjnym.

Zasadniczo nie zatrudniamy już osób, które nie rutynowo tworzą testów jednostkowych w ramach swojej pracy - jest to coś, czego oczekujemy, jak pojawienie się każdego dnia. Nie widziałem analizy kosztów i korzyści posiadania testów jednostkowych (ktoś może wskazać mi jeden), jednak z doświadczenia mogę powiedzieć, że w środowisku komercyjnym warto udowodnić, że kod działa w dużym, ważnym systemie . Pozwala mi także lepiej spać w nocy, wiedząc, że kod, który napisałem, działa pewnie (do pewnego poziomu), a jeśli się zmieni, ktoś zostanie ostrzeżony o wszelkich nieoczekiwanych skutkach ubocznych z powodu zepsutej kompilacji.

Rozwój oparty na testach, moim zdaniem nie jest podejściem testowym. W rzeczywistości jest to podejście / praktyka projektowa, której wynikiem jest działający system i zestaw testów jednostkowych. Nie podoba mi się ta praktyka, ponieważ jest to umiejętność dość trudna do rozwinięcia i doskonalenia. Osobiście, jeśli buduję system i nie mam jasnego pojęcia, jak to będzie działać, zastosuję TDD, aby pomóc mi znaleźć drogę w ciemności. Jeśli jednak zastosuję istniejący wzór / rozwiązanie, zazwyczaj tego nie zrobię.

Wobec braku matematycznego dowodu na to, że pisanie testów jednostkowych ma sens, zachęcam do wypróbowania go przez dłuższy czas i samodzielnego czerpania korzyści.

rupjones
źródło
5
Chciałbym dodać, że testy jednostkowe sprawiają, że myślisz o projekcie interfejsu. Gdy przejdziesz do części, w której myślisz „jak mogę testować prywatne metody jednostkowe?”, Wiesz, że prawdopodobnie twój interfejs jest nieprawidłowy.
TC1
1
„Zachęcam do wypróbowania go przez dłuższy czas i samodzielnego czerpania korzyści”. Wystarczyło mi, że raz spróbowałem, korzyści wydawały się oczywiste.
NimChimpsky
1
+1 za „Zasadniczo nie zatrudniamy już osób, które nie rutynowo tworzą testów jednostkowych w ramach swojej pracy”. Niedawno musiałem odrzucić kandydata, który pośród innych niedociągnięć stanowczo ogłosił, że nie lubi pisać testów automatycznych, ponieważ są stratą czasu i sam może przetestować kod.
pt
4
nie można udowodnić, że nietrywialny kod działa w jakikolwiek odpowiedni sposób, za pomocą automatycznych testów. Za pomocą testów automatycznych możesz tylko udowodnić, że kod pozytywnie przechodzi testy - jeśli testy obejmują 100% przypadków użycia, prawdopodobnie masz swój „określony poziom”, ale to nie znaczy, że kod „działa”. Aby mieć prawdziwą możliwość udowodnienia, potrzebujesz en.wikipedia.org/wiki/Formal_verification - jako takiego używasz tutaj niepoprawnego terminu „możliwe do udowodnienia”.
vaxquis
1
@vaxquis tak, masz całkowitą rację co do użycia terminu dowód. Założę się jednak, że obecność testów (lub praktyka TDD) jest lepszym dowodem na działający system niż brak testów.
rupjones
16

Błędy znalezione wcześniej są tańsze do naprawienia niż błędy znalezione później. TDD pomaga zweryfikować poprawność systemu. Inwestujesz trochę więcej z góry, ale odzyskasz go później. Wykres jest nieco przesadzony, ale dobrze pokazuje ten pomysł.

wprowadź opis zdjęcia tutaj

Źródło obrazu

Martin Wickman
źródło
Co rozumiesz przez tradycyjny ? Coś, co nie jest TDD?
Giorgio
Nie wydaje się, aby ten wykres opierał się na prawdziwych statystykach, przedstawia jedynie doświadczenie jednej osoby, która napisała ten wpis na blogu w 2006 roku. Nie twierdzę, że jest to całkowicie błędne, ale rzeczywistość jest o wiele bardziej skomplikowana.
Doc Brown
9

Czy warto poświęcić czas na testy jednostkowe lub rozwój oparty na testach?

Tak to robi . Wujek Bob (Robert C Martin) powiedział w prezentacji;

Aby programista udowodnił, że jego kod działa lepiej, napisać test i przejść go niż krzyczeć, śpiewać lub tańczyć.

A ponieważ nie zamierzasz usuwać testu, dopóki test jest pozytywny, masz pewność, że funkcjonalność działa - problemy z regresją zostały rozwiązane.

Napisano na nim wiele rzeczy,

  1. Jesteś odpowiedzialny za uruchomienie tej funkcji. Napisz test. Po prostu to zrób.
  2. Kiedy zastąpić testy jednostkowe testem integracyjnym

Czy SCRUM, testy jednostkowe i TDD są powiązane?

Wkrótce, gdy będziesz mistrzem Unit testing, będziesz blisko TDD. SCRUM nie ma z tym nic wspólnego, ale jak mówią, świetne rzeczy dobrze się mieszają, te techniki tworzenia oprogramowania składają się na doskonały stos , jeśli jeszcze go nie wypróbowałeś, spróbuj.

Czy jest coś, co czyni TDD szczególnie dobrym dla SCRUM?

Jak powiedziałem powyżej , stanowią dobrą kombinację ; Jeśli dodasz do tego testy automatyzacji, będzie to bardziej wyjątkowe .

ManuPK
źródło
8

Wygląda na to, że pisanie testów jest dodatkową pracą, daje ludziom siłę do pisania, gdy piszą prawdziwy kod, i może nie być zbyt często skuteczne.

Testowanie jednostkowe ma wartość jako kula. Wspiera wysiłki programistyczne, umożliwiając zmianę implementacji bez obawy, że aplikacja przestanie działać zgodnie z wymaganiami. Testy jednostkowe są również czymś więcej niż kulą, ponieważ zapewniają narzędzie, dzięki któremu można sprawdzić, czy implementacja spełnia wymagania.

Wszystkie testy, czy to testy jednostkowe, testy akceptacyjne, testy integracyjne itd., Są tak skuteczne, jak ludzie, którzy ich używają. Jeśli podejdziesz do pracy niechlujnie, twoje testy będą niechlujne, a twoja implementacja będzie miała problemy. Więc po co zawracać sobie głowę? Niepokoi Cię testowanie, ponieważ musisz udowodnić sobie i swoim klientom, że oprogramowanie działa, i nie ma żadnych problemów, które mogłyby uniemożliwić korzystanie z niego. Tak, testy to zdecydowanie dodatkowa praca, ale to, jak przejdziesz do testowania, określi, ile wysiłku będziesz musiał włożyć w naprawę błędów po wydaniu i ile wysiłku twój kod będzie wymagał zmiany i utrzymania.

Rozumiem, jak działają testy jednostkowe i jak je napisać, ale czy ktoś może twierdzić, że to naprawdę dobry pomysł i wart wysiłku i czasu?

TDD, a właściwie każda metoda, która wymaga napisania testów przed kodowaniem, przyjmuje podejście, które wkładasz w wysiłek wcześniej jako zaliczkę na przyszłe zadłużenie techniczne. W trakcie pracy nad projektem wszystko, co zostanie pominięte lub źle wdrożone, spowoduje większe zadłużenie techniczne w postaci zwiększonych trudności w konserwacji, co bezpośrednio wpływa na przyszłe koszty i wymagania dotyczące zasobów. Testowanie z góry zapewnia, że ​​nie tylko starałeś się rozwiązać przyszły dług techniczny, ale także upewniasz się, że kodujesz swoje wymagania w taki sposób, że można je zweryfikować po prostu przez uruchomienie kodu. Najpierw test daje również możliwość sprawdzenia zrozumienia problemu, zanim podejmiesz się rozwiązania problemu w kodzie, i potwierdzi twoje wysiłki związane z implementacją.

To naprawdę sprowadza się do próby maksymalizacji wartości biznesowej twojego kodu. Kod, który jest w dużej mierze nieprzetestowany i trudny w utrzymaniu, jest na ogół tani i szybki w tworzeniu oraz bardzo kosztowny w utrzymaniu przez cały okres użytkowania produktu po wydaniu. Kod, który został dokładnie przetestowany na poziomie jednostki, jest generalnie droższy w tworzeniu, ale kosztuje stosunkowo niewiele, aby utrzymać go przez cały okres użytkowania produktu po wydaniu.

Czy jest coś, co sprawia, że ​​TDD jest szczególnie dobry dla SCRUM?

TDD nie jest szczególnie dobre dla żadnej konkretnej metodologii. To po prostu narzędzie. Praktyka, którą możesz zintegrować z procesami programistycznymi, aby pomóc Ci osiągnąć określone wyniki. Tak więc, aby odpowiedzieć na twoje pytanie, TDD jest komplementarny do twojej metody, czy to SCRUM, czy jakiegokolwiek innego podejścia.

S.Robins
źródło
6

Ludzie myślą, że to dodatkowy wysiłek, ponieważ jest to czynność z góry. To, co tracisz na czasie, zyskujesz później.

Moje powody do testowania jednostkowego obejmują również:

Daje ci cel: nie możesz napisać testu, jeśli nie wiesz, co powinno zrobić oprogramowanie. Pomaga to usunąć problemy ze specyfikacji wcześniej niż później.

Daje poczucie postępu.

Ostrzega, jeśli zmiana kodu zmienia dane wyjściowe innych obszarów kodu. To ułatwia refaktoryzację.

Zapewnia dodatkową warstwę dokumentacji (zwłaszcza jeśli odpowiednio skomentujesz swoje testy).

Zachęca do wszelkiego rodzaju dobrych praktyk. Ponieważ testy powinny działać szybko, zachęca to do pisania kodu, który jest odsprzężony i obsługuje kpiny. To wszystko pomaga w refaktoryzacji.

Są też inne omówione w innych postach w tym wątku. Jest tego warte.

Łan
źródło
2

Czy warto przeprowadzać testy jednostkowe lub rozwój oparty na testach?

Zdecydowanie tak (zobacz inne odpowiedzi)

[Czy to] naprawdę dobry pomysł i wart wysiłku i czasu?

  • Tak, jeśli uruchomisz coś nowego (dodaj nowy moduł lub zupełnie nową aplikację)
  • Nie, jeśli istnieje już wiele istniejących kodów, które nie zostały opracowane na podstawie testów i które należy rozszerzyć (starsze wersje).

Moim zdaniem rozwój oparty na testach jest najskuteczniejszy, jeśli napiszesz testy jednostkowe przed właściwym kodem. w ten sposób kod, który spełnia testy, zostaje wyraźnie oddzielony przy pomocy minimum zewnętrznych odnośników, które można łatwo przetestować.

Jeśli kod już istnieje bez testów jednostkowych, zwykle jest dużo pracy, aby napisać testy jednostkowe później, ponieważ kod nie został napisany dla łatwego testowania.

Jeśli wykonasz TDD, kod będzie można łatwo przetestować.

k3b
źródło
2

Podejdę do tego z drugiej strony. Co się stanie, gdy opracujesz nietrywialną aplikację bez testów jednostkowych? Jeśli masz dobry dział kontroli jakości, jedną z pierwszych rzeczy, które się wydarzy, jest to, że zauważysz dużą liczbę zgłoszonych problemów. Dlaczego, ponieważ nie przetestowałeś tego, co zrobiłeś i zakładałeś, że to zadziała, a ponieważ nie przywiązywałeś tak dużej uwagi do wymagań, a Twoja aplikacja ich nie spełnia. Ups z powrotem do tablicy kreślarskiej, aby przepisać i naprawić. Teraz wprowadziłeś poprawki i znalazłeś zupełnie nowy zestaw problemów, ponieważ nie miałeś sposobu, aby sprawdzić, czy Twoje poprawki nie wpłynęły na nic innego, zanim przeszedłeś do kontroli jakości. Upłynął termin, który minął, a zarząd jest zdenerwowany.

Sytuacja jest gorsza, jeśli nie masz dobrego działu kontroli jakości, ponieważ wtedy użytkownicy znajdą błędy i nie tylko sprawią, że twój szef będzie niezadowolony, może sprowadzić środowisko produkcyjne na kolana, a setki, a nawet tysiące ludzi będzie w stanie przestój podczas naprawy błędów, których zapobiegłoby testowanie jednostkowe. To NIE jest dobry wybór kariery.

Załóżmy teraz, że to podejście kowbojskie trwa przez lata? Teraz każda zmiana, nawet trywialna, wydaje się wywoływać nowe, nieoczekiwane problemy. Nie tylko to, ale wiele rzeczy, które chciałbyś zrobić, aby aplikacja działała lepiej, nie możesz tego zrobić, ponieważ są one zbyt ryzykowne, zbyt drogie lub oba. Więc nakładasz łaty na plastry, dzięki czemu system jest coraz bardziej zawiły, bugger i trudniejszy w użyciu.

Użytkownicy zaczynają kwestionować twoje oszacowania czasu, ponieważ stają się coraz większe i trudno im wytłumaczyć, że system stał się tak skomplikowanym bałaganem, trudno jest znaleźć miejsce, aby wprowadzić zmiany, a jeszcze trudniej upewnić się, że nie zepsuć coś innego.

Pracowałem w takim miejscu, w którym po dziesięciu latach rozwoju praktycznie nic nie chcieliśmy zrobić, aby naprawić prawdziwe problemy, ponieważ nie mogliśmy stwierdzić, która z setek niestandardowych aplikacji klienckich ulegnie awarii. Pierwotni programiści byli bardzo podobni do „testów jednostkowych, nie potrzebujemy żadnych śmierdzących testów jednostkowych”. Każdy, kto za nimi podążał, cierpiał z powodu krótkowzroczności.

Bez testów jednostkowych oprogramowanie jest wadliwe i zajmuje więcej czasu zarówno na początkowy rozwój, jak i na utrzymanie. Dlaczego, u licha, nie chcesz przeprowadzać testów jednostkowych? Czas poświęcony na napisanie testu będzie znacznie krótszy niż czas spędzony na naprawianiu problemów, które powinieneś znaleźć wcześniej (im wcześniej błąd zostanie znaleziony, tym mniej czasu zajmie naprawa) i problemów, których można by całkowicie uniknąć, pisząc testy po pierwsze, co pozwala lepiej zrozumieć wymagania przed rozpoczęciem kodowania.

HLGEM
źródło
1

Cały kod, który piszesz, musi zostać w pewnym momencie przetestowany. Nie chcesz pisać wszystkiego za jednym razem, a następnie nacisnąć przycisk kompilacji i trzymać kciuki. Piszesz i kompilujesz małe bloki i wysyłasz starannie spreparowane dane wejściowe w kodzie, aby sprawdzić, czy robi to, co myślisz. Następnie zazwyczaj usuwasz aparat testowy ad hoc i przechodzisz do następnego komponentu.

Dzięki testom jednostkowym upraszcza ten proces i daje wymówkę, aby utrzymać swoje testy. W ten sposób, jeśli wprowadzisz jakiekolwiek zmiany, które psują rzeczy, które testowałeś w przeszłości, możesz jawnie złapać tę regresję, zamiast pozwalać jej wpływać na inne części twojego kodu. Jest w tym prawdziwa wartość.

Jeśli chodzi o podejście do TDD z czerwono-zielonymi refaktorami, uważam to za nieco nudne. Ale każdemu jego.

tylerl
źródło
1
Dla mojego 2c: Aby dowiedzieć się, czy twoje testy faktycznie działają, musisz zobaczyć, jak kończą się niepowodzeniem, zanim zobaczysz, że zdają. Niestety byłem świadkiem, jak wielu programistów pisze testy, które wydają się działać, ale gdy warunki testowe zostały zmienione, kod nadal przechodzi test, nawet jeśli powinien się nie udać. Jeśli test nie powiedzie się pierwszy, a drugi przejdzie, bardziej prawdopodobne jest, że napisałeś test bez błędu. Jeśli zmodyfikujesz test po zmianie kodu, nie możesz być pewien, że kod jest poprawny. Tak, to nużące, ale ma większą szansę na poprawność. :-)
S.Robins,
0

Przez większość czasu uważam, że programiści są odporni na pomysł pisania testów. Nie chodzi o to, że będą argumentować, że testy nie mają żadnej wartości, ale raczej, że są jedynie środkiem do znalezienia sposobu rozwiązania konkretnego problemu. Zwykle ten problem zmienia się w zależności od kontekstu. Gdy to nastąpi, testy nie będą miały żadnego celu i równie dobrze mogą zostać usunięte. Oto przykład kontekstów, które moi koledzy podali w przeszłości, jak zdecydować, kiedy napisać test, a znajdziesz jedyną możliwą odpowiedź według nich:

  • problemem musi być przykład podręcznika TDD, taki jak stos lub kalkulator
  • trywialny kod nie powinien być testowany (unieważnia poprzedni argument)
  • krytyczny lub trudny kod powinien zostać dokładnie przetestowany (implikowany przez poprzedni argument)
  • testy nie powinny być ściśle powiązane z implementacją, aby umożliwić zamiatanie refaktoryzacji (unieważnia poprzedni argument)
  • testowanie pod kątem skutków ubocznych, takich jak wywoływanie usługi innej firmy o określonej ładowności, nie jest konieczne (więc nie testowanie czarnej skrzynki)

W rzeczywistości istnieje jeden rodzaj testów, który, jak się okazało, jest ogólnie akceptowany i który moim zdaniem jest ostatecznie bezużyteczny. Mianowicie testy oparte na GUI, takie jak użycie selenu, webdriver, watir lub arquillian. W ten sposób otrzymujemy 7-godzinne cykle kompilacji zamiast 5-minutowych cykli kompilacji w moich projektach TDD.

Ci sami deweloperzy zwykle narzekają na wszystkich, jak zły jest kod i jak niekompetentni musieli być poprzedni deweloperzy. Uważają również za niezwykle ważne, aby właściwie zaprojektować tablicę, MS Office lub wiki i dołożyć wszelkich starań, aby ten projekt był aktualny.

To ostatnie sprawiło, że zdałem sobie sprawę, że tacy twórcy są oszustami. Wszyscy wiemy, że każdy dokument projektowy, który nie jest testem jednostkowym, stanie się nieaktualny i nie będzie aktualizowany z powodu ogromnych kosztów utrzymania. W rzeczywistości próbowałem znaleźć dobry sposób na wyrażenie pomysłów projektowych w formacie MS Office, który był użyteczny i czytelny zarówno przed, jak i po napisaniu kodu. Nie udało mi się we wszystkich przypadkach i chociaż są ludzie, którym udaje się stworzyć dokument MS Office, który wydaje się ładny, nigdy tak naprawdę nie znalazłem tych przydatnych.

Masz więc wybór. Możesz projektować i dokumentować, ćwicząc TDD, który jest jedyną znaną i sprawdzoną metodą tworzenia takiej dokumentacji w oparciu o moje 10-letnie doświadczenie programistyczne. Lub możesz przejść do polityki.

Sebastian Gozin
źródło
1
testy nie są dokumentacją. TDD jest dobrą praktyką, ale zbyt wiele razy deweloperzy używają narzędzi auto-gen, które wyrzucają zbyt uproszczone kody testowe. Jeśli masz programistę, który jest na to odporny, zamiast pisać drobiazgowe testy, spróbuj napisać większą uprząż testową, która ćwiczy więcej całego produktu. Uznają to za oczywiście przydatne. Nadal musisz napisać odpowiednią dokumentację, nie da się od tego uciec.
gbjbaanb
@gbjbaanb: jeśli programiści używają narzędzi auto-gen, być może istnieją testy jednostkowe, ale na pewno nie TDD. W TDD powinieneś napisać test przed metodami. Nie można zautomatyzować rusztowania testu metody, która jeszcze nie istnieje. Również dobrze napisane testy to dokumentacja (dokumentacja techniczna dla innych programistów projektu, nie wymagania ani instrukcja użytkownika). Dobrze napisane i utrzymywane testy jednostkowe pokazują, jak metody powinny być testami. A jeśli testy są regularnie sprawdzane i kończą się powodzeniem, są one oczywiście dokładniejsze niż nieaktualna dokumentacja. Nie możesz temu zaprzeczyć.
kriss
unittests może być bardzo dobrą dokumentacją dla programistów, ponieważ pokazują przykłady użycia interfejsu API.
k3b
Chodzi o to, że selen, webdriver itp. Nie wymagają ręcznej kontroli jakości witryny. Nie oszczędzasz więc czasu, usuwając je z procesu kompilacji, ponieważ one same mają oszczędzać czas.
Muhd,