Oskar Dudycz

Pragmatic about programming

Gdy testy jednostkowe to nie wszystko

2019-12-16 oskar dudyczTesty

Cześć!

Czy wiesz, że jeszcze nie ma zimy? Pewnie, że wiesz, przecież widzisz co jest za oknem. Ale czy wiesz, że formalnie nawet jest jeszcze jesień, czy nie narzekasz, że kiedyś to były zimy? Zima zaczyna się formalnie 22 grudnia. W “Chłopaki nie płaczą” Fred opowiada historię swojej miłości, o tym, że za swoją ukochaną kiedyś dałby sobie rękę uciąć, no i na szczęście nie musiał ręczyć, bo by teraz k… ręki nie miał. Czy pierogi ruskie są ruskie? Co więcej, Amerykanie myślą, że Pierogi to liczba pojedyncza i piszą potem “Pierogis”.

Jedną z moich ulubionych moich anegdot to gdy Maciek Żurawski, jeden z naszych najbardziej eksportowych napastników w “Erze przed Lewandowskim” wyjechał do Celitcu Glasgow. Nasi dziennikarze byli mega podjarani i tworzyli spore nagłówki, że szkoccy kibice mówili o nim “Magic”. Nie wiedzieli jednak, że w języku angielskim tak niepozorne słowo dla nas jak Maciek jest nie do wymówienia, a w zasadzie wypowiadane brzmi jako “Maczik”, które to już zupełnie łatwo posądzić o brzmienie jak “Medżik”.

Gdy zaczynałem ponad 12 lat swoją karierę (hoho, dumnie brzmi) programisty to czasy były zupełnie inne niż teraz. Na imprezie będąc zapytanym przez dziewczynę, o to czym się zajmuję zdecydowanie bezpieczniejszą opcją było udać, że się nie słyszy i zmienić temat aby Jej nie odstraszyć perspektywą rozmowy z programistą. Nie było też Stack Overflow. No i nie było testów jednostkowych. Dzikie czasy.

Dopiero po 3 latach kariery udało mi się je wprowadzić nieskładne w swoim projekcie, a po 4 latach pracować w takim gdzie one były traktowane jako rzecz wymagana.

Do dziś mimo prób nie piszę najpierw testów potem kodu, w każdym razie nie zawsze, ale mam od 2,5 roku klienta gdzie Code Coverage nie może zejść poniżej 85% bo build się nie przekręci.

Od bandy do bandy.

I tak pomiędzy tymi bandami znajduje się niestety spora część z nas. Szczególnie programistów backendowych, a już w moim światku .NET obserwuję to niestety nagminnie. Część z nas w końcu dała się przekonać do testów jednostkowych i potraktowała to jako okazję do tego by wreszcie móc pozbyć się konieczności klikania po aplikacji, a jeszcze lepiej odcięcia tych paskudnych testerów, którzy uprzykrzają nam życie. Część z nas poszła nawet dalej i zaczęła uważać, że nasza praca kończy się na napisaniu kodu i testów jednostkowych i wystawienia PRa. Merdż już lepiej niech zrobi kto inny. W połączeniu z CI i CD dostaliśmy nasz zamknięty świat gdzie jesteśmy my i nasz kod. Wszystko zależy od nas. Komunikacja to na kawie i piłkarzykach lub przy lunchu, a nie przy programowaniu. Zamykamy się w naszym bezpiecznym światku. Tak jak Fred dajemy sobie rękę uciąć za nasze testy jednostkowe. Code Coverage mylimy z poziomem przetestowania funkcjonalności.

Unikamy też najchętniej testów integracyjnych i akceptacyjnych, bo to już trzeba wyjść poza nasze pudełko. To niech sobie już ktoś inny napisze. A jak coś wyjdzie to nie bug tylko feature.

Nie zrozumcie mnie źle, nie mówię tutaj w stylu “ło panie, kiedyś to samochodów nie było, końmi się jeździło, teraz też można”. To co próbuję powiedzieć to to, żebyśmy podchodzili pragmatycznie do tego co robimy i nie szukali złotego środka, który zrobi za nas robotę. Testy jednostkowe są konieczne, to jest punkt wyjścia, który broni nas przed regresją, zwiększa komfort pracy oraz pewność i poczucie spokoju. Byle nie było ono złudne. Testy jednostkowe tak naprawdę tylko i aż nadają się do testów tego co sami napisaliśmy, tego za co sami odpowiadamy. Co więcej tylko za te scenariusze, które znamy. Jeżeli używamy zewnętrznych bibliotek to będziemy w stanie przetestować tylko nasze wyobrażenie i wiedzę na ich temat. Przykładowo w Martenie świadomie nie udostępniliśmy tak jak EF kontekst in memory. Wiemy, że nasze Queryable ma swoje braki i może działać inaczej niż zapytania na kolekcjach w pamięci. Gdyby użytkownicy w pełni polegali na przeświadczeniu, że jak przetestują sobie jednostkowo Query w pa mięci i zadziała to potem przy wdrożeniu okazałoby się, że nie bardzo. Nie dawno takie zdziwko mieli użytkownicy EF. Zobacz więcej tutaj.

Co gorsza jeśli używamy intensywnie Mocków to tak naprawdę w ogóle testujemy funkcjonalność na bazie już naszego wyobrażenia o implementacji przygotowanej przez innych. Potem się okazuje, że ktoś to inaczej zrozumiał i z Maćka wyszedł nam Magic.

Nie każę Ci teraz rezygnować z testów jednostkowych, wręcz przeciwnie - zachęcam do TDD i posiadania 100% Code Coverage. To co chcę powiedzieć to, żeby podchodzić do tego z głową i pamiętać, że to tylko punkt wyjścia, który jest do podstawowej weryfikacji tego co sami robimy. Nie możemy zapewniać, że są rzeczy, o których możemy nie wiedzieć, które możemy źle zinterpretować. Jeśli chcemy robić dobrze swoją robotę to zainteresujmy się co może się wydarzyć gdy naszą pełnoletnią funkcjonalność puścimy na swoje. Upewnijmy się, że ją do tego dobrze przygotowaliśmy. Choćby testem integracyjnym, choćby dobrym testem manualnym od testera czy po prostu dialogiem z koleżanką/kolegą z innego zespołu upewniając się, że dobrze wszystko rozumiemy.

A jakie jest Twoje zdanie? Zgadzasz się ze mną czy nie bardzo? Coś wyraziłem nieprecyzyjnie?

Jak wygląda to u Ciebie w projekcie?

Z góry dziękuję za odpowiedź i pozdrawiam serdecznie!

Oskar

P.S. pisałem we wcześniejszych newsletterach o webinarze, nie wyrobiłem się, a teraz przed świętami nie będę Ci zawracał tym głowy, ale nie ucieknie, na początku stycznia na pewno się pojawi.

  • © Oskar Dudycz 2019-2020