Automatyzacja testów stała się niemalże standardem w projektach IT. Mimo licznych zalet, nie brakuje jednak przykładów, gdy ambitne plany automatyzacji kończą się spektakularnym fiaskiem. Co więcej – takie sytuacje są znacznie częstsze, niż mogłoby się wydawać.
Dlaczego tak się dzieje? Poniżej zebrałem trzy najczęstsze problemy, które miałem okazję obserwować w różnych projektach automatyzacji.
Brak jasno określonego celu automatyzacji
W projektach automatyzacji testów często można spotkać się z podejściem „automatyzujemy wszystko” – wtedy celem jest pokrycie testami jak najwięcej funkcjonalności w obrębie aplikacji.
Według mnie jest to błąd. Osobiście preferuję podejście, w którym testy automatyczne UI pokrywają jedynie ścieżki krytyczne i inne scenariusze o najwyższym priorytecie. Pozostałymi scenariuszami mogą zająć się np. testy automatyczne API.
Skąd takie podejście? Przede wszystkim dlatego, że testy UI są zazwyczaj najbardziej podatne na awarie i najdroższe w utrzymaniu. Każda zmiana w interfejsie – nawet kosmetyczna – może skutkować koniecznością aktualizacji wielu testów. Zbyt szerokie pokrycie funkcjonalności na poziomie UI szybko prowadzi do sytuacji, w której więcej czasu spędza się na poprawianiu testów niż na ich uruchamianiu.
Kluczowe ścieżki aplikacji powinny być monitorowane automatycznie na warstwie UI, bo to ich awaria niesie największe ryzyko. Resztę lepiej testować tam, gdzie jest to tańsze, szybsze i bardziej stabilne – czyli na poziomie API.
Niestabilne testy
To jest temat rzeka. Bardzo często można zaobserwować testy automatyczne, które napisane są tak, że ich wynik jest nieprzewidywalny. Raz przechodzą bez problemu, innym razem – mimo braku zmian w kodzie – kończą się błędem. Albo – lokalnie wszystko działa poprawnie, ale na CI test potrafi się wysypać bez wyraźnej przyczyny. Tego typu testy są nazywane niestabilnymi (ang. flaky tests) – i stanowią jedno z największych zagrożeń dla skutecznej automatyzacji.
Niestabilność testów zwykle wynika z braku oczekiwania na załadowanie elementów na stronie, zależności testów od siebie nawzajem lub niestabilnego środowiska. Częstą przyczyną są też słabe selektory, które przestają działać po niewielkich zmianach w UI.
Największy problem z niestabilnymi testami polega na tym, że zespół przestaje im ufać. Jeśli test raz działa, a raz nie – jego wyniki przestają być brane pod uwagę, a z czasem to samo dzieje się z całą automatyzacją. Zamiast wspierać jakość – zaczyna szkodzić.
Jak w takim razie pisać stabilne testy? Na ten temat napisaliśmy osobny artykuł, ale w dużym skrócie należy:
- dbać o niezależność i izolację testów
- stosować dynamiczne oczekiwania na elementy (explicit waity w Selenium, auto-waity w Playwright)
- używać selektorów w miarę możliwości odpornych na zmiany w UI
Brak sensownego raportowania
Z własnego doświadczenia mogę stwierdzić, że jeśli „raport” z testów automatycznych to nieczytelny, zagnieżdżony JSON lub po prostu zbiór logów, większość zespołu nie będzie tam zaglądać i nie będzie analizować błędów sygnalizowanych przez test.
Dobre testy automatyczne to nie tylko kod testowy, ale też skuteczny mechanizm raportowania. Zrozumiały raport z testu (np. generowany z pomocą biblioteki Allure), zawierający logi, zrzuty ekranu i przebieg testu krok po kroku, pozwala szybko zidentyfikować przyczynę problemu i realnie skraca czas reakcji zespołu.
W pracy projektowej dobrze sprawdziła się także integracja testów ze Slackiem – skrócone wyniki były automatycznie wysyłane na jeden z kanałów, co pozwalało zespołowi szybko reagować na znalezione błędy.