To, jak cenne jest konkretne podejście do testowania, zależy od tego, jak krytyczny jest opracowywany system i jak bardzo zależy od niego inny system o krytycznym znaczeniu. Prostego skryptu księgi gości dla Twojej witryny nie można uznać za kluczowy dla misji, ale jeśli witryna, na której działa, może zostać zagrożona przez błąd, który umożliwił niefiltrowane dane wejściowe do bazy danych, a strona ta oferuje pewną istotną usługę, nagle staje się znacznie bardziej ważne, aby skrypt księgi gości został dokładnie przetestowany. To samo dotyczy kodu frameworka / biblioteki. Jeśli opracujesz platformę z błędem, każda aplikacja korzystająca z tej funkcji ma również ten sam błąd.
Rozwój oparty na testach zapewnia dodatkową warstwę bezpieczeństwa, jeśli chodzi o testy. Jeśli napiszesz testy obok lub nawet po kodzie, który chcesz przetestować, istnieje realne ryzyko, że pomylisz testy. Jeśli najpierw napiszesz wszystkie testy, to sposób, w jaki kod działa wewnętrznie, nie może wpłynąć na to, dla czego piszesz testy, dlatego istnieje mniejsze prawdopodobieństwo, że przypadkowo napiszesz testy, które uznają, że dane dane są błędne.
Programowanie testowe zachęca również programistów do pisania kodu, który jest łatwy do przetestowania, ponieważ nie chcą poświęcać sobie więcej pracy! Kod, który jest łatwy do przetestowania, zwykle jest kodem łatwym do zrozumienia, ponownego wykorzystania i konserwacji.
A konserwacja to miejsce, w którym naprawdę będziesz czerpać korzyści z TDD. Zdecydowana większość wysiłku programistycznego poświęconego oprogramowaniu jest związana z konserwacją. Oznacza to dokonywanie zmian w kodzie aktywnym, aby nadać mu nowe funkcje, naprawić błędy lub dostosować go do nowych sytuacji. Dokonując takich zmian, chcesz mieć pewność, że wprowadzone zmiany mają pożądany efekt, a co ważniejsze, nie powodują nieoczekiwanego efektu domina. Jeśli masz pełny pakiet testowy dla swojego kodu, łatwo jest sprawdzić, czy wszelkie wprowadzone zmiany nie psują czegoś innego, a jeśli wprowadzone zmiany powodują uszkodzenie czegoś innego, możesz szybko znaleźć przyczynę. Korzyści są długoterminowe.
W swoim pytaniu powiedziałeś:
Widzę pewne korzyści z pisania testów dla niektórych rzeczy, ale bardzo niewiele. I chociaż podoba mi się pomysł, aby najpierw napisać test, okazuje się, że spędzam znacznie więcej czasu na debugowaniu moich testów, aby powiedzieć im, co naprawdę mam na myśli, niż debugowanie faktycznego kodu. Jest to prawdopodobnie spowodowane tym, że kod testowy jest często znacznie bardziej skomplikowany niż kod testowany. Mam nadzieję, że jest to po prostu brak doświadczenia z dostępnymi narzędziami (w tym przypadku rspec).
To wydaje mi się sugerować, że nie do końca się testujesz. Test jednostkowy ma być niezwykle prosty, po prostu sekwencja wywołań metod, po których następuje stwierdzenie, aby porównać oczekiwany wynik z faktycznym wynikiem. Mają być proste, ponieważ błędy w twoich testach byłyby katastrofalne, a jeśli wprowadzisz do testu pętle, rozgałęzienia lub inne sterowanie rzutami programu, wtedy bardziej prawdopodobne jest, że w teście zostanie wprowadzony błąd. Jeśli spędzasz dużo czasu na debugowaniu testów, oznacza to, że twoje testy są zbyt skomplikowane i powinieneś je uprościć.
Jeśli testów nie można uprościć, sam ten fakt sugeruje, że coś jest nie tak z testowanym kodem. Na przykład, jeśli twoja klasa ma długie metody, metody z wieloma instrukcjami if / elseif / else lub switch lub dużą liczbą metod, które mają złożone interakcje podyktowane obecnym stanem klasy, testy z konieczności będą musiały być niezwykle złożone aby zapewnić pełne pokrycie kodu i przetestować wszystkie ewentualności. Jeśli twoja klasa ma zakodowane na stałe zależności od innych klas, to ponownie zwiększy liczbę obręczy, do których będziesz musiał przejść, aby skutecznie przetestować swój kod.
Jeśli utrzymujesz swoje klasy małe i wysoce skoncentrowane, przy użyciu krótkich metod z kilkoma ścieżkami wykonywania i próbujesz wyeliminować stan wewnętrzny, testy można uprościć. I to jest sedno sprawy. Dobry kod jest z natury łatwy do przetestowania. Jeśli kod nie jest łatwy do przetestowania, prawdopodobnie jest z nim coś nie tak.
Pisanie testów jednostkowych przynosi korzyści na dłuższą metę, a unikanie ich to po prostu gromadzenie problemów na później. Być może nie znasz pojęcia długu technicznego, ale działa on podobnie jak dług finansowy. Nie pisanie testów, nie komentowanie kodu, pisanie w zakodowanych na stałe zależnościach, a więc sposoby na zadłużenie się. „Pożyczasz” czas, wcześnie skracając rogi, co może pomóc ci dotrzymać napiętego terminu, ale oszczędzasz czas wcześniej w projekcie. Każdy dzień, który mija bez czyszczenia kodu, prawidłowe komentowanie go lub zbudowanie pakietu testowego będzie Cię kosztować. Im dłużej to trwa, tym większe jest zainteresowanie. W końcu odkryjesz, że Twój kod stał się splątanym bałaganem, do którego nie możesz wprowadzać zmian bez wywoływania niezamierzonych konsekwencji.
Możesz pomyśleć o pisaniu testów jednostkowych wcześnie i aktualizowaniu ich jako formie „kredytu technicznego”. Czas spędzasz w banku, spędzając go wcześnie w projekcie na przestrzeganie dobrych praktyk. Zyskasz zainteresowanie tym foresightem później, gdy przejdziesz do fazy konserwacji projektu. Kiedy chcesz dokonać zmiany, możesz łatwo zweryfikować poprawność zmiany i że nie ma ona żadnych niepożądanych efektów ubocznych, a także możesz szybko otrzymywać aktualizacje bez problemów. Jeśli pojawią się błędy, możesz dodać nowy test jednostkowy, który wykonuje błąd, a następnie napraw błąd w kodzie. Przy następnym uruchomieniu testu jednostkowego będziesz mógł sprawdzić, czy błąd został naprawiony i że nie spowodował żadnych innych problemów. Co więcej, unikniesz „regresji”,
TL: DR - Tak, to pomoc w prawdziwym świecie, ale to inwestycja. Korzyści stają się widoczne dopiero później.