Praktyczny przewodnik po testowaniu aplikacji React za pomocą Jest
Opublikowany: 2022-03-10W tym artykule przedstawię narzędzie testujące React o nazwie Jest wraz z popularną biblioteką Enzyme, która jest przeznaczona do testowania komponentów React. Przedstawię techniki testowania Jest, w tym: przeprowadzanie testów, testowanie komponentów React, testowanie migawek i mockowanie. Jeśli jesteś nowy w testowaniu i zastanawiasz się, jak zacząć, ten samouczek będzie pomocny, ponieważ zaczniemy od wprowadzenia do testowania. Pod koniec będziesz już gotowy do pracy, testując aplikacje React przy użyciu Jest i Enzyme. Aby skorzystać z tego samouczka, powinieneś znać React.
Krótkie wprowadzenie do testowania
Testowanie to przeglądanie wiersz po wierszu sposobu wykonania kodu. Zestaw testów dla aplikacji składa się z różnych fragmentów kodu w celu sprawdzenia, czy aplikacja działa pomyślnie i bez błędów. Testowanie przydaje się również w przypadku aktualizacji kodu. Po zaktualizowaniu fragmentu kodu możesz uruchomić test, aby upewnić się, że aktualizacja nie zepsuje funkcjonalności już w aplikacji.
Dlaczego testować?
Dobrze jest zrozumieć, dlaczego coś robimy, zanim to zrobimy. Po co więc testować i jaki jest jego cel?
- Pierwszym celem testowania jest zapobieganie regresji. Regresja to ponowne pojawienie się błędu, który został wcześniej naprawiony. Powoduje, że funkcja przestaje działać zgodnie z przeznaczeniem po wystąpieniu określonego zdarzenia.
- Testowanie zapewnia funkcjonalność złożonych komponentów i aplikacji modułowych.
- Testowanie jest wymagane do efektywnego działania aplikacji lub produktu.
Testowanie sprawia, że aplikacja jest bardziej niezawodna i mniej podatna na błędy. Jest to sposób na sprawdzenie, czy Twój kod działa zgodnie z Twoimi oczekiwaniami i czy Twoja aplikacja działa zgodnie z przeznaczeniem dla użytkowników.
Przyjrzyjmy się rodzajom testów i ich czynnościom.
Test jednostkowy
W tego typu teście testowane są poszczególne jednostki lub komponenty oprogramowania. Jednostką może być pojedyncza funkcja, metoda, procedura, moduł lub obiekt. Test jednostkowy izoluje fragment kodu i weryfikuje jego poprawność w celu sprawdzenia, czy każda jednostka kodu oprogramowania działa zgodnie z oczekiwaniami.
W testach jednostkowych poszczególne procedury lub funkcje są testowane, aby zagwarantować ich prawidłowe działanie, a wszystkie komponenty są testowane indywidualnie. Na przykład testowanie funkcji lub sprawdzenie, czy instrukcja lub pętla w programie działa poprawnie, wchodzi w zakres testów jednostkowych.
Test komponentów
Testy modułowe weryfikują funkcjonalność poszczególnych części aplikacji. Testy są przeprowadzane na każdym komponencie w oderwaniu od innych komponentów. Ogólnie rzecz biorąc, aplikacje React składają się z kilku komponentów, więc testowanie komponentów zajmuje się testowaniem tych komponentów indywidualnie.
Rozważmy na przykład witrynę internetową, która ma różne strony internetowe z wieloma komponentami. Każdy składnik będzie miał swoje własne podkomponenty. Testowanie każdego modułu bez uwzględniania integracji z innymi komponentami nazywamy testowaniem komponentowym.
Takie testowanie w React wymaga bardziej wyrafinowanych narzędzi. Tak więc potrzebowalibyśmy Jest i czasami bardziej wyrafinowanych narzędzi, takich jak Enzyme, które omówimy pokrótce później.
Test migawek
Test migawki zapewnia, że interfejs użytkownika (UI) aplikacji sieci Web nie zmienia się nieoczekiwanie. Przechwytuje kod komponentu w danej chwili, dzięki czemu możemy porównać komponent w jednym stanie z dowolnym innym możliwym stanem, jaki może przyjąć.
O testowaniu migawek dowiemy się w dalszej części.
Zalety i wady testowania
Testowanie jest świetne i powinno być wykonane, ale ma swoje wady i zalety.
Zalety
- Zapobiega nieoczekiwanej regresji.
- Pozwala deweloperowi skupić się na bieżącym zadaniu, zamiast martwić się o przeszłość.
- Umożliwia modułową budowę aplikacji, która w innym przypadku byłaby zbyt złożona do zbudowania.
- Zmniejsza potrzebę ręcznej weryfikacji.
Niedogodności
- Musisz napisać więcej kodu, a także debugować i konserwować.
- Niekrytyczne niepowodzenia testów mogą spowodować odrzucenie aplikacji pod kątem ciągłej integracji.
Wprowadzenie do Jest
Jest to zachwycająca platforma do testowania JavaScript z naciskiem na prostotę. Może być zainstalowany z npm lub przędzą. Jest wpisuje się w szerszą kategorię narzędzi zwanych test runnerami. Świetnie sprawdza się w aplikacjach React, ale działa również świetnie poza aplikacjami React.
Enzym to biblioteka używana do testowania aplikacji React. Jest przeznaczony do testowania komponentów i umożliwia pisanie potwierdzeń, które symulują akcje, które potwierdzają, czy interfejs użytkownika działa poprawnie.
Jest i Enzyme tak dobrze się uzupełniają, więc w tym artykule będziemy używać obu.
Proces uruchamiania testu z Jest
W tej sekcji będziemy instalować Jest i pisać testy. Jeśli jesteś nowy w React, polecam użyć aplikacji Create React, ponieważ jest ona gotowa do użycia i jest dostarczana z Jest.
npm init react-app my-app
Musimy zainstalować Enzyme****i enzyme-adapter-react-16
z react-test-renderer
(liczba powinna być oparta na używanej wersji Reacta).
npm install --save-dev enzyme enzyme-adapter-react-16 react-test-renderer
Teraz, gdy stworzyliśmy nasz projekt zarówno z Jest, jak i Enzyme, musimy utworzyć plik setupTest.js
w folderze src
projektu. Plik powinien wyglądać tak:
import { configure } from "enzyme"; import Adapter from "enzyme-adapter-react-16"; configure({ adapter: new Adapter() });
Spowoduje to zaimportowanie Enzyme i skonfigurowanie adaptera do uruchomienia naszych testów.
Zanim przejdziemy dalej, nauczmy się podstaw. Niektóre kluczowe rzeczy są często używane w tym artykule i musisz je zrozumieć.
-
it
ortest
Do tej metody należałoby przekazać funkcję, a program uruchamiający testy wykonałby tę funkcję jako blok testów. -
describe
Ta opcjonalna metodait
do grupowania dowolnej liczby instrukcji lub instrukcjitest
. -
expect
Jest to warunek, który musi przejść test. Porównuje odebrany parametr z dopasowaniem. Daje również dostęp do wielu elementów dopasowujących, które pozwalają sprawdzać różne rzeczy. Więcej na ten temat możesz przeczytać w dokumentacji. -
mount
Ta metoda renderuje cały DOM, łącznie z komponentami potomnymi komponentu nadrzędnego, w którym przeprowadzamy testy. -
shallow
Powoduje to, że tylko poszczególne komponenty, które testujemy. Nie renderuje komponentów podrzędnych. Dzięki temu możemy testować komponenty w izolacji.
Tworzenie pliku testowego
Skąd Jest wie, co jest plikiem testowym, a co nie? Pierwsza zasada mówi, że wszystkie pliki znalezione w dowolnym katalogu o nazwie __test__
są uważane za test. Jeśli umieścisz plik JavaScript w jednym z tych folderów, Jest spróbuje go uruchomić, gdy wywołasz Jest, na dobre lub na złe. Druga zasada mówi, że Jest rozpozna każdy plik z rozszerzeniem .spec.js
lub .test.js
. Przeszuka nazwy wszystkich folderów i wszystkich plików w całym repozytorium.
Stwórzmy nasz pierwszy test dla miniaplikacji React stworzonej na potrzeby tego samouczka. Możesz go sklonować na GitHub. Uruchom npm install
, aby zainstalować wszystkie pakiety, a następnie npm start
, aby uruchomić aplikację. Więcej informacji znajdziesz w pliku README.md
.
Otwórzmy App.test.js
, aby napisać nasz pierwszy test. Najpierw sprawdź, czy nasz komponent aplikacji renderuje się poprawnie i czy określiliśmy wyjście:
it("renders without crashing", () => { shallow(<App />); }); it("renders Account header", () => { const wrapper = shallow(<App />); const welcome = <h1>Display Active Users Account Details</h1>; expect(wrapper.contains(welcome)).toEqual(true); });
W powyższym teście, pierwszy test, z shallow
, sprawdza, czy nasz komponent aplikacji renderuje się poprawnie bez awarii. Pamiętaj, że metoda shallow
renderuje tylko jeden komponent, bez komponentów podrzędnych.
Drugi test sprawdza, czy określiliśmy wynik tagu h1
„Wyświetl aktywne konto użytkownika” w naszym komponencie aplikacji z dopasowaniem Jest toEqual
.
Teraz uruchom test:
npm run test /* OR */ npm test
Dane wyjściowe w twoim terminalu powinny wyglądać tak:
PASS src/App.test.js √ renders without crashing (34ms) √ renders Account header (13ms) Test Suites: 1 passed, 1 total Tests: 2 passed, 2 total Snapshots: 0 total Time: 11.239s, estimated 16s Ran all test suites related to changed files. Watch Usage: Press w to show more.
Jak widać, nasz test zdał. Pokazuje, że mamy jeden zestaw testów o nazwie App.test.js
, z dwoma pomyślnymi testami, gdy uruchomiono Jest. Porozmawiamy o testowaniu migawek później, a także zobaczysz przykład nieudanego testu.
Pomijanie lub izolowanie testu
Pomijanie lub izolowanie testu oznacza, że po uruchomieniu Jest nie jest uruchamiany określony oznaczony test.
it.skip("renders without crashing", () => { shallow(<App />); }); it("renders Account header", () => { const wrapper = shallow(<App />); const header = <h1>Display Active Users Account Details</h1>; expect(wrapper.contains(header)).toEqual(true); });
Nasz pierwszy test zostanie pominięty, ponieważ użyliśmy metody skip
do wyizolowania testu. Tak więc nie uruchomi się ani nie wprowadzi żadnych zmian w naszym teście po uruchomieniu Jest. Pobiegnie tylko drugi. Możesz również użyć it.only()
.
Trochę frustrujące jest wprowadzanie zmian w pliku testowym, a następnie ponowne ręczne uruchomienie npm test
. Jest ma fajną funkcję zwaną trybem obserwacji, który obserwuje zmiany w plikach i przeprowadza odpowiednie testy. Aby uruchomić Jest w trybie zegarka, możesz uruchomić npm test -- --watch
lub jest --watch
. Polecam również pozostawienie działającego Jest w oknie terminala do końca tego samouczka.
kpiąca funkcja
Makieta to przekonująca kopia obiektu lub modułu bez żadnych rzeczywistych wewnętrznych działań. Może mieć odrobinę funkcjonalności, ale w porównaniu z prawdziwymi rzeczami to tylko szyderstwo. Może być tworzony automatycznie przez Jest lub ręcznie.
Dlaczego mielibyśmy kpić? Mockowanie zmniejsza liczbę zależności — to znaczy liczbę powiązanych plików, które muszą zostać załadowane i przeanalizowane po uruchomieniu testu. Tak więc użycie wielu makiet sprawia, że testy są wykonywane szybciej.
Funkcje atrapy są również znane jako „szpiedzy”, ponieważ pozwalają szpiegować zachowanie funkcji, która jest wywoływana bezpośrednio przez inny kod, a nie tylko testować dane wyjściowe.
Istnieją dwa sposoby na mock funkcji: albo przez utworzenie funkcji atrapy, aby użyć jej w kodzie testowym, albo przez napisanie ręcznej atrapy, aby przesłonić zależność modułu.
Ręczne makiety ****są używane do odcinania funkcjonalności za pomocą makiety danych. Na przykład zamiast uzyskiwać dostęp do zdalnego zasobu, takiego jak witryna internetowa lub baza danych, możesz utworzyć ręczną makieta, która pozwala na wykorzystanie fałszywych danych.
W następnej sekcji użyjemy funkcji atrapy.
Testowanie komponentów React
Sekcja połączy całą wiedzę, którą zdobyliśmy do tej pory, aby zrozumieć, jak testować komponenty React. Testowanie polega na upewnieniu się, że dane wyjściowe składnika nie zmieniły się nieoczekiwanie na coś innego. Konstruowanie komponentów we właściwy sposób jest zdecydowanie najskuteczniejszym sposobem zapewnienia pomyślnego testowania.
Jedną z rzeczy, które możemy zrobić, jest przetestowanie właściwości komponentów — w szczególności sprawdzenie, czy właściwości jednego komponentu są przekazywane do drugiego. Jest i Enzyme API pozwalają nam stworzyć funkcję makiety, która symuluje, czy właściwości są przekazywane między komponentami.
Musimy przekazać właściwości konta użytkownika z głównego komponentu App
do komponentu Account
. Musimy podać dane konta użytkownika do Account
, aby udostępnić aktywne konto użytkowników. Tu przydaje się mocowanie, które pozwala nam testować nasze komponenty na fałszywych danych.
Stwórzmy makietę dla rekwizytów user
:
const user = { name: "Adeneye David", email: "[email protected]", username: "Dave", };
Stworzyliśmy ręczną funkcję makiety w naszym pliku testowym i owinięto ją wokół komponentów. Załóżmy, że testujemy dużą bazę danych użytkowników. Dostęp do bazy danych bezpośrednio z naszego pliku testowego nie jest zalecany. Zamiast tego tworzymy funkcję makiety, która umożliwia nam wykorzystanie fałszywych danych do testowania naszego komponentu.
describe(" ", () => { it("accepts user account props", () => { const wrapper = mount(<Account user={user} />); expect(wrapper.props().user).toEqual(user); }); it("contains users account email", () => { const wrapper = mount(<Account user={user} />); const value = wrapper.find("p").text(); expect(value).toEqual("[email protected]"); }); });
describe(" ", () => { it("accepts user account props", () => { const wrapper = mount(<Account user={user} />); expect(wrapper.props().user).toEqual(user); }); it("contains users account email", () => { const wrapper = mount(<Account user={user} />); const value = wrapper.find("p").text(); expect(value).toEqual("[email protected]"); }); });
Powyżej mamy dwa testy i używamy warstwy describe
, która pobiera testowany komponent. Określając rekwizyty i wartości, które spodziewamy się przejść przez test, jesteśmy w stanie kontynuować.
W pierwszym teście sprawdzamy, czy rekwizyty, które przekazaliśmy do zamontowanego komponentu, są takie same jak mock rekwizytów, które stworzyliśmy powyżej.
W drugim teście przekazujemy właściwości użytkownika do zamontowanego komponentu Account
. Następnie sprawdzamy, czy możemy znaleźć element <p>
odpowiadający temu, co mamy w komponencie Account
. Gdy uruchomimy zestaw testów, zobaczysz, że test przebiega pomyślnie.
Możemy również przetestować stan naszego komponentu. Sprawdźmy, czy stan komunikatu o błędzie jest równy null:
it("renders correctly with no error message", () => { const wrapper = mount( ); expect(wrapper.state("error")).toEqual(null); });
it("renders correctly with no error message", () => { const wrapper = mount( ); expect(wrapper.state("error")).toEqual(null); });
W tym teście sprawdzamy, czy stan błędu naszego komponentu jest równy null, używając toEqual()
. Jeśli w naszej aplikacji pojawi się komunikat o błędzie, test zakończy się niepowodzeniem.
W następnej sekcji omówimy, jak testować komponenty React za pomocą migawek, kolejnej niesamowitej techniki.
Testowanie migawek
Testowanie migawkowe przechwytuje kod komponentu w danej chwili w celu porównania go z referencyjnym plikiem migawkowym przechowywanym wraz z testem. Służy do śledzenia zmian w interfejsie użytkownika aplikacji.
Rzeczywista reprezentacja kodu migawki to plik JSON, a ten JSON zawiera zapis tego, jak wyglądał składnik podczas tworzenia migawki. Podczas testu Jest porównuje zawartość tego pliku JSON z danymi wyjściowymi komponentu podczas testu. Jeśli pasują, test przechodzi; jeśli nie, test kończy się niepowodzeniem.
Aby przekonwertować wrapper enzymu do formatu zgodnego z testowaniem migawek Jest, musimy zainstalować enzyme-to-json
:
npm install --save-dev enzyme-to-json
Stwórzmy nasz test migawek. Kiedy uruchomimy go po raz pierwszy, migawka kodu tego komponentu zostanie skomponowana i zapisana w nowym folderze __snapshots__
w katalogu src
.
it("renders correctly", () => { const tree = shallow(<App />); expect(toJson(tree)).toMatchSnapshot(); });
Gdy powyższy test zakończy się pomyślnie, obecny składnik interfejsu użytkownika zostanie porównany z istniejącym.
Teraz przeprowadźmy test:
npm run test
Po uruchomieniu zestawu testów zostanie wygenerowana nowa migawka i zapisana w folderze __snapshots__
. Gdy później uruchomimy test, Jest sprawdzi, czy komponenty pasują do obrazu stanu.
Jak wyjaśniono w poprzedniej sekcji, ta shallow
metoda z pakietu Enzyme jest używana do renderowania pojedynczego komponentu i niczego więcej. Nie renderuje komponentów podrzędnych. Daje nam raczej dobry sposób na wyizolowanie kodu i uzyskanie lepszych informacji podczas debugowania. Inna metoda, nazwana mount
, służy do renderowania całego DOM, łącznie z komponentami potomnymi komponentu nadrzędnego, w którym przeprowadzamy testy.
Możemy również zaktualizować naszą migawkę. Zróbmy kilka zmian w naszym komponencie, aby nasz test się nie powiódł, co stanie się, ponieważ komponent nie odpowiada już temu, co mamy w pliku migawki. Aby to zrobić, zmieńmy tag <h3>
w naszym komponencie z <h3> Loading...</h3>
na <h3>Fetching Users...</h3>
. Po uruchomieniu testu w terminalu dostaniemy:
FAIL src/App.test.js (30.696s) × renders correctly (44ms) ● renders correctly expect(received).toMatchSnapshot() Snapshot name: `renders correctly 1 - Snapshot + Received
7 | it("renderuje poprawnie", () => { 8 | const wrapper = płytkie( FAIL src/App.test.js (30.696s) × renders correctly (44ms) ● renders correctly expect(received).toMatchSnapshot() Snapshot name: `renders correctly 1 - Snapshot + Received
Wyświetl szczegóły konta aktywnych użytkowników
- Ładowanie... + Pobieranie użytkowników...
); > 9 | oczekiwać(toJson(opakowanie)).toMatchSnapshot(); | ^ 10 | }); 11 | 12 | /* it("renderuje bez awarii", () => { w obiekcie. (źródło/App.test.js:9:27) › 1 zrzut nie powiódł się. Podsumowanie zrzutu › 1 migawka nie powiodła się z 1 zestawu testów. Sprawdź zmiany w kodzie lub naciśnij „u”, aby je zaktualizować. Zestawy testowe: 1 nieudany, 1 łącznie Testy: 1 nieudany, 1 łącznie Migawki: 1 nieudane, 1 łącznie Czas: 92,274s Uruchomił wszystkie zestawy testów związane ze zmienionymi plikami. Wykorzystanie zegarka: Naciśnij w, aby wyświetlić więcej.
Jeśli chcemy, aby nasz test zakończył się pomyślnie, albo zmienimy test do poprzedniego stanu, albo zaktualizujemy plik migawki. W wierszu poleceń Jest udostępnia instrukcje dotyczące aktualizacji zrzutu obrazu. Najpierw naciśnij w
w wierszu poleceń, aby wyświetlić więcej, a następnie naciśnij u
, aby zaktualizować migawkę.
› Press u to update failing snapshots.
Gdy naciśniemy u
, aby zaktualizować migawkę, test przejdzie.
Wniosek
Mam nadzieję, że praca z tym samouczkiem Ci się podobała. Nauczyliśmy się kilku technik testowania Jest przy użyciu biblioteki testowej Enzyme. Wprowadziłem Cię również w proces przeprowadzania testu, testowania komponentów React, mockowania i testowania migawek. Jeśli masz jakieś pytania, możesz je zostawić w sekcji komentarzy poniżej, a z przyjemnością odpowiem na każde z nich i rozwiążę z Tobą wszelkie problemy.
Zasoby i dalsze czytanie
- Jest dokumentacja
- Dokumentacja enzymatyczna
- „Jak testować komponenty React: kompletny przewodnik”, Mohammad Iqbal, freeCodeCamp
- „Testowanie React With Jest and Enzyme”, Dominic Fraser, CodeClan