Różnica czasu między opracowaniem z testami jednostkowymi a brakiem testów

132

Jestem deweloperem solo z dość ograniczonym czasowo środowiskiem pracy, w którym czas opracowywania wynosi zwykle od 1 do 4 tygodni na projekt, w zależności od wymagań, pilności lub obu. W danym momencie wykonuję około 3-4 projektów, z których niektóre mają nakładające się na siebie terminy.

Oczekuje się, że ucierpi jakość kodu. Nie mam również formalnych testów; zwykle sprowadza się do przejścia przez system, dopóki się nie zepsuje. W rezultacie znaczna liczba błędów ucieka do produkcji, którą muszę naprawić, a to z kolei opóźnia moje inne projekty.

W tym momencie pojawia się testowanie jednostkowe. Prawidłowe wykonanie powinno ograniczyć błędy, nie mówiąc już o tych, które uciekają do produkcji. Z drugiej strony pisanie testów może zająć sporo czasu, co nie brzmi dobrze w przypadku projektów o ograniczonym czasie, takich jak mój.

Pytanie brzmi: ile różnicy czasu napisałby kod testowany jednostkowo w stosunku do kodu niepoddanego testowi i jak zmienia się ta różnica czasu w miarę rozszerzania zakresu projektu?

Revenant
źródło
Komentarze nie są przeznaczone do rozszerzonej dyskusji; ta rozmowa została przeniesiona do czatu .
wałek klonowy
8
Rozwiązujesz zły problem. Jesteś zbyt zajęty i nie masz wsparcia w zarządzaniu projektami. Oceniasz nakład projektu? Czy rezerwujesz 20% swojego czasu na poprawki błędów, spotkania i inne zadania niekodujące? Ile nadgodzin pracujesz?
Tony Ennis
20
Czy zdajesz sobie sprawę, że zasadniczo mówisz „mam czas, aby zrobić to dwa razy, ale nie czas, aby zrobić to we właściwy sposób”?
RubberDuck
5
@RubberDuck w rzeczywistości jest punkt na krzywej złożoności projektu mierzony jako Czas do zapisu w porównaniu do Czasu do przetestowania, gdzie „Dwukrotne kliknięcie” zajmuje mniej czasu niż „Napisz i przetestuj”. Myślę, że może to być gdzieś w okolicy bash oneliner.
Lyndon White
Pewnego razu programiści dostali prezenty i dziękuję za anulowanie projektu. Wskazałem, że moglibyśmy być jeszcze bardziej produktywni, gdybyśmy wiedzieli, że produkt nie zostanie wysłany. Jest to więc przypadek, w którym korzystne byłoby opracowanie bez testowania.
JDługosz

Odpowiedzi:

149

Im później testujesz, tym więcej kosztuje pisanie testów.

Im dłużej żyje błąd, tym droższe jest jego usunięcie.

Prawo malejących zwrotów gwarantuje, że możesz sprawdzić się w zapomnieniu, próbując upewnić się, że nie ma żadnych błędów.

Budda nauczał mądrości środkowej ścieżki. Testy są dobre. Jest coś takiego, jak zbyt wiele dobrego. Kluczem jest możliwość stwierdzenia, kiedy straciłeś równowagę.

Każdy wiersz kodu, który piszesz bez testów, będzie miał znacznie większe koszty dodania testów później niż gdybyś napisał testy przed napisaniem kodu.

Każda linia kodu bez testów będzie znacznie trudniejsza do debugowania lub przepisania.

Każdy test, który napiszesz, zajmie trochę czasu.

Każdy błąd wymaga czasu na naprawę.

Wierni powiedzą ci, abyś nie pisał ani jednego wiersza kodu bez uprzedniego napisania testu zakończonego niepowodzeniem. Test zapewnia zachowanie, którego oczekujesz. Umożliwia szybką zmianę kodu bez obawy o wpływ na resztę systemu, ponieważ test dowodzi, że zachowanie jest takie samo.

Musisz to wszystko porównać z faktem, że testy nie dodają funkcji. Kod produkcyjny dodaje funkcje. A funkcje są tym, co płacą rachunki.

Pragmatycznie dodaję wszystkie testy, z którymi mogę uciec. Ignoruję komentarze na rzecz oglądania testów. Nie ufam nawet kodowi, który robi to, co myślę, że działa. Ufam testom. Ale jestem znany z rzucania okazjonalnego gradu mary i mam szczęście.

Jednak wielu udanych programistów nie robi TDD. To nie znaczy, że nie testują. Po prostu nie obsesyjnie nalegają, aby każda linia kodu miała zautomatyzowany test. Nawet wujek Bob przyznaje, że nie testuje swojego interfejsu użytkownika. Nalega również, abyś wyprowadził całą logikę z interfejsu użytkownika.

Jako metafora futbolu (czyli futbol amerykański) TDD jest dobrą grą naziemną. Testowanie ręczne tylko tam, gdzie piszesz stos kodu i mam nadzieję, że zadziała, jest grą przejściową. W obu przypadkach możesz być dobry. Twoja kariera nie pozwoli na rozegranie play-off, chyba że możesz zrobić jedno i drugie. Nie sprawi, że superowl będzie, dopóki nie dowiesz się, kiedy wybrać każdego z nich. Ale jeśli potrzebujesz szturchnięcia w określonym kierunku: wezwania urzędników częściej mi się zdarzają, kiedy przechodzę.

Jeśli chcesz wypróbować TDD, gorąco polecam ćwiczenie przed próbą zrobienia tego w pracy. TDD wykonane w połowie, na pół serca i na wpół dupsko, to duży powód, dla którego niektórzy go nie szanują. To jak wlewanie jednej szklanki wody do drugiej. Jeśli nie popełnisz tego i zrobisz to szybko i całkowicie, w końcu ściekasz wodą po całym stole.

candied_orange
źródło
68
Jest coś takiego jak zbyt dobra rzecz Ani ty, ani Budda nie przetestowaliście ciasteczek mojej babci :-)
Pierre Arlaud
3
@NickAlexeev Uwielbiam ten wykres tam. Jedną z rzeczy, na które nie wskazuje, jest to, że testy jednostkowe (które zwykle są zautomatyzowane) są naprawdę dobre w znajdowaniu błędów, gdy kod jest modyfikowany. Chciałbym zobaczyć, jak ten podział na „błędy znalezione przed wydaniem” i „błędy znalezione po wydaniu”. Testy jednostkowe są najlepszą linią obrony przed regresją.
corsiKa
3
Myślę, że to bardzo zrównoważona odpowiedź: testowanie wszystkiego, nawet błahych rzeczy, może być stratą czasu. Bardzo pomocne mogą być dobre testy złożonych części, które można łatwo złamać. Właśnie skończyłem przenosić mały, ale nietrywialny projekt z Javy na C ++. Najpierw przeniosłem testy, co pomogło mi skonfigurować całą implementację C ++. Gdy wszystkie testy były zielone, trzeba było przenieść tylko kilka łatwiejszych klas i przebiegło to całkiem sprawnie. Z drugiej strony nie mam testów dla całego kodu: wydłużyłoby to wdrożenie o co najmniej 3, 4 dni z niewielkim zyskiem.
Giorgio
5
Nieznaczna różnica zdań: „Musisz to wszystko porównać z faktem, że testy nie dodają funkcji. Kod dodaje funkcje. A cechy są tym, co płaci rachunki. Zdecydowanie sugerowałbym, że to nie funkcje płacą rachunki - to funkcje działające. (czy ludzie zarabiają za niedziałające produkty?). Reszta odpowiedzi całkowicie się zgadzam.
Tony Suffolk 66
6
@ TonySuffolk66 masz rację, to funkcje robocze płacą rachunki (z wyjątkiem sprzedaży flimflam) Jednak ludzie tworzyli funkcje robocze na długo przed TDD. Będą długo po jego zniknięciu. Pamiętaj, że TDD to zdyscyplinowany sposób testowania. To nie jedyny zdyscyplinowany sposób testowania.
candied_orange
112

Zgadzam się z resztą odpowiedzi, ale bezpośrednio odpowiadam na pytanie o różnicę czasu .

Roy Osherove w swojej książce The Art of Unit Testing, wydanie drugie, strona 200, przeprowadził studium przypadku wdrażania projektów o podobnej wielkości z podobnymi zespołami (pod względem umiejętności) dla dwóch różnych klientów, w których jeden zespół testował, a drugi nie.

Jego wyniki były takie:

Postęp zespołu i wydajność mierzone z testami i bez

Pod koniec projektu masz mniej czasu i mniej błędów. To oczywiście zależy od tego, jak duży jest projekt.

Aki K.
źródło
32
Wielkość próbki jest zbyt mała, aby uznać ją za naukową, ale myślę, że jest reprezentatywna dla tego, czego doświadcza wiele osób. Uważam, że kiedy robię TDD, większość dodatkowego czasu spędzam na naprawianiu błędów, które powodują niepowodzenie moich testów jednostkowych, a nie na pisaniu samych testów. To tak naprawdę nie dodaje dodatkowego czasu, po prostu zmienia się, gdy znajdziesz i naprawiasz te problemy. Dodatkowy czas to naprawianie problemów, których nie znalazłbyś, przynajmniej nie w pierwszej rundzie.
JimmyJames
7
@JimmyJames To studium przypadku, które jest szeroko stosowane w biznesie i dużo w nauce, gdy nie jest (jeszcze) możliwe przeprowadzenie eksperymentu na dużą skalę. Są pełne czasopism psychologicznych. „Nienaukowy” nie jest właściwym słowem.
djechlin
25
Dlaczego myślę, że gdyby wynik tego studium przypadku wykazał coś przeciwnego, nie znalazłby się w książce ;-)?
Doc Brown
11
@DocBrown Zastanawiam się, ile analiz przypadków wykonano i odrzucono, zanim znaleźli jedną z prawidłowymi odpowiedziami :-)
gbjbaanb
6
@JimmyJames, który prawie na pewno kwalifikuje się jako nauka. Ponadto inny naukowiec może przeczytać to studium przypadku „n = 1”, zdecydować, że warto studiować więcej, a następnie przeprowadzić badanie statystyczne na dużą skalę lub nawet kontrolowany eksperyment podłużnie, i potwierdzić je lub odrzucić. Właśnie tak działa nauka. Tak to powinno działać. możesz przeczytać więcej o tym, jak nauka działa tutaj en.wikipedia.org/wiki/Scientific_method
djechlin
30

Jest tylko jedno badanie, które znam, które badało to w „realnym świecie”: Realizacja poprawy jakości poprzez rozwój oparty na testach: wyniki i doświadczenia czterech zespołów przemysłowych . Wykonanie tego w rozsądny sposób jest drogie, ponieważ zasadniczo oznacza to, że musisz opracować to samo oprogramowanie dwukrotnie (lub najlepiej jeszcze częściej) w podobnych zespołach, a następnie wyrzucić wszystkie oprócz jednego.

Rezultatami badań było wydłużenie czasu rozwoju między 15% –35% (co nie jest niczym w pobliżu wartości 2x, która często jest cytowana przez krytyków TDD) oraz zmniejszenie gęstości defektów przed uwolnieniem z 40% –90% (! ). Należy zauważyć, że wszystkie zespoły nie miały wcześniejszego doświadczenia z TDD, więc można założyć, że wydłużenie czasu można przynajmniej częściowo przypisać uczeniu się, a tym samym pójdzie w dół z czasem, ale nie zostało to ocenione w badaniu.

Zauważ, że to badanie dotyczy TDD, a twoje pytanie dotyczy testów jednostkowych, które są bardzo różne, ale jest to najbliższe, jakie mogłem znaleźć.

Jörg W Mittag
źródło
1
Bardziej interesujące byłoby nałożenie dodatkowych ograniczeń: brak stanu zmiennego, po SOLID, typowanie statyczne, brak polegania null, funkcjonalność ponad imperatywem, kontrakty kodu, analiza statyczna, automatyczne refaktoryzowanie, brak kontenerów IoC (ale DI) itp. Założę się o tę wartość testów jednostkowych zmniejszy się (ale nie zniknie).
Den
24

Wykonanie dobrze, rozwijanie za pomocą testów jednostkowych może być szybsze, nawet bez uwzględnienia korzyści z wykrycia dodatkowych błędów.

Faktem jest, że nie jestem wystarczająco dobrym programistą, aby po prostu mój kod działał, gdy tylko się skompiluje. Kiedy piszę / modyfikuję kod, muszę go uruchomić, aby upewnić się, że działa tak, jak myślałem. W jednym projekcie wyglądało to tak:

  1. Zmodyfikuj kod
  2. Skompiluj aplikację
  3. Uruchom aplikację
  4. Zaloguj się do aplikacji
  5. Otwórz okno
  6. Wybierz element z tego okna, aby otworzyć kolejne okno
  7. Ustaw niektóre elementy sterujące w tym oknie i kliknij przycisk

I oczywiście po tym wszystkim zajęło to zwykle kilka podróży w obie strony.

A co jeśli korzystam z testów jednostkowych? Następnie proces wygląda bardziej jak:

  1. Napisz test
  2. Uruchom testy, upewnij się, że nie powiedzie się w oczekiwany sposób
  3. Napisz kod
  4. Ponownie uruchom testy, sprawdź, czy przebiegło pomyślnie

Jest to łatwiejsze i szybsze niż ręczne testowanie aplikacji. Nadal muszę ręcznie uruchomić aplikację (więc nie wyglądam głupio, kiedy oddaję pracę, która tak naprawdę wcale nie działa), ale w przeważającej części już wypracowałem załamania i po prostu jestem weryfikacja w tym momencie. Zazwyczaj robię pętlę jeszcze ściślej, używając programu, który automatycznie uruchamia moje testy po zapisaniu.

Zależy to jednak od pracy w bazie kodu przyjaznego dla testów. Wiele projektów, nawet tych z wieloma testami, utrudnia pisanie testów. Ale jeśli nad tym pracujesz, możesz mieć bazę kodu, którą łatwiej przetestować za pomocą testów automatycznych niż testów ręcznych. Jako bonus, możesz utrzymać zautomatyzowane testy i uruchamiać je, aby uniknąć regresji.

Winston Ewert
źródło
1
A użycie czegoś takiego jak nCrunch pozwala wyciąć kroki 2 i 4, dzięki czemu pętla sprzężenia zwrotnego jest jeszcze ściślejsza.
Euforyczny
„Nadal muszę ręcznie uruchomić aplikację” to ważna obserwacja, IMHO. Żadnych srebrnych kul.
Den
20

Mimo że jest już wiele odpowiedzi, są one nieco powtarzalne i chciałbym wybrać inny sposób. Testy jednostkowe są cenne tylko wtedy , gdy zwiększają wartość biznesową . Testowanie w celu testowania (testy trywologiczne lub tautologiczne) lub w celu uzyskania jakiejkolwiek arbitralnej metryki (np. Pokrycia kodu) jest programowaniem kultowym.

Testy są kosztowne, nie tylko w czasie, w którym trzeba je napisać, ale także w konserwacji. Muszą być zsynchronizowane z testowanym kodem, inaczej są bezwartościowe. Nie wspominając o koszcie czasu ich uruchomienia przy każdej zmianie. Nie stanowi to przełomu (ani usprawiedliwienia dla nie robienia naprawdę niezbędnych), ale musi zostać uwzględnione w analizie kosztów i korzyści.

Więc pytanie, które należy zadać, decydując, czy (lub jakiego rodzaju) przetestować funkcję / metodę, zadaj sobie pytanie: „jaką wartość dla użytkownika końcowego tworzę / zabezpieczam za pomocą tego testu?”. Jeśli nie potrafisz odpowiedzieć na to pytanie z góry , wtedy ten test prawdopodobnie nie jest wart kosztów pisania / utrzymania. (lub nie rozumiesz domenę problem, który jest waaaay większy problem niż brak testów).

http://rbcs-us.com/documents/Why-Most-Unit-Testing-is-Waste.pdf

Jared Smith
źródło
1
Nie jestem zbyt obeznany z BDD, ale zgaduję, że działa on na nieco bardziej zgrubnej ziarnistości niż na poziomie metody / funkcji i prawdopodobnie ma mniej wątły związek z wartością użytkownika.
Jared Smith,
1
Powiązane
Robbie Dee,
9
„Testowanie w celu testowania (testy trywologiczne lub tautologiczne) lub w celu uzyskania jakiejkolwiek arbitralnej metryki (np. Pokrycia kodu) jest programowaniem kultowym”. Tak prawdziwe i tak dobrze powiedziane. Przetestuj w taki sposób, abyś czuł się jak fajny badass - pomyśl o sobie jako ... szpiegu, elitarnym sportowcu ... NIE testuj jak „departament rządowy”. Wiesz?
Fattie,
2
@ SteveJessop nie zgadza się, że pokrycie kodu (w sensie bycia metryką) jest z natury arbitralne: liczba ścieżek w nietrywialnym programie na poziomie instrukcji maszyny (tj. Ta, która się liczy) będzie większa niż liczba atomów na Ziemia, a może nawet widzialny wszechświat. Tego nie da się przetestować. Zatem wszelkie roszczenia dotyczące „pokrycia kodu” będą przekraczać dowolny heurystycznie wybrany arbitralny próg. Programiści są dobrzy w graniu takimi wskaźnikami kosztem rzeczy, które naprawdę mają znaczenie.
Jared Smith,
2
Powiedziałbym również, że testy dostarczają wartość biznesową w przybliżeniu (choć nie dokładnie) za każdym razem, gdy zawodzą, a rozwiązaniem jest poprawienie testowanego kodu. Więc jeśli używasz TDD, prawie automatycznie dzieje się co najmniej jeden na test. Testy tautologiczne z definicji nie mogą zawieść i dlatego są bezużyteczne. W przypadku „trywialnych” testów - ponieważ pracowałem z Javą TCK na początku mojej kariery, nie jestem już zaskoczony tym, jak trywialny test może się nie powieść przy ponownej implementacji API od zera ;-) Ale wartość biznesowa jest prawie zawsze przewidywano heurystycznie, podobnie jak „arbitralne”.
Steve Jessop,
9

To zależy od osoby, a także od złożoności i kształtu kodu, z którym pracujesz.

W przypadku większości projektów pisanie testów jednostkowych oznacza, że ​​wykonuję pracę o około 25% szybciej. Tak, nawet uwzględniając czas na napisanie testów.

Ponieważ faktem jest, że oprogramowanie nie jest wykonywane podczas pisania kodu. Odbywa się to, gdy wysyłasz go do klienta i jest z niego zadowolony. Testy jednostkowe są zdecydowanie najbardziej wydajnym sposobem na wykrycie większości błędów, wyodrębnienie większości błędów na potrzeby debugowania i uzyskanie pewności, że kod jest dobry. Musisz zrobić te rzeczy, tak czy inaczej , więc zrobić je dobrze.

Telastyn
źródło
7
Myślę, że warto zauważyć, że jest to umiejętność nabyta. Widzę, że tak wielu ludzi słyszy twierdzenie, że TDD tak naprawdę nie jest nawet pułapką czasową, która się opłaca na dłuższą metę, to po prostu szybszy okres. potem próbują tego przez jeden dzień i jest to bolesne, ponieważ mają 0 doświadczeń, przeczytali 0 książek, nie mają praktyki, po prostu oczekują, że zadziała. TDD nie ma tajemnicy, która czyni cię lepszym programistą, wciąż musisz ćwiczyć, wciąż myśleć, wciąż podejmować dobrze wykształcone decyzje.
sara
1
@kai - +1. Spędziłem tygodnie czytając o TDD, zanim go wypróbowałem. Przeczytałem wszystko, co mogłem znaleźć. Czytam książki. Czytam przykłady znanych blogów zwinnych. Czytam wzorce testowe xUnit od początku do końca . Przez pierwsze kilka tygodni zajęło mi to dwa razy dłużej.
Jules
2
Zgadzam się. TDD jest trudne. Sposób myślenia jest trudny. Każdy, kto mówi „Najpierw napisz testy” i twierdzi, że jest bezpłatny, nie wie, jak to zrobić. To wymaga praktyki.
duffymo
@kai: z podobnych powodów wiele osób nie może pisać dotykiem. Próbowali raz i po całej godzinie nadal nie pisali szybciej niż wcześniej ;-)
Steve Jessop,
@ SteveJessop Myślę, że to całkiem miłe porównanie. Lub być naprawdę niezdolnym i wychodzić na 10-minutowy jogging, wyczerpać się i zastanawiać, dlaczego nie możesz przebiec 10 mil w ciągu godziny. naprawdę pokazuje, jak musisz pracować, zanim uzyskasz świadczenia.
sara
4

Pytanie brzmi: ile różnicy czasu napisałby kod testowany jednostkowo w stosunku do kodu niepoddanego testowi i jak zmienia się ta różnica czasu w miarę rozszerzania zakresu projektu?

Problem pogarsza się wraz ze wzrostem wieku projektu: ponieważ za każdym razem, gdy dodajesz nową funkcjonalność i / lub za każdym razem, gdy refaktoryzujesz istniejącą implementację, powinieneś ponownie przetestować to, co wcześniej testowano, aby upewnić się, że nadal działa. Tak więc w przypadku długowiecznego (wieloletniego) projektu może być konieczne nie tylko przetestowanie funkcjonalności, ale ponowne przetestowanie jej 100 razy i więcej. Z tego powodu możesz skorzystać z automatycznych testów. Jednak IMO jest wystarczająco dobry (a nawet lepszy), jeśli są to automatyczne testy systemu, a nie automatyczne testy jednostkowe.

Drugim problemem jest to, że błędy mogą być trudniejsze do znalezienia i naprawienia, jeśli nie zostaną wcześnie wykryte. Na przykład, jeśli w systemie jest błąd i wiem, że działał on idealnie, zanim wprowadziłeś ostatnią zmianę, wtedy skoncentruję swoją uwagę na twojej ostatniej zmianie, aby zobaczyć, jak mogła ona wprowadzić błąd. Ale jeśli nie wiem, czy system działał, zanim wprowadziłeś ostatnią zmianę (ponieważ system nie został odpowiednio przetestowany przed ostatnią zmianą), błąd może być wszędzie.

Powyższe dotyczy szczególnie głębokiego kodu, a mniej płytkiego kodu, np. Dodawania nowych stron internetowych, na których nowe strony raczej nie wpłyną na istniejące strony.

W rezultacie znaczna liczba błędów ucieka do produkcji, którą muszę naprawić, a to z kolei opóźnia moje inne projekty.

Z mojego doświadczenia byłoby to nie do przyjęcia, więc zadajesz niewłaściwe pytanie. Zamiast pytać, czy testy przyspieszą programowanie, powinieneś zapytać, co sprawi, że programowanie będzie bardziej wolne od błędów.

Lepszym pytaniem może być:

  • Czy testowanie jednostkowe jest właściwym rodzajem testowania, którego potrzebujesz, aby uniknąć „znacznej liczby błędów”, które produkujesz?
  • Czy istnieją inne mechanizmy kontroli / poprawy jakości (oprócz testów jednostkowych), które można zalecić, czy zamiast tego?

Uczenie się jest procesem dwuetapowym: naucz się robić to wystarczająco dobrze, a następnie naucz się robić to szybciej.

ChrisW
źródło
3

Niektóre aspekty do rozważenia, niewymienione w innych odpowiedziach.

  • Dodatkowa korzyść / dodatkowy koszt zależą od doświadczenia w pisaniu artykułów
    • w moim pierwszym projekcie testów jednostkowych dodatkowe koszty potroiły się, ponieważ musiałem dużo się nauczyć i popełniłem wiele błędów.
    • po 10 latach doświadczenia z tdd potrzebuję 25% więcej czasu na napisanie testów z wyprzedzeniem.
  • przy większej liczbie modułów TDD nadal istnieje potrzeba ręcznego testowania GUI i testowania integracji
  • tdd działa tylko od początku.
    • zastosowanie tdd do istniejącego, wyhodowanego projektu jest kosztowne / utrudnione. Zamiast tego możesz wdrożyć testy regresji.
  • testy automatyczne (testy jednostkowe i inne rodzaje testów) wymagają constanace const, aby działały.
    • po utworzeniu testu przez kopiowanie i wklejanie może kosztować utrzymanie kodu testowego.
    • wraz z rosnącym doświadczeniem kod testowy staje się bardziej modułowy i łatwiejszy w utrzymaniu.
  • wraz z rosnącym doświadczeniem poczujesz, kiedy warto tworzyć automatyczne testy, a kiedy nie.
    • przykład nie ma dużej korzyści dla najprostszych prostych pobierających / ustawiających / owijających
    • Nie piszę automatycznych testów za pomocą GUI
    • Dbam o to, aby testować biznesmena

Podsumowanie

Zaczynając od tdd, trudno jest osiągnąć stan „więcej korzyści niż kosztów”, o ile jesteś w „ograniczonym czasowo środowisku pracy”, zwłaszcza jeśli są „sprytni menedżerowie”, którzy mówią ci „pozbyć się drogiego, bezużytecznego” testowanie rzeczy ”

Uwaga: przez „testowanie jednostkowe” mam na myśli „testowanie modułów w izolacji”.

Uwaga: mam na myśli „test regresji”

  • napisz kod, który tworzy tekst wyjściowy.
  • napisz kod „testowania regresji”, który potwierdzi, że wynik generowania jest nadal taki sam.
  • test regresji informuje cię za każdym razem, gdy wynik się zmienia (co może być w porządku lub wskaźnik nowego błędu)
  • idea „testów regresji” jest podobna do testów zatwierdzających
    • ... robiąc migawkę wyników i potwierdzając, że się nie zmieniły.
k3b
źródło
Potrzebuje korekty (literacki odpowiednik testowania?)
JDługosz
3

Programiści, podobnie jak ludzie zajmujący się większością zadań, nie doceniają tego, ile czasu zajmuje ich wykonanie. Mając to na uwadze, można poświęcić 10 minut na napisanie testu, ponieważ można było napisać mnóstwo kodu, podczas gdy w rzeczywistości spędziłbyś ten czas na wymyśleniu tej samej nazwy funkcji i parametrów, co podczas testu . To jest scenariusz TDD.

Brak pisania testów jest bardzo podobny do posiadania karty kredytowej; wydajemy więcej lub piszemy więcej kodu. Więcej kodu zawiera więcej błędów.

Zamiast decydować się na całkowite pokrycie kodu lub jego brak, sugeruję skupienie się na krytycznej i skomplikowanej części aplikacji i przeprowadzenie testów. W aplikacji bankowej może to być naliczanie odsetek. Narzędzie diagnostyczne silnika może mieć złożone protokoły kalibracji. Jeśli pracujesz nad projektem, prawdopodobnie wiesz, co to jest i gdzie są błędy.

Zacznij powoli. Zbuduj trochę płynności, zanim osądzisz. Zawsze możesz przestać.

JeffO
źródło
3

Od dawna Rada Programistów promuje TDD i inne metodologie testowe, nie przypominam sobie ich argumentów i nie zgadzam się z nimi, ale oto dodatkowe rzeczy do rozważenia, które powinny trochę niuansować:

  • Testowanie nie jest równie wygodne i wydajne w zależności od kontekstu. Tworzę oprogramowanie sieciowe, powiedz mi, czy masz program do testowania całego interfejsu użytkownika ... w tej chwili programuję makra programu Excel, czy naprawdę powinienem opracować moduł testowy w języku VBA?
  • Pisanie i konserwacja oprogramowania testowego to prawdziwa praca, która się liczy w krótkim okresie (opłaca się w dłuższym okresie). Pisanie odpowiednich testów to także wiedza specjalistyczna
  • Pracując jako zespół i pracując samemu, nie masz takich samych wymagań testowych, ponieważ w zespole musisz zweryfikować, zrozumieć i przekazać kod, którego nie napisałeś.

Powiedziałbym, że testowanie jest dobre, ale upewnij się, że testujesz wcześnie i sprawdzasz, gdzie jest zysk.

Arthur Havlicek
źródło
1
„Czy naprawdę powinienem opracować moduł testowy dla VBA?” Cholera, powinieneś. rubberduckvba.com/Features#unitTesting
RubberDuck
Jest kilka powodów, dla których nie użyję tego, ponieważ nie pasuje do moich potrzeb (jestem na co najwyżej kilka dni, zamknięte środowisko, następca nie będzie przeszkadzał stronom trzecim). Dobry komentarz, język sam w sobie nie jest jednak wymówką :)
Arthur Havlicek,
Wszystkie uczciwe punkty @ArthurHavlicek.
RubberDuck,
2
Pisanie testów jest nadal trywialne w VBA. Posiadasz wszystkie fantazyjne funkcje, które mają niektóre najbardziej niestabilne frameworki? To trudniejsze, ale uruchomienie programu o nazwie mainTest()wszystkie moduły testowe nie jest tak trudne.
enderland
1

Często pomijaną zaletą TDD jest to, że testy działają jako zabezpieczenie, aby upewnić się, że nie wprowadzasz nowych błędów podczas wprowadzania zmian.

Podejście TDD jest niewątpliwie bardziej czasochłonne, ale na wynos napisz mniej kodu, co oznacza mniej problemów. Wszystkie te dzwonki i gwizdy, które często dołączasz, oczywiście nie znajdą się w bazie kodu.

W filmie Swordfish jest scena, w której jeśli pamięć służy, haker musi pracować z pistoletem przy głowie i być rozproszony ... w przeciwnym razie rozproszony. Chodzi o to, że o wiele łatwiej jest pracować, gdy twoja wolna przestrzeń jest w kodzie i masz czas po swojej stronie, a nie miesiące później, gdy klient krzyczy na ciebie i inne priorytety zostają ściśnięte.

Programiści rozumieją, że późniejsze naprawianie błędów jest droższe, ale odwróć to na głowie. Jeśli możesz otrzymać wynagrodzenie w wysokości 500 USD dziennie za kodowanie sposobu, w jaki piszesz teraz, lub 1000 USD, jeśli napisałeś w sposób TDD, zryjesz rękę osobie składającej 2. ofertę. Im szybciej przestaniesz postrzegać testowanie jako obowiązek i postrzegać go jako oszczędność pieniędzy, tym lepiej.

Robbie Dee
źródło
Ta rzecz w pierwszym zdaniu nazywa się Testowaniem regresji
kot
0

Mogę odnieść się do twojego doświadczenia - nasza baza kodu prawie nie miała testów i była w większości niestabilna. Stworzenie czegoś zajęło dosłownie wieki, a naprawianie błędów w produkcjach zabrało cenny czas na nowe funkcje.

W celu częściowego przepisania przysięgałem napisać testy dla wszystkich podstawowych funkcji. Na początku zajęło to znacznie więcej czasu, a moja produktywność znacznie spadła, ale potem moja wydajność była lepsza niż kiedykolwiek wcześniej.

Częścią tej poprawy było to, że miałem mniej błędów produkcyjnych, co z kolei prowadziło do mniejszej liczby przerw -> Miałem lepszą uwagę w danym momencie.

Co więcej, umiejętność samodzielnego testowania ORAZ debugowania kodu naprawdę się opłaca - zestaw testów jest znacznie lepszy niż system, którego nie można debugować inaczej niż przy ręcznej konfiguracji, np. Uruchomienie aplikacji i przejście do ekranu i zrobienie czegoś ... być może kilkadziesiąt razy

Ale zauważ, że na początku występuje spadek wydajności, więc zacznij uczyć się testowania w niektórych projektach, w których presja czasu nie jest już szalona. Spróbuj także uruchomić go w projekcie typu greenfield, testowanie jednostek starszego kodu jest bardzo trudne i pomaga, gdy wiesz, jak wygląda dobry zestaw testów.

Christian Sauer
źródło
0

Aby uzupełnić poprzednie odpowiedzi: pamiętaj, że testowanie nie jest celem samym w sobie. Celem przeprowadzania testów jest zachowanie aplikacji zgodnie z oczekiwaniami poprzez ewolucję, w nieoczekiwanych kontekstach itp.

Dlatego pisanie testów nie oznacza udowodnienia wszystkich zachowań wszystkich punktów końcowych bytu. To jest częsty błąd. Wielu programistów uważa, że ​​muszą przetestować wszystkie funkcje / obiekty / metody / właściwości / itp. Prowadzi to do dużego obciążenia pracą oraz szeregu nieistotnych kodów i testów. Takie podejście jest powszechne w dużych projektach, w których większość programistów nie jest świadoma holistycznego zachowania, ale widzi tylko domenę interakcji.

Właściwe podejście w przypadku rzadkich zasobów i testowania jest dość oczywiste i ma zdrowy rozsądek, ale nie jest powszechnie sformalizowane: najpierw zainwestuj w testowanie zasobów programistycznych w funkcje wysokiego poziomu, a następnie stopniowo popadaj w specyficzne cechy . Oznacza to, że w pewnym momencie, jako samotny programista, skupisz się nie tylko na testowaniu jednostkowym, ale także na funkcjonalności / integracji / itp. testowanie i w zależności od zasobów czasowych, stopniowo do głównych funkcji jednostkowych, tak jak planowałbyś i rozważał. Testy na wysokim poziomie dostarczą informacji niezbędnych do rozwiązania testów na niskim poziomie / jednolitych oraz do zaplanowania strategii rozwoju testów zgodnie z posiadanymi zasobami.

Na przykład chciałbyś najpierw przetestować łańcuch przetwarzania jako czarną skrzynkę. Jeśli stwierdzisz, że jeden członek łańcucha zawodzi z powodu zachowania, które nie uwzględniało jakiegoś ekstremalnego warunku, piszesz testy, które gwarantują funkcjonalność nie tylko na tym elemencie, ale także na innych. Potem dostarczasz. W następnym cyklu wykryjesz, że czasami awaria sieci. Więc piszesz testy, które rozwiązują taki problem na modułach, które mogą być podatne na atak. I tak dalej.

RodolfoAP
źródło