W przeciwieństwie do testów jednostkowych i testów funkcjonalnych, używane do testowania aplikacji frontendowych testy migawkowe nie mają na celu bezpośredniego sprawdzenia poprawnego zachowania aplikacji.
Mają one wiele form, ale zazwyczaj odnoszą się do weryfikacji względem wcześniej wykonanych zrzutów danych, zrzutów ekranów, zamrożonych plików dyskowych itp.
Bazują one na porównaniu wyników, konfrontując aktualne dane (obrazy) wyjściowe z zapisanym wcześniej poprawnym wzorcem tych danych (obrazów), ale bez sprawdzania, czy zachowanie aplikacji generujące aktualny rezultat było poprawne.
Spójrzmy na poniższe formularze logowania:
Pierwotny formularz to oryginał, a widok aktualnego formularza jest widokiem po dokonanych zmianach stylistycznych. Test migawkowy, który opierałby się na obrazach, wykryłby tę różnicę i wskazał ją, nie informując przy tym, czy stylizacje były poprawne, ponieważ celem testu było po prostu podkreślenie, że coś się zmieniło.
Narzędzia
Narzędzia obsługujące testy migawkowe można podzielić na dwa rodzaje:
- Narzędzia do wykonywania migawek danych, które można serializować.
Przykładem takiego narzędzia jest Jest, który posiada wbudowaną obsługę snapshot testów, dzięki czemu wspiera ono testowanie komponentów React. Z kolei Cypress posiada opcję testowania migawek za pomocą wtyczek. - Narzędzia do wykonywania migawek wizualnych.
Do przykładów takich narzędzi zaliczamy: Intern (za pośrednictwem wtyczki wizualnej) czy wtyczkę Jest-Image-Snapshot, Applitools (przeznaczone do testowania wizualnej sztucznej inteligencji).
Działanie
Test migawkowy polega na zarejestrowaniu pewnej cechy systemu (zrobieniu migawki), a następnie porównaniu jej z bieżącą wartością cechy. Można tworzyć go z użyciem trzech sekcji:
- given – ustawienie testu i danych,
- when – uruchamiana jest akcja,
- then – sprawdzany jest wynik testu z użyciem asercji. W tej sekcji weryfikujemy, czy obecna migawka jest taka sama, jak ta znajdująca się w repozytorium. Jeśli migawki się różnią, oznacza to, że albo nastąpił regres jakości albo, że zmiany były potrzebne i wtedy należy zastąpić stary zrzut przez nowy.
Snapshot testy zazwyczaj powinny zawierać możliwie dużo przypadków testowych – im większe pokrycie, tym łatwiej można wychwycić nieprawidłowości przy zmianie kodu. Migawki często będą traktowane jak zwykły kod; przechowywane są w repozytorium i powinny być objęte code review, za pomocą którego przy porównaniu kodu z poprzednią wersją można wykrywać wszelkie różnice, nie sprawdzając przy tym aplikacji w przeglądarce.
Istnieje kilka sposobów tworzenia snapshotów. IDE, np. Intellij Idea, pozwala na włączenie testów tworzących migawki z poziomu kodu testu (oddzielnie) lub pliku z testami. Powstały w rezultacie snapshot możemy odrzucić lub zaakceptować, a w następnym kroku włączyć testy w całym repozytorium, by w ten sposób upewnić się, że regresja nie powstała gdzieś indziej.
Istotne jest, aby pamiętać o aktualizacji snapshotów, by nie dopuścić do sytuacji, w której włączenie wszystkich testów informuje nas o przestarzałych zrzutach. Może tak się stać, jeśli dla przykładu usuniemy test, ale w pliku snapshota pozostanie jeszcze kod dotyczący usuniętego przypadku testowego. Rozwiązaniem takiej sytuacji jest wygenerowanie zrzutu ponownie z użyciem Jest lub usunięcie go i ponowne wygenerowanie.
Analizując snapshoty należy zwrócić uwagę na to, czy:
- nie doszło przypadkiem do zmiany migawki bez potrzeby (przykład: w kodzie zaszła mała zmiana, w migawce – duża),
- nie pojawiają się gdzieś miejsca zawierające puste lub nieprawidłowo sformatowane dane,
- nie powinniśmy dodać nowego testu - dotyczy to z reguły przypadków, w których zostały stworzone nowe funkcjonalności albo jakiś przypadek nie został pokryty.
Korzyści
Snapshot testy są dobrym rozwiązaniem, kiedy chcemy uniknąć czasochłonnego pisania przypadków. Są one znacznie krótsze i łatwiejsze do napisania niż tradycyjne testy, a dodatkowo charakteryzują się łatwością ich aktualizowania, ponieważ do zarejestrowania migawki potrzebne jest uruchomienie tylko jednego polecenia. To z pewnością będzie znacznie łatwiejsze, niż konieczność edytowania wielu plików tekstowych, chcąc zsynchronizować testy z rzeczywistością.
Podsumowanie
Testy migawkowe nie są nową koncepcją, ale w ostatnich latach ewoluują.
Są one znacznie łatwiejsze do utworzenia i utrzymania, a także nadają się do sprawdzania, czy zachowanie aplikacji nie zmienia się podczas tworzenia. Mimo to nie zastąpią one testów jednostkowych i funkcjonalnych dostarczających nam informacji na temat tego, czy sama aplikacja działa poprawnie.