Testowanie aplikacji z Enzyme i Jest – Kurs React – cz. 7

Testowanie aplikacji z Enzyme i Jest - Kurs React

Czym są i jak pisać testy jednostkowe w React? W tej części przedstawiam jak pisać testy jednostkowe w Enzyme i Jest. Wszystko opisane jest krok po kroku.

Czym jest Enzyme?

Enzyme to JavaScriptowe narzędzie do testowania komponentów Reacta. Ułatwia testowanie danych wyjściowych komponentów. Czyli prościej mówiąc zajmuje się renderowaniem komponentów, manipulowaniem czy symulowaniem środowiska wykonawczego.

Czym jest Jest?

Jest to JavaScriptowy framework stworzony do testowania. Dzięki niemu można np. sprawdzić czy oczekiwana wartość zwrócona przez Enzyme jest poprawna.

Instalacja Enzyme w Create React App

Enzyme można zainstalować za pomocą komendy npm.

npm i --save-dev enzyme enzyme-adapter-react-16

Kolejnym krokiem będzie stworzenie pliku src/setupTests.js. CRA będzie szukać tego w pliku w podanej lokalizacji, dlatego nazwa i ścieżka do pliku musi być identyczna. W tym pliku należy umieścić podany kod:

import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

configure({ adapter: new Adapter() });

enzyme-to-json

Warto zainstalować jeszcze paczkę enzyme-to-json. Pomoże w testowaniu snapshotów – skonwertuje Enzymowy wrapper do przyjaznego formatu dla Jest.

npm i --save-dev enzyme-to-json

Testowanie komponentu

Napisanie prostych testów nie należy do czynności skomplikowanych – zatem do dzieła!

Pierwszy test – renderowanie

Pierwszy test zostanie wykonany na komponencie Heading i sprawdzi on czy komponent renderuje się poprawnie. W folderze Heading należy stworzyć plik Heading.test.js, a następnie umieścić w nim podany kod.

import React from 'react';
import { shallow } from 'enzyme';
import {Heading} from './Heading';

const wrapper = shallow(<Heading />);
it('should render <Heading/>', () => {
    expect(wrapper);
});

Importujemy funkcję shallow z Enzyme, a następnie z wykorzystaniem funkcji expect() (można ją określić jako „spodziewamy się tego co jest w środku”) sprawdzamy czy komponent wyrenderuje się poprawnie.

Uruchomienie testów

Do uruchomienia testów służy komenda:

npm run test

Wynikiem tego będzie podsumowanie testów.

Poprawny wynik testów
npm run test – wynik testów

Celowy błąd – sprawdzenie działania testów

Sprawdźmy teraz, czy jeśli błąd będzie w komponencie Heading to czy wykryją to testy.

import React from 'react';
import {LargePageHeading} from './styled/PageHeading';

export function Heading(props) {
    return (
        <LargePageHeadingXXXX variant={props.variant}>
            {props.title}
        </LargePageHeading>
    );
}

Do komponentu LargePageHeading zostało dodanych kilka znaków X. Ten komponent nie może wyrenderować się poprawnie, a testy powinny to wychwycić.

Błąd podczas uruchomienia testów
Błąd testów

Jak widać testy wykryły błąd. Wskazują miejsce, w którym się pojawia i dzięki temu można go szybko poprawić.

Więcej testów

Poniżej przedstawiam więcej przykładów testów.

Tworzenie migawki – snapshot

Migawka (snapshot) to zapisana wartość testów z użyciem metody toMatchSnapshot() w pliku NAZWA.snap (plik znajduje się w folderze __snapsshots__). Plik wraz z folderem tworzony jest podczas pierwszego uruchomienia testów. Celem tych testów jest wykrycie niepowołanych zmian i porównanie ich z wersją poprzednią. Jeśli pojawią się jakieś zmiany to podczas uruchomienia testów zostanie wyświetlony komunikat z różnicami. Wtedy są dwie opcje:

  • zostaną wprowadzone poprawki do kodu, ponieważ zmiany spowodowane są błędem
  • zostanie wykonana aktualizacja snapshotów, ponieważ zmiany są oczekiwanym wynikiem

Snapshot często jest używany do testowania styled componentów.

Do prawidłowego przetestowania należy zamockować styled componenty (LargePageHeading), który jest użyty w komponencie Heading. Więcej o mockowaniu w dalszej części artykułu.

Taki test wygląda tak jak poniżej.

Rezultat (snapshot Heading.test.js.snap) wygląda następująco:

Sprawdzanie zawartości tekstowej

Za pomocą metody .text() oraz .toEqual() można sprawdzić czy zawartość tekstu zgadza się z przekazanym w propsie title.

Sprawdzanie przekazanych propsów

Dzięki metodzie .prop() i .toEqual() można przetestować czy prawidłowo przekazują się propsy do komponentu.

Podsumowanie testów

Jak widać można napisać wiele testów dla tak małego komponentu. Oczywiście trzeba zwrócić uwagę, aby testy były pisane rzetelnie i testowały to co potrzeba. Tego oczywiście można się dowiedzieć wraz z praktyką lub od osób z większym doświadczeniem.

Cały kod testów dla komponentu Heading poniżej.

Wynik uruchomienia wszystkich testów.

Wynik uruchomienia testów jednostkowych - npm test
Wynik uruchomienia testów

Dlaczego warto testować aplikacje

Testowanie aplikacji jest bardzo ważne, ponieważ na wczesnym etapie tworzenia funkcjonalności czy jakichkolwiek zmian w kodzie można wykryć błędy w aplikacji.

Im większa aplikacja tym testy odgrywają większą rolę. Duża ilość komponentów sprawia, że programista nie jest w stanie przewidzieć wszystkiego i sprawdzić wszystkich miejsc przed wdrożeniem na produkcję.

Enzyme – sposoby testowania

create-react-app domyślnie używa Jest. Oczywiście Enzyme można również używać z innymi frameworkami (lista z oficjalnej dokumentacji):

Using Enzyme with Mocha
Using Enzyme with Karma
Using Enzyme with Browserify
Using Enzyme with SystemJS
Using Enzyme with Webpack
Using Enzyme with JSDOM
Using Enzyme with React Native
Using Enzyme with Jest
Using Enzyme with Lab
Using Enzyme with Tape and AVA

W Enzyme mamy dostępne trzy sposoby testowania aplikacji.

Shallow Rendering

Shallow Rendering pozwala na testowanie konkretnego komponentu, co oznacza, że nie są testowane inne komponenty (child components). Shallow uruchamia następujące metody życia komponentu (lifecycle methods) – componentDidMount i componentDidUpdate.

Shallow będzie używane w większości przypadków.

import { shallow } from 'enzyme';

const wrapper = shallow(<MyComponent />);

Full Rendering

Full DOM rendering używa się wtedy, kiedy potrzeba jest interakcji z DOM API lub do testowania komponentów, które są owinięte w higher order components (HOC).

import { mount } from 'enzyme';

const wrapper = mount(<MyComponent />);

Static Rendering

Jak sama nazwa wskazuje, Static Rendering zajmuje się generowaniem statycznego kodu HTML. Funkcja render zwraca kod HTML parsowany przez bibliotekę Cheerio (zewnętrzna biblioteka).

import { render } from 'enzyme';

const wrapper = render(<MyComponent />);

Jest – JavaScript Testing Framework

Jest udostępnia znacznie więcej metod, dzięki którym można sprawdzić różne przypadki testowe. Jest tego bardzo dużo, dlatego warto zacząć od najprostszych przypadków i wraz z rozwojem testować coraz bardziej skomplikowane komponenty.

Kilka przykładowych metod:

Kompletną listę z wykorzystaniem expect można znaleźć na oficjalnej dokumentacji Jest w sekcji Expect, natomiast tutaj jest początek dokumentacji.

Czym jest describe()?

Jak można było wcześniej zauważyć pojawia się coś takiego jak describe() w testach. Służy on do grupowania testów. Dzięki temu czytelność kodu testów jest lepsza, a wynik uruchomienia ich jest znacznie bardziej przejrzysty.

describe() może być używany wielopoziomowo co oznacza, że wewnątrz describe() można użyć kolejnego i tak dalej. Oczywiście logika podziału powinna być przemyślana.

// testy mogą być tutaj
describe('level 1', () => {
  // testy mogą być tutaj
  describe('level 2', () => {
    // i tutaj również
  });
});

describe() nie jest obowiązkowy.

Czym jest it()? it() czy test()?

Funkcja ta to pojedynczy test, a wewnątrz niej definiujemy przypadek testowy.

it() jest aliasem dla test() czyli działanie jest takie same. W dokumentacji w przykładach używana jest funkcja test(), natomiast której się powinno używać to już jest Twoja decyzja lub zespołu.

Mockowanie

jest.mock() pozwala na izolowanie testowanego komponentu. Oznacza to, że wszelkie zależności wewnątrz komponentu, które są importowane zamieniane są na obiekty, które możemy kontrolować wewnątrz testów (testowany jest tylko ten konkretny komponent, a nie funkcje czy komponenty importowane wewnątrz).

Mockowanie jest całkiem przystępnie opisane w artykule na medium – Understanding Jest Mocks.

Źródła / przydatne linki

Dokumentacja Enzymehttps://airbnb.io/enzyme/docs/api/

Dokumentacja Jesthttps://jestjs.io/docs/en/getting-started

Ćwiczenie

Stwórz prosty komponent (najlepiej z propsami) i napisz do niego testy, np:

  • czy poprawnie się renderuje,
  • czy poprawnie przekazuje propsy,
  • czy poprawnie wyświetla podany tekst,
  • + test wymyślony przez Ciebie.

Powodzenia!

Podsumowanie

W tym artykule przedstawiłem (główne rzeczy, które powinieneś wiedzieć po przeczytaniu):

  • jak napisać pierwsze testy
  • czym jest Enzyme
  • czym jest Jest

Mam nadzieje, że w tej części zawierają się wszystkie najistotniejsze rzeczy. Podziel się opinią na temat tej części kursu Reacta. Czy wszystko jest zrozumiałe? Podoba Ci się? Daj znać! 😊😊😊

A może like? 😉

Powstała kolejna część darmowego Kursu Reacta! 😍Wyszło dość obszernie!Czym są i jak pisać testy jednostkowe w React?…

Opublikowany przez Devpebe Czwartek, 17 października 2019

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *