Jak już kiedyś wspominałem w poście dotyczącym testowania(znajdziecie go tutaj) testowanie jest ważnym elementem podczas tworzenia oprogramowania. Dziś chciałbym poświęcić chwilę czasu w testy jednostkowe w React'cie. Testy jednostkowe powinniśmy tworzyć dla adekwatnie każdego komponentu dzięki czemu będziemy mieć pewność, iż działa poprawnie i niczego nie psujemy podczas zmian lub ulepszania kodu.
Jest i Enzyme
Oficialne narzędzie create-react-app, które posłużyło mi do stworzenia szkieletu aplikacji korzysta z frameworka Jest do uruchamiania testów. Oprócz tego zdecydowałem się skorzystać z biblioteki Enzyme, która ułatwia testowanie komponentu o czym będzie więcej za chwilę. Najpierw parę słów poświęcę Jest'owi. Aby uruchomić testy musimy się trzymać pewnej konwencji, którą narzuca nam Jest a mianowicie sposób tworzenia plików, które ma uruchomić. Mamy tutaj 3 opcje:
- Folder o nazwie __tests__ w którym plikami testowymi są wszystkie pliki o rozszerzeniu *.js
- Pliki testowe o nazwie *.spec.js
- Pliki testowe o nazwie *.test.js
Pliki te mogą w dowolnej lokalizacji wewnątrz folderu src. Zalecane jest również by pliki te były jak najbliżej testowanych komponentów. Ja osobiście preferuję pliki o nazwie *.spec.js, które umieszczam w tym samym folderze co komponent.
Aby napisać test musimy w nim umieścić blok it(), który zawiera nazwę testu oraz funkcję, która go przeprowadzą. Można jeszcze umieścić bloki it() wewnątrz bloku describe() aby bardziej poukładać kod. Nie jest to wymagane jednak ja z tego korzystam, ponieważ pomaga w poukładaniu testów. Taki przykładowy szblon pliku testowego wygląda następująco:
Warto również tutaj wspomnieć, iż plik testowy musi zawierać przynajmniej jeden test(blok it()), ponieważ w innym przypadku będzie wyrzucał następujący błąd:
Każde ciało funkcji, które będzie przeprowadzało test będzie zawierać następującą konstrukcję
Jest to dosyć proste i wykorzystuje naturalny język. Wewnątrz funkcji expect musimy umieścić to co chcemy testować np.: funkcję, natomiast wewnątrz funkcji sprawdzajacej toEqual() spodziewany przez nas wynik np.:
Zamiast funkcji toEqual możemy stosować inne dostarczone nam przez Jest funkcje np.: toBe(), toHaveBeenCalled(), toContain() itd. Całą listę możecie zobaczyć tutaj
Enzyme
W takim razie do czego nam jest potrzebny Enzyme? Ano do renderowania komponentu i wyszukiwania w nim istotnych dla nas elementów. Chodzi o to by podczas testowania komponentu móc w nim znaleźć szukany przez nas element np. p i zwrócić na przykład tekst, który w nim się znajduje. Zanim opiszę pokrótce tą bibliotekę to musimy ją zainstalować przy pomocy następujących komend:
W Enzymie mamy 3 sposoby tworzenia komponentu:
- shallow - tworzy komponent bez tworzenia jego dzieci, nie wowułe funkcji należących do cyklu życia komponentu
- mount - tworzy komponent razem ze wszystkimi dziećmi oraz wywołuje funkcje należące do cyklu życia komponentu
- render - przekształca komponent React'owy do statycznego pliku HTML
Tworzenie komponentu wewnątrz testów może wyglądać następująco:
W tak stworzonym komponencie możemy wyszukiwać elementy np.: przy pomocy funkcji find lub też zwracać tekst przy pomocy funkcji text(). Możemy również zarządzać zmiennymi props i state z komponentu. Wszystkie dostępne metody możecie znaleźć tutaj
Przetestujmy cos wreszcie
Wstęp troszkę mi zajął ale był potrzebny by teraz przejść do adekwatniej części postu. Chciałbym teraz pokazać jak można przetestować prosty komponent, który wyświetla liczbę kliknięć przycisku. Kod komponentu wygląda następująco:
Nie jest on duży ale został specjalnie dobrany by pokazać parę ciekawych rzeczy. Testowanie komponentów zwykle zaczynam od sprawdzenia czy wyświetla wszystkie potrzebne mi elementy. Dla tego komponentu może to wyglądać następująco:
Widać tutaj przykład połączenia Jest'a i Enzym'a. dzięki tego drugiego wyszukujemy interesujący nas element by potem zwrócić tekst do porównania. Oprócz samego sprawdzenia czy komponent jest tworzony ze wszystkimi elementami możemy sprawdzić czy adekwatnie reaguje na zmiany wartości props lub state.
Tutaj wykorzystuję jedną z funkcji Enzyme by zmienić wartość counter w obiektcie store a następnie sprawdzam czy mój komponent adekwatnie to wyświetlił. No i jeszcze został nam przycisk który zwiększa wartość counter o 1. To również możemy przetestować:
Aby zasymulować przeciśnięcie przycisku przez użytkownika wykorzystałem funkcję pochodzącą z Enzyme o nazwie simulate(). Na sam koniec warto puścić testy w konsoli przy pomocy polecenia yarn test i zobaczyć czy wszystkie przechodzą na zielono.
Jeśli w trakcie rozwijania kodu jakiś zmieni się na czerwono to znaczy, iż albo coś popsuliśmy i musimy poprawić kod lub zmiana kodu była zrobiona specjalnie i musimy poprawić testy
A wy czego używacie do testowania i czy w ogóle testujecie komponenty? Napiszcie też czy wam się podobało i czy chcecie więcej postów dotyczących testowania różnych elementów. No i jak macie jakieś problemy to śmiało piszcie a może uda mi się pomóc a jeżeli zbierze się więcej takich ciekawych rzeczy to stworzę z tego osobny post :)