Chociaż jestem za testowaniem jednostkowym, czasami zastanawiam się, czy ta forma testowania pierwszego rozwoju jest naprawdę korzystna ...
Małe, trywialne testy, takie jak ten, mogą być „kanarkiem w kopalni” dla Twojej bazy kodów, ostrzegając o niebezpieczeństwie, zanim będzie za późno. Trywialne testy są przydatne, ponieważ pomagają w prawidłowym przeprowadzaniu interakcji.
Na przykład pomyśl o trywialnym teście wprowadzonym w celu zbadania, jak korzystać z interfejsu API, którego nie znasz. Jeśli ten test ma jakikolwiek związek z tym, co robisz w kodzie, który używa interfejsu API „w rzeczywistości”, warto go zachować. Kiedy API wyda nową wersję i musisz zaktualizować. Masz teraz swoje założenia dotyczące oczekiwanego zachowania interfejsu API zapisane w formacie wykonywalnym, którego można użyć do przechwytywania regresji.
... [ja] w rzeczywistym procesie masz 3-4 warstwy nad swoim kodem (wniosek biznesowy, dokument wymagań, dokument architektury), w których rzeczywista zdefiniowana reguła biznesowa (cena rabatowa to cena - rabat) może być błędnie zdefiniowana. Jeśli tak jest, twój test jednostkowy nic dla ciebie nie znaczy.
Jeśli od lat programujesz bez pisania testów, może nie być od razu oczywiste, że ma to jakąkolwiek wartość. Ale jeśli myślisz, że najlepszym sposobem pracy jest „wydawanie wczesne, wydawanie często” lub „zwinność”, ponieważ chcesz mieć możliwość szybkiego / ciągłego wdrażania, to Twój test zdecydowanie coś znaczy. Jedynym sposobem na to jest legitymizowanie każdej zmiany wprowadzanej w kodzie za pomocą testu. Bez względu na to, jak mały jest test, po uzyskaniu zielonego zestawu testów teoretycznie można je wdrożyć. Zobacz także „ciągła produkcja” i „wieczysta wersja beta”.
Nie musisz też najpierw „testować”, aby mieć taki sposób myślenia, ale jest to generalnie najskuteczniejszy sposób, aby się tam dostać. Kiedy wykonujesz TDD, zamykasz się w małym, trwającym od dwóch do trzech minut cyklu Red Green Refactor. W żadnym momencie nie jesteś w stanie zatrzymać się i wyjść i mieć kompletnego bałaganu na rękach, którego debugowanie i ponowne złożenie zajmie godzinę.
Dodatkowo twój test jednostkowy jest kolejnym punktem niepowodzenia ...
Pomyślny test to taki, który wykazuje awarię w systemie. Niepowodzenie testu ostrzeże Cię o błędzie w logice testu lub w logice Twojego systemu. Celem testów jest złamanie kodu lub udowodnienie, że jeden scenariusz działa.
Jeśli piszesz testy po kodzie, ryzykujesz napisaniem testu, który jest „zły”, ponieważ aby zobaczyć, że Twój test naprawdę działa, musisz zobaczyć, że jest on zarówno uszkodzony, jak i działa. Kiedy piszesz testy po kodzie, oznacza to, że musisz „wyzwolić pułapkę” i wprowadzić błąd do kodu, aby zobaczyć, że test się nie powiedzie. Większość programistów nie tylko jest z tego powodu zaniepokojona, ale twierdzi, że jest to strata czasu.
Co tu zyskujemy?
Robienie rzeczy w ten sposób zdecydowanie przynosi korzyści. Michael Feathers definiuje „stary kod” jako „nieprzetestowany kod”. Stosując to podejście, legitymizujesz każdą zmianę wprowadzoną w bazie kodu. Jest to bardziej rygorystyczne niż niestosowanie testów, ale jeśli chodzi o utrzymanie dużej bazy kodu, opłaca się.
Mówiąc o piórach, są dwa świetne zasoby, które powinieneś sprawdzić w związku z tym:
Obydwa wyjaśniają, jak zastosować tego typu praktyki i dyscypliny w projektach, które nie są „greenfield”. Zapewniają techniki pisania testów wokół ściśle powiązanych komponentów, twardych zależności i rzeczy, nad którymi niekoniecznie masz kontrolę. Chodzi o znalezienie „szwów” i przetestowanie ich.
[I] Jeśli cena rabatu jest nieprawidłowa, zespół testowy nadal znajdzie problem, w jaki sposób testy jednostkowe uratowały jakąkolwiek pracę?
Takie nawyki są jak inwestycja. Zwroty nie są natychmiastowe; z czasem narastają. Alternatywą dla braku testowania jest zasadniczo zaciągnięcie długu w postaci braku możliwości wychwycenia regresji, wprowadzenia kodu bez obawy o błędy integracji lub podejmowania decyzji projektowych. Piękno polega na tym, że legitymizujesz każdą zmianę wprowadzoną w swoim kodzie.
Czego tu brakuje? Naucz mnie kochać TDD, ponieważ do tej pory ciężko mi zaakceptować to jako przydatne. Ja też chcę, ponieważ chcę być postępowy, ale to po prostu nie ma dla mnie sensu.
Traktuję to jako odpowiedzialność zawodową. To ideał, do którego warto dążyć. Ale jest to bardzo trudne i nużące. Jeśli zależy ci na tym i uważasz, że nie powinieneś tworzyć kodu, który nie jest testowany, będziesz w stanie znaleźć siłę woli, aby nauczyć się dobrych nawyków testowania. Jedną z rzeczy, które robię teraz (podobnie jak inni), jest czas na samodzielne pisanie kodu bez żadnych testów, a następnie posiadanie dyscypliny, aby go wyrzucić. Może się to wydawać marnotrawstwem, ale tak nie jest. To nie jest tak, że to ćwiczenie kosztuje firmowe materiały fizyczne. Pomogło mi to zrozumieć problem i jak pisać kod w taki sposób, aby był zarówno wyższej jakości, jak i testowalny.
Moja rada byłaby taka, że jeśli naprawdę nie masz ochoty być w tym dobrym, to w ogóle tego nie rób. Słabe testy, które nie są utrzymywane, nie działają dobrze itp. Mogą być gorsze niż brak jakichkolwiek testów. Trudno jest się uczyć samemu i prawdopodobnie nie spodoba ci się to, ale nauka będzie prawie niemożliwa, jeśli nie masz ochoty tego robić lub nie widzisz w tym wystarczającej wartości gwarantuje inwestycję czasu.
Kilka osób wspomina, że testowanie pomaga egzekwować zgodność ze specyfikacją. Z mojego doświadczenia wynika, że specyfikacja również się myliła, najczęściej ...
Klawiatura programisty to miejsce, w którym guma styka się z drogą. Jeśli specyfikacja jest nieprawidłowa i nie podnosisz na niej flagi, jest wysoce prawdopodobne, że zostaniesz za to obwiniony. A przynajmniej twój kod będzie. Dyscyplina i rygor związany z testowaniem jest trudny do przestrzegania. To wcale nie jest łatwe. Wymaga praktyki, dużo nauki i wielu błędów. Ale ostatecznie to się opłaca. W szybko zmieniającym się projekcie to jedyny sposób, w jaki możesz spać w nocy, bez względu na to, czy spowalnia.
Inną rzeczą do przemyślenia jest to, że techniki, które są zasadniczo takie same jak testowanie, okazały się działać w przeszłości: „pomieszczenie czyste” i „projektowanie na podstawie umowy” mają tendencję do tworzenia tych samych typów konstrukcji kodu „meta”, które testy robią i wymuszają je w różnych punktach. Żadna z tych technik nie jest srebrną kulą, a rygor ostatecznie będzie Cię kosztował w zakresie funkcji, które możesz dostarczyć pod względem czasu wprowadzenia na rynek. Ale nie o to chodzi. Chodzi o to, aby móc utrzymać to, co dostarczasz. Jest to bardzo ważne w przypadku większości projektów.