Pracuję w małej firmie jako programista solo. W rzeczywistości jestem jedynym programistą w firmie. Mam kilka (stosunkowo) dużych projektów, które regularnie napisałem i prowadzę, i żaden z nich nie ma testów na ich wsparcie. Kiedy rozpoczynam nowe projekty, często zastanawiam się, czy powinienem spróbować podejścia TDD. Brzmi jak dobry pomysł, ale szczerze mówiąc, nigdy nie usprawiedliwiam dodatkowej pracy.
Ciężko pracuję, by myśleć przyszłościowo w swoim projekcie. Zdaję sobie sprawę, że z pewnością pewnego dnia inny programista będzie musiał zachować mój kod lub przynajmniej go rozwiązać. Utrzymuję rzeczy tak proste, jak to możliwe, komentuję i dokumentuję rzeczy, które trudno byłoby pojąć. A faktem jest, że projekty te nie są tak duże ani skomplikowane, że przyzwoity programista miałby problemy z ich zrozumieniem.
Wiele przykładów testów, które widziałem, sprowadza się do najdrobniejszych szczegółów, obejmujących wszystkie aspekty kodu. Ponieważ jestem jedynym programistą i jestem bardzo blisko kodu w całym projekcie, znacznie bardziej efektywne jest stosowanie wzorca testowego zapisu i ręcznego zapisu. Uważam również, że wymagania i funkcje zmieniają się na tyle często, że utrzymywanie testów spowodowałoby znaczne obciążenie projektu. Czas, który można by poświęcić na zaspokojenie potrzeb biznesowych.
Tak więc za każdym razem dochodzę do tego samego wniosku. Zwrot z inwestycji jest zbyt niski.
Od czasu do czasu konfiguruję kilka testów, aby upewnić się, że poprawnie napisałem algorytm, na przykład obliczanie liczby lat, które ktoś spędził w firmie na podstawie daty zatrudnienia. Ale z punktu widzenia pokrycia kodu pokryłem około 1% mojego kodu.
Czy w mojej sytuacji nadal znajdowałbyś sposób na regularne przeprowadzanie testów jednostkowych, czy czy mam uzasadnione podstawy, by unikać tego narzutu?
AKTUALIZACJA: Kilka rzeczy o mojej sytuacji, które pominąłem: wszystkie moje projekty to aplikacje internetowe. Aby pokryć cały mój kod, musiałbym użyć automatycznych testów interfejsu użytkownika, i to jest obszar, w którym nadal nie widzę wielkiej przewagi nad testowaniem ręcznym.
źródło
Odpowiedzi:
Więc? Nie musisz wszystkiego testować . Tylko odpowiednie rzeczy.
To właściwie fałsz. To nie jest bardziej wydajne. To naprawdę tylko nawyk.
To, co robią inni twórcy solo, to napisanie szkicu lub konspektu, napisanie przypadków testowych, a następnie wypełnienie konturu ostatecznym kodem.
To bardzo, bardzo wydajne.
To także fałsz. Testy to nie opór. Zmiany wymagań są przeciągane.
Musisz naprawić testy, aby odzwierciedlić wymagania. Czy to ich drobiazgi, czy wysoki poziom; napisane jako pierwsze lub napisane jako ostatnie.
Kod nie jest wykonywany, dopóki testy nie przejdą. To jedna uniwersalna prawda oprogramowania.
Możesz mieć ograniczony test akceptacyjny „tutaj jest”.
Lub możesz mieć jakieś testy jednostkowe.
Lub możesz mieć oba.
Ale bez względu na to, co robisz, zawsze jest test wykazujący, że oprogramowanie działa.
Sugerowałbym, że odrobina formalności i ładny zestaw narzędzi do testowania jednostek sprawia, że ten test jest o wiele bardziej użyteczny.
źródło
sqrt(-1)
powinna być liczbą całkowitą, uzyskasz przytłaczające odpowiedzi pochylone w jedną stronę. Bilans dotyczy „jak” i „jaki porządek”. Sam fakt jest taki, że musisz przetestować. Więc najpierw napisz testy i upewnij się, że działają.Wyobraź sobie, że masz zestaw testów, które można uruchomić w linku do oczu i zapalić zielone lub czerwone światło. Wyobraź sobie, że ten zestaw testów przetestował wszystko ! Wyobraź sobie, że wystarczyło tylko napisać ^ T, aby uruchomić zestaw testów. Jaką moc to by ci dało?
Czy możesz zmienić kod bez obawy, że coś zepsujesz? Czy możesz dodać nową funkcję bez obawy o uszkodzenie starej funkcji? Czy potrafisz szybko wyczyścić niechciany kod bez obawy o uszkodzenie?
Tak, możesz robić te wszystkie rzeczy! A co z czasem stanie się z twoim kodem? Byłoby coraz czystsze, ponieważ nie byłoby ryzyka czyszczenia.
Wyobraźmy sobie, że miałeś małą wróżkę na ramieniu. Za każdym razem, gdy piszesz wiersz kodu, wróżka dodaje coś do zestawu testów, który testuje, że ten wiersz kodu robi to, co powinien. Więc co kilka sekund możesz nacisnąć ^ T i zobaczyć, że ostatni wiersz kodu, który napisałeś, działał.
Jak myślisz, ile debugowania zrobiłbyś?
Jeśli to brzmi jak fantazja, masz rację. Ale rzeczywistość niewiele się różni. Wymień linkę oczną na kilka sekund, a wróżka na dyscyplinę TDD, a już ją masz.
Powiedzmy, że wracasz do systemu zbudowanego rok temu i zapomniałeś, jak stworzyć jeden z centralnych obiektów. Istnieją testy, które tworzą ten obiekt w każdy możliwy sposób. Możesz przeczytać te testy i pobudzić pamięć. Chcesz zadzwonić do API? Istnieją testy, które wywołują ten interfejs API w każdy możliwy sposób. Te testy to małe dokumenty napisane w języku, który rozumiesz. Są całkowicie jednoznaczne. Są tak formalni, że wykonują. I nie mogą się zsynchronizować z aplikacją!
Nie warta inwestycji? Chyba sobie żartujesz! Jak ktokolwiek mógłby NIE chcieć tego zestawu testów? Zrób sobie przysługę i przestań się kłócić o głupotę. Naucz się dobrze robić TDD i patrz, jak szybko jedziesz i jak czystszy jest twój kod.
źródło
Popełniasz błąd, ponieważ postrzegasz testowanie jako inwestycję czasową bez natychmiastowego zwrotu. To niekoniecznie tak działa.
Po pierwsze, pisanie testów naprawdę koncentruje się na tym, co powinna zrobić ta część kodu.
Po drugie ich uruchomienie ujawnia błędy, które w innym przypadku pojawiałyby się w testach.
Po trzecie, uruchamianie ich czasami pokazuje błędy, które inaczej nie pojawiałyby się w testach, a następnie naprawdę ugryzłyby cię w tyłek podczas produkcji.
Po czwarte, jeśli trafisz błąd w działającym systemie i utworzysz dla niego test jednostkowy, nie będziesz mógł ponownie wprowadzić tego błędu później. To może być naprawdę duża pomoc. Ponownie wprowadzone błędy są powszechne i bardzo denerwujące.
Po piąte, jeśli kiedykolwiek będziesz musiał przekazać kod komuś innemu, pakiet testowy znacznie ułatwi jego życie. Również jeśli zignorujesz projekt i powrócisz do niego po kilku latach, nie będziesz już tak blisko niego, a także będzie ci pomocny.
Moje doświadczenie konsekwentnie polega na tym, że w trakcie opracowywania projektu, posiadanie przyzwoitych testów jednostkowych zawsze czyniło proces szybszym i bardziej niezawodnym.
źródło
Ludzie z JUnit (platforma testowa Java Unit) mają filozofię, że jeśli testowanie jest zbyt proste, nie testuj go . Bardzo polecam przeczytanie często zadawanych pytań dotyczących najlepszych praktyk , ponieważ jest to dość pragmatyczne.
TDD to inny proces pisania oprogramowania. Podstawową przesłanką testów jednostkowych jest to, że będziesz spędzać mniej czasu w debuggerze przechodząc przez kod i szybciej dowiedzieć się, czy zmiana kodu przypadkowo psuje coś innego w systemie. To pasuje do TDD. Cykl TDD wygląda następująco:
Mniej oczywiste w zastosowaniu TDD jest to, że zmienia sposób pisania kodu . Zmuszając się do myślenia o tym, jak przetestować / sprawdzić poprawność działania kodu, piszesz testowalny kod. A ponieważ mówimy o testowaniu jednostkowym, zwykle oznacza to, że kod staje się bardziej modułowy. Dla mnie modułowy i testowalny kod to duża wygrana.
Czy musisz teraz przetestować takie właściwości, jak C #? Wyobraź sobie właściwość zdefiniowaną w ten sposób:
Odpowiedź brzmiałaby „nie”, nie warto testować, ponieważ w tym momencie testujesz funkcję języka. Ufaj, że faceci z platformy C # mają rację. Poza tym, jeśli nie powiodła się, co mógłby zrobić, aby to naprawić?
Przekonasz się również, że istnieją pewne części twojego kodu, które bardzo dobrze będą wymagały zbyt dużego wysiłku, aby poprawnie przetestować. Oznacza to, że nie rób tego, ale upewnij się, że testujesz kod, który używa / jest używany przez trudny problem:
Wierz lub nie, TDD pomoże ci wpaść w zrównoważone tempo rozwoju. Nie dzieje się tak z powodu magii, ale raczej dlatego, że masz ścisłą pętlę sprzężenia zwrotnego i jesteś w stanie szybko złapać naprawdę głupie błędy. Koszt naprawienia tych błędów jest zasadniczo stały (przynajmniej wystarczający do celów planowania), ponieważ małe błędy nigdy nie stają się dużymi błędami. Porównaj to z masywną naturą sprintów do usuwania kodu i usuwania błędów.
źródło
Musisz zrównoważyć koszt testowania z kosztem błędów.
Pisanie 10-liniowego testu jednostkowego dla funkcji, która otwiera plik, w przypadku niepowodzenia „brak pliku” jest bezcelowe.
Funkcja, która robi coś złożonego ze złożoną strukturą danych - wtedy oczywiście tak.
Podstępny bit znajduje się pomiędzy. Pamiętaj jednak, że prawdziwą wartością testów jednostkowych nie jest testowanie konkretnej funkcji, lecz testowanie trudnych interakcji między nimi. Zatem test jednostkowy, który wykrył zmianę jednego bitu kodu, psuje jakąś funkcję w innym module oddalonym o 1000 linii, jest wart swojej wagi w kawie.
źródło
Testowanie to hazard.
Utworzenie testu to zakład, że koszt błędów w jednostce, które się pojawią i ich nie złapanie w tym teście (teraz i podczas wszystkich przyszłych poprawek kodu) jest większy niż koszt opracowania testu. Te koszty opracowywania testów obejmują między innymi płacę za dodatkową inżynierię testów, dodatkowy czas wprowadzenia na rynek, utracone koszty alternatywne wynikające z braku kodowania innych rzeczy itp.
Jak każdy zakład, czasami wygrywasz, czasem przegrywasz.
Czasami późne oprogramowanie z znacznie mniejszą liczbą błędów wygrywa z szybkimi, ale błędnymi rzeczami, które trafiają na rynek jako pierwsze. Czasem odwrotnie. Musisz spojrzeć na statystyki w swojej dziedzinie i na ile zarząd chce grać.
Niektóre rodzaje błędów mogą być tak mało prawdopodobne, aby były wykonane, lub nie mogły zostać wykorzystane na wczesnych testach poczytalności, ponieważ statystycznie nie warto poświęcać czasu na tworzenie dodatkowych konkretnych testów. Ale czasami koszt błędu jest tak wielki (medyczny, nuklearny itp.), Że firma musi postawić przegrany zakład (podobnie jak zakup ubezpieczenia). Wiele aplikacji nie wiąże się z tak wysokimi kosztami awarii, a zatem nie potrzebuje wyższej nieekonomicznej ochrony ubezpieczeniowej. Inni tak.
źródło
Radzę przetestować tylko kod, który chcesz poprawnie działać.
Nie testuj kodu, który ma być błędem i powodować problemy w przyszłości.
źródło
TDD i testy jednostkowe to nie to samo.
Możesz napisać kod, a następnie dodać testy jednostkowe później. To nie jest TDD i wymaga dużo dodatkowej pracy.
TDD to praktyka kodowania w pętli czerwonego światła. Zielone światło. Refaktoryzuj iteracje.
Oznacza to pisanie testów dla kodu, który jeszcze nie istnieje, obserwowanie niepowodzenia testów, poprawianie kodu, aby testy działały, a następnie poprawianie kodu. To często oszczędza ci pracy
Jedną z zalet TDD jest to, że zmniejsza potrzebę myślenia o ciekawostkach. Rzeczy, takie jak błędy indywidualne, znikają. Nie musisz przeszukiwać dokumentacji API, aby dowiedzieć się, czy lista, którą zwraca, zaczyna się od 0 lub 1, po prostu zrób to.
źródło
Pracowałem nad systemem, w którym testowaliśmy prawie wszystko. Ważnymi wykonaniami do testowania były kod wyjściowy PDF i XLS.
Dlaczego? Byliśmy w stanie przetestować części, które zgromadziły dane i zbudowaliśmy model, który został użyty do utworzenia danych wyjściowych. Byliśmy również w stanie przetestować części, które wymyśliły, które części modelu przejdą do plików PDF. Nie byliśmy w stanie sprawdzić, czy plik PDF wyglądał dobrze, ponieważ było to całkowicie subiektywne. Nie byliśmy w stanie sprawdzić, czy wszystkie części w pliku PDF były czytelne dla typowego użytkownika, ponieważ było to również subiektywne. Lub jeśli wybór między wykresami słupkowymi i kołowymi był prawidłowy dla zestawu danych.
Jeśli dane wyjściowe będą subiektywne, niewiele jest testów jednostkowych, dzięki czemu można zrobić tyle, ile warto.
źródło
W wielu przypadkach „test zapisu i ręczny” nie zajmuje więcej czasu niż napisanie kilku testów. Oszczędności czasu wynikają z możliwości ponownego uruchomienia tych testów w dowolnym momencie.
Pomyśl o tym: Jeśli masz jakiś przyzwoity zasięg funkcji ze swoich testów (nie mylić z pokrycia kodu) i powiedzmy masz 10 możliwości - kliknięcie przycisku oznacza, że z grubsza 10 yous wielokrotnego robi swoje badania ... podczas gdy ty siadasz i popijasz kawę.
Także nie ma przetestować minutae. Możesz pisać testy integracyjne, które obejmują twoje funkcje, jeśli nie chcesz zagłębiać się w drobiazgowe szczegóły ... IMO, niektóre testy jednostkowe są zbyt szczegółowe, testując język i platformę, a nie kod.
TL; DR To naprawdę nigdy nie jest właściwe, ponieważ korzyści są po prostu zbyt dobre.
źródło
Dwie bardzo dobre odpowiedzi, na które natrafiłem, są tutaj:
Uzasadnienie unikania postrzeganego narzutu:
Czy nie chciałbyś zostawić ze swojej strony świetnego produktu jako dowodu jakości swojej pracy? Mówiąc samolubnie, czy nie jest to dla ciebie lepsze?
źródło
Profesjonalni programiści piszą testy jednostkowe, ponieważ w dłuższej perspektywie oszczędzają czas. Wcześniej czy później zamierzasz przetestować swój kod, a jeśli tego nie zrobią użytkownicy, a jeśli będziesz musiał później naprawić błędy, trudniej będzie je naprawić i będzie miał więcej efektów powalających.
Jeśli piszesz kod bez testów i nie ma błędów, to dobrze. Nie sądzę jednak, aby można było napisać nietrywialny system z zerowymi błędami, więc zakładam, że testujesz go w ten czy inny sposób.
Testy jednostkowe są również niezbędne, aby zapobiec regresjom podczas modyfikacji lub refaktoryzacji starszego kodu. Nie dowodzą, że twoja zmiana nie złamała starego kodu, ale dają ci dużo pewności siebie (o ile oczywiście przejdą :))
Nie wracałbym i nie napisałbym całej partii testów dla kodu, który już wysłałeś, ale następnym razem, gdy będziesz musiał zmodyfikować funkcję, sugeruję, aby spróbować napisać testy dla tego modułu lub klasy, aby uzyskać zasięg do 70% + przed zastosowaniem jakichkolwiek zmian. Sprawdź, czy to ci pomoże.
Jeśli spróbujesz i możesz szczerze powiedzieć, że to nie była pomoc, to wystarczająco uczciwa, ale myślę, że istnieje wystarczająca ilość dowodów branżowych, że pomagają sprawić, by była przynajmniej warta wypróbowania tego podejścia.
źródło
Wygląda na to, że większość odpowiedzi jest pro-TDD, chociaż pytanie nie dotyczyło TDD, ale ogólnie testów jednostkowych.
Nie ma całkowicie obiektywnej zasady dotyczącej tego, co należy testować, a czego nie. Ale zdarza się, że wielu programistów nie testuje jednostkowo:
W zależności od filozofii OOP możesz tworzyć prywatne metody oddzielania złożonych procedur od metod publicznych. Metody publiczne są zwykle przeznaczone do wywoływania w wielu różnych miejscach i często używane, a metody prywatne są tak naprawdę wywoływane tylko przez jedną lub dwie metody publiczne w klasie lub module, aby uzyskać coś bardzo konkretnego. Zwykle wystarczy napisać testy jednostkowe dla metod publicznych, ale nie podstawowe metody prywatne, które powodują magię. Jeśli coś pójdzie nie tak z metodą prywatną, publiczne testy jednostkowe metody powinny być wystarczająco dobre, aby wykryć te problemy.
Wielu nowych programistów sprzeciwia się temu, kiedy uczą się najpierw testować i myślą, że muszą przetestować każdą wykonywaną linię. Jeśli korzystasz z zewnętrznej biblioteki, a jej funkcjonalność jest dobrze przetestowana i udokumentowana przez jej autorów, zwykle nie ma sensu testować konkretnej funkcjonalności w testach jednostkowych. Na przykład ktoś może napisać test, aby upewnić się, że jego model ActiveRecord utrzymuje poprawną wartość atrybutu z wywołaniem zwrotnym „before_save” do bazy danych, nawet jeśli samo to zachowanie jest już dokładnie przetestowane w Railsach. Metoda może wywoływać funkcję zwrotną, ale nie samo zachowanie wywołania zwrotnego. Wszelkie podstawowe problemy z importowanymi bibliotekami lepiej byłoby ujawnić za pomocą testów akceptacyjnych niż testów jednostkowych.
Oba mogą mieć zastosowanie niezależnie od tego, czy robisz TDD, czy nie.
źródło
Ken, ja i wielu innych programistów doszliśmy do tego samego wniosku co ty kilka razy w ciągu naszej kariery.
Prawda, którą, jak sądzę, znajdziesz (podobnie jak wiele innych), jest taka, że początkowa inwestycja w pisanie testów dla twojej aplikacji może wydawać się zniechęcająca, ale jeśli dobrze napisana i ukierunkowana na właściwe części twojego kodu, może naprawdę zaoszczędzić mnóstwo czasu.
Moim wielkim problemem były dostępne ramy testowe. Nigdy tak naprawdę nie czułem, że są tym, czego szukałem, więc właśnie opracowałem własne bardzo proste rozwiązanie. To naprawdę pomogło mi przenieść się na „ciemną stronę” testów regresji. Podzielę się podstawowym pseudo fragmentem tego, co tutaj zrobiłem, i mam nadzieję, że znajdziesz rozwiązanie, które będzie dla ciebie odpowiednie.
Jedyną trudną częścią po tym jest ustalenie, jaki poziom szczegółowości uważasz za najlepszy „huk za grosze” dla każdego projektu.
Zbudowanie książki adresowej będzie oczywiście wymagało znacznie mniej testów niż wyszukiwarka korporacyjna, ale podstawy tak naprawdę się nie zmieniają.
Powodzenia!
źródło