#7 Antywzorce w testowaniu oprogramowania: Niestabilne lub powolne testy

10 stycznia 2021 | Trochę teorii, Uczymy się!

Nie powiem, bolesny to dla mnie temat. Z niestabilnymi testami w tej chwili walczę już trzeci miesiąc – bezskutecznie i nie bez ofiar. A do tego ta powolność… To temat na co najmniej przydługawy esej. Specyfikacja oprogramowania, które jest pod opieką współtworzonych przeze mnie testów automatycznych nie ułatwia zadania w żaden sposób, a pewne zaniedbania z przeszłości czynią testy już nie Hydrę, w której na miejsce jednego rozwiązanego problemu pojawia się kolejnych kilka, a wręcz Uroborosa, który zjada własny ogon: przyspieszenie testów zmniejsza ich stabilność, stabilizacja – spowalnia.

Kostis Kapelonis, autor listy antywzorców, na której wzoruję mój cykl artykułów podkreśla, a ja się z nim zgadzam, że dzisiejszy temat jest całkiem już przerobiony. Ale wciąż aktualny, co pokazuje przykład moich testów, dlatego warto o nim rozmawiać i ciągle przypominać. Dlatego dzisiaj o tym, dlaczego powolność i niestabilność zdecydowanie możemy uznać za antywzorzec.

Myślę, że wszyscy będziemy zgodni, że głównym zadaniem testów automatycznych – jako mających odciążyć inżynierów z pracy najbardziej powtarzalnej i żmudnej – jest jak najwcześniejsze wykrywanie regresji, W związku z tym zwykle chcielibyśmy na nich polegać. Prowadzi to do wniosku, że jednak dobrze by więc było, gdyby działały w sposób niezawodny – wszak czy nie na tym opieramy wiarę w pewne rozwiązania? Niepowodzenie testu powinno być łatwo rozpoznawalne przez wszystkich w zespole (a czasem nawet poza nim). A nie zawsze tak się dzieje – jeżeli nasze testy naszpikowane są „fałszywymi alarmami” w postaci niepowodzenia testu przy minimalnym spowolnieniu ruchu sieciowego czy minimalnej zmianie lokatorów na stronie, to z czasem przestajemy im ufać. Albo – podobnie jak to jest w przypadku ikonki „Check engine” w samochodzie – z czasem gotowi jesteśm sobie z tymi „sfailowanymi testami” robić selfie, ale na pewno nie opierać na nich wiary w brak regresji w naszym oprogramowaniu. Jeżeli już test kończy się niepowodzeniem, to powinien być to jednoznaczny sygnał, że gdzieś czai się usterka, a osoba odpowiedzialna za sprawdzenie wyniku powinna mieć możliwość z łatwością ustalić co się stało.

Testy, na których chcielibyśmy polegać, muszą kończyć się niepowodzeniem w ściśle określony, deterministyczny sposób – mówiąc ściślej, ich niepowodzenie powinno się wiązać z faktyczną usterką. A jeśli mamy test, który czasami kończy się niepowodzeniem, a czasem przechodzi (co często dzieje się bez żadnych zmian w kodzie pomiędzy uruchomieniami! Komu się nie zdarzyło pracować z takimi testami, niech pierwszy rzuci klawiaturą), jest on jednocześnie niewiarygodny i… podważa zasadność testów.

Inne podejście, rodzące powolność i brak stabilności testów da nam skutki dwojakie:

  • Osoby zaangażowane w development nie będą ufać już testom i szybko zignorują ich wyniki. A będzie się to nasilać wraz z dalszym rozwojem oprogramowania czy poziomem stresu wywołanego przez zbliżający się deadline.
  • W morzu niestabilności trudno będzie wykryć faktyczne usterki. Jeśli z 50 testów niepowodzeniem w każdym uruchomieniu kończy się pięć do siedmiu testów, to skąd pewność, że te dwa – zawodzące od czasu do czasu – są wynikiem niestabilności, a nie faktycznej usterki?

Swoją drogą naprawdę nawet niewielka liczba błędnych testów wystarcza, aby zniszczyć wiarygodność pozostałej części testów. Jeśli nie wiemy dlaczego testy zawodzą, to skąd mamy pewność, że te przechodzące dają nam prawdziwy obraz jakości?

Podobnym się rzecz ma z testami, które są naprawdę bardzo wolne. Jeżeli czas wykonania testów zajmuje tyle czasu, ile mogłoby zająć sprawdzenie testów manualnie, to trudno oczekiwać entuzjazmu względem takiego rozwiązania. Szczególnie, jeśli testy odpalane są pod koniec dnia pracy, a zadaniem osoby uruchamiającej jest także ich analiza. A ta – w przypadku dodatkowej niestabilności – może być czasochłonna i frustrująca.

Niestabilność i powolność jest wynikiem najczęściej skomplikowania infrastruktury testowej i samego testowanego obiektu. Dlatego w praktyce takie testy są prawie zawsze testami integracyjnymi i/lub testami interfejsu użytkownika – w miarę wspinaczki w górę piramidy testów rośnie kompilacja rozwiązania, a co za tym idzie, prawdopodobieństwo niestabilnych testów znacznie rośnie. Z mojego doświadczenia wynika, że ze znacznie większą niestabilnością i powolnością wiążą się też testy aplikacji desktopowych, których logika zwykle jest dużo bardziej zaawansowana, a dostępne rozwiązania do automatyzacji raczej pozostawiają wiele do życzenia (nie, żeby Selenium było ideałem, ale… konia z rzędem oddam za to, by nie mieć więcej styczności z TestStack.White).

Kostis Kapelonis jako propozycję szybkiej ochrony przed problemami powodowanymi przez „badziewne” testy stawia wyizolowywanie ich do osobnego zestawu testów (oczywiście przy założeniu, że rzeczywiście nie możemy ich w żaden sposób naprawić). Mam doświadczenie z podobnym rozwiązaniem i muszę przyznać, że choć nie rozwiązuje to problemu samych „wiecznie padających testów”, to przynajmniej podnosi wiarygodność tych stabilnych, a jednocześnie daje nam możliwość przechowania testów, przeczekania na lepsze czasy, kiedy będziemy mieli możliwość na przykład przeprowadzić gruntowny refactor.

No właśnie – refactor. Moim zdaniem to powinien być klucz do rozwiązania niestabilności. Nic tak nie poprawia jakości (hihi) testów, jak solidne porządki. Szczególnie, jeśli za cel tej przebudowy stawiamy sobie konkretnie uporanie się z testami, którym nikt – łącznie z twórcami – nie chce ufać. Tak czy inaczej, jeśli chcemy, aby testy dawały wymierną korzyść, powinniśmy dbać o to, aby były w pełni niezawodne, a ich weryfikacja powinna być możliwa względnie szybko po ich uruchomieniu i przez każdą osobę zaangażowaną w proces wytwarzania oprogramowania.

Najnowsze wpisy

#7 Antywzorce w testowaniu oprogramowania: Niestabilne lub powolne testy

Nie powiem, bolesny to dla mnie temat. Z niestabilnymi testami w tej chwili walczę już trzeci miesiąc – bezskutecznie i nie bez ofiar. A do tego ta powolność…

CzytanQA: Czarny Łabędź

Jak już pewnie wiecie, a jak nie wiecie, to właśnie się dowiecie, interesuję się już od dłuższego czasu błędami poznawczymi.

Biały pasek na pączkach, czyli o TQM słów kilka

Total Quality Management jako zagadnienie od dawna chciałam opisać, ponieważ właśnie ono w czasie moich studiów zapadło mi w pamięć.

Pin It on Pinterest

Podoba Ci się wpis?

Podziel się ze znajomymi!