Hoe een React-app testen met Jest en React Testing Library

De auteur heeft Vets Who Code geselecteerd om een donatie te ontvangen als onderdeel van het Write for DOnations-programma.

Introductie

Het verkrijgen van een solide testdekking is essentieel voor het opbouwen van vertrouwen in uw webtoepassing. Jest is een JavaScript-testrunner die middelen biedt voor het schrijven en uitvoeren van tests. React Testing Library biedt een set testhelpers die uw tests structureren op basis van gebruikersinteracties in plaats van details van de implementatie van componenten. Zowel Jest als React Testing Library worden standaard meegeleverd met Create React App en houden zich aan het leidende principe dat het testen van apps moet lijken op hoe de software zal worden gebruikt.

In deze tutorial zult u asynchrone code en interacties testen in een voorbeeldproject met verschillende UI-elementen. U zult Jest gebruiken om unit tests te schrijven en uit te voeren, en u zult React Testing Library implementeren als een hulplibrary voor de DOM (Document Object Model) om te interacteren met componenten.

Vereisten

Om deze handleiding te voltooien, heb je het volgende nodig:

  • Node.js versie 14 of hoger geïnstalleerd op je lokale machine. Om Node.js te installeren op macOS of Ubuntu 18.04, volg de stappen in Hoe Node.js te installeren en een lokale ontwikkelomgeving op macOS te maken of de sectie Installeren met behulp van een PPA van Hoe Node.js te installeren op Ubuntu 18.04.

  • npm versie 5.2 of hoger op je lokale machine, die je nodig zult hebben om Create React App en npx te gebruiken in het voorbeeldproject. Als je npm niet hebt geïnstalleerd naast Node.js, doe dat dan nu. Voor Linux, gebruik het commando sudo apt install npm.

    • Om npm-pakketten te laten werken in deze tutorial, installeer het build-essential-pakket. Voor Linux, gebruik het commando sudo apt install build-essential.
  • Git geïnstalleerd op je lokale machine. Je kunt controleren of Git is geïnstalleerd op je computer of het installatieproces doorlopen voor je besturingssysteem met Hoe Git te installeren op Ubuntu 20.04.

  • Bekendheid met React, dat je kunt ontwikkelen met de serie Hoe te coderen in React.js. Omdat het voorbeeldproject is opgestart met Create React App, hoef je het niet apart te installeren.

  • Enige bekendheid met Jest als testrunner of framework is nuttig maar niet vereist. Omdat Jest wordt meegeleverd met Create React App, hoef je het niet apart te installeren.

Stap 1 — Het project instellen

In deze stap ga je een voorbeeldproject klonen en de test suite starten. Het voorbeeldproject maakt gebruik van drie belangrijke tools: Create React App, Jest en React Testing Library. Create React App wordt gebruikt om een React-toepassing met één pagina te starten. Jest wordt gebruikt als de test runner, en React Testing Library biedt test-helpers voor het structureren van tests rond gebruikersinteracties.

Om te beginnen, ga je een vooraf gebouwde React App klonen vanuit GitHub. Je zult werken met de Doggy Directory-app, wat een voorbeeldproject is dat de Dog API gebruikt om een zoek- en weergavesysteem voor een verzameling hondafbeeldingen op basis van een specifiek ras te bouwen.

Om het project van Github te klonen, open je je terminal en voer je de volgende opdracht uit:

  1. git clone https://github.com/do-community/doggy-directory

Je ziet een output die vergelijkbaar is met deze:

Output
Cloning into 'doggy-directory'... remote: Enumerating objects: 64, done. remote: Counting objects: 100% (64/64), done. remote: Compressing objects: 100% (48/48), done. remote: Total 64 (delta 21), reused 55 (delta 15), pack-reused 0 Unpacking objects: 100% (64/64), 228.16 KiB | 3.51 MiB/s, done.

Verander naar de map doggy-directory:

  1. cd doggy-directory

Installeer de projectafhankelijkheden:

  1. npm install

De npm install-opdracht zal alle projectafhankelijkheden installeren die zijn gedefinieerd in het package.json-bestand.

Na het installeren van de afhankelijkheden kun je ofwel de gedeployde versie van de app bekijken, of je kunt de app lokaal uitvoeren met de volgende opdracht:

  1. npm start

Als je ervoor kiest om de app lokaal uit te voeren, zal deze openen op http://localhost:3000/. Je ziet de volgende output in de terminal:

Output
Compiled successfully! You can now view doggy-directory in the browser. Local: http://localhost:3000 On Your Network: http://network_address:3000

Nadat je het hebt gelanceerd, zal de startpagina van de app er zo uitzien:

De projectafhankelijkheden zijn geïnstalleerd en de app wordt nu uitgevoerd. Open vervolgens een nieuwe terminal en start de tests met de volgende opdracht:

  1. npm test

Het npm test commando start de tests in een interactieve kijkmodus met Jest als testrunner. In de kijkmodus worden de tests automatisch opnieuw uitgevoerd nadat een bestand is gewijzigd. De tests worden uitgevoerd telkens wanneer u een bestand wijzigt en laten u weten of die wijziging geslaagd is voor de tests.

Na het uitvoeren van npm test voor de eerste keer, ziet u deze uitvoer in de terminal:

Output
No tests found related to files changed since last commit. Press `a` to run all tests, or run Jest with `--watchAll`. Watch Usage › Press a to run all tests. › Press f to run only failed tests. › Press q to quit watch mode. › Press p to filter by a filename regex pattern. › Press t to filter by a test name regex pattern. › Press Enter to trigger a test run.

Nu u het voorbeeld van de applicatie en de test suite heeft draaien, kunt u beginnen met het testen van de landingspagina.

Stap 2 — Het testen van de landingspagina

Standaard zal Jest zoeken naar bestanden met de extensie .test.js en bestanden met de extensie .js in __tests__ mappen. Wanneer u wijzigingen aanbrengt in de relevante testbestanden, worden deze automatisch gedetecteerd. Naarmate testcases worden gewijzigd, wordt de uitvoer automatisch bijgewerkt. Het testbestand dat is voorbereid voor het doggy-directory voorbeeldproject is opgezet met minimale code voordat u testparadigma’s toevoegt. In deze stap schrijft u tests om te controleren of de landingspagina van de app zal laden voordat u een zoekopdracht uitvoert.

Open src/App.test.js in uw editor om de volgende code te zien:

src/App.test.js
import { render, screen } from '@testing-library/react';
import App from './App';

test('renders the landing page', () => {
  render(<App />);
});

A minimum of one test block is required in each test file. Each test block accepts two required parameters: the first argument is a string representing the name of the test case; the second argument is a function that holds the expectations of the test.

Binnen de functie is er een render methode die React Testing Library biedt om je component in de DOM te renderen. Met de component die je wilt testen, weergegeven in de DOM van de testomgeving, kun je nu code gaan schrijven om te verifiëren tegen de verwachte functionaliteit.

Je zult een testblok toevoegen aan de render methode dat zal testen of de landingspagina nauwkeurig wordt weergegeven voordat er API-aanroepen of selecties worden gedaan. Voeg de gemarkeerde code toe onder de render methode:

src/App.test.js
...
test('renders the landing page', () => {
  render(<App />);
  
  expect(screen.getByRole("heading")).toHaveTextContent(/Doggy Directory/);
  expect(screen.getByRole("combobox")).toHaveDisplayValue("Select a breed");
  expect(screen.getByRole("button", { name: "Search" })).toBeDisabled();
  expect(screen.getByRole("img")).toBeInTheDocument();
});

De expect functie wordt gebruikt telkens wanneer je een bepaalde uitkomst wilt controleren, en het accepteert een enkel argument dat de waarde vertegenwoordigt die je code produceert. De meeste expect functies worden gekoppeld aan een matcher functie om iets te verifiëren over een bepaalde waarde. Voor de meeste van deze beweringen zul je aanvullende matchers gebruiken die worden geleverd door jest-dom om het gemakkelijker te maken om te controleren op veelvoorkomende aspecten die in de DOM worden gevonden. Bijvoorbeeld, .toHaveTextContent is de matcher voor de expect functie in de eerste regel, terwijl getByRole("heading") de selector is om het DOM-element te pakken.

React Testing Library biedt het screen object als een handige manier om toegang te krijgen tot de relevante queries die nodig zijn om te verifiëren tegen de test DOM-omgeving. Standaard biedt React Testing Library queries waarmee je elementen binnen de DOM kunt vinden. Er zijn drie hoofdcategorieën van queries:

  • getBy* (meestal gebruikt)
  • queryBy* (gebruikt wanneer het testen van de afwezigheid van een element zonder een fout te genereren)
  • findBy* (gebruikt bij het testen van asynchrone code)

Elk querytype heeft een specifiek doel dat later in de tutorial zal worden gedefinieerd. In deze stap richt je je op de getBy* query, die het meest voorkomende querytype is. Om een uitgebreide lijst van de verschillende queryvariaties te zien, kun je de query cheatsheet van React bekijken.

Hieronder staat een geannoteerde afbeelding van de Doggy Directory landingspagina waarin elke sectie wordt aangegeven die de eerste test (bij het renderen van de landingspagina) behandelt:

Elke expect functie beweert het volgende (zoals getoond in de geannoteerde afbeelding hierboven):

  1. Je verwacht dat het element met de rol van heading een substring match heeft van Doggy Directory.
  2. Je verwacht dat de selectie-invoer een exacte weergavewaarde heeft van Selecteer een ras.
  3. Je verwacht dat de Zoeken knop uitgeschakeld is omdat er geen selectie is gemaakt.
  4. Je verwacht dat de placeholder-afbeelding aanwezig is in het document omdat er nog geen zoekopdracht heeft plaatsgevonden.

Wanneer je klaar bent, sla het bestand src/App.test.js op. Omdat de tests worden uitgevoerd in de kijkmodus, worden de wijzigingen automatisch geregistreerd. Als de wijzigingen niet automatisch worden geregistreerd, moet je mogelijk de test-suite stoppen en opnieuw starten.

Nu, wanneer je naar je tests kijkt in de terminal, zie je de volgende output:

Output
PASS src/App.test.js ✓ renders the landing page (172 ms) Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 0 total Time: 2.595 s, estimated 5 s Ran all test suites related to changed files. Watch Usage: Press w to show more.

In deze stap heb je een initiële test geschreven om de initiële weergave van de Doggy Directory-landingspagina te verifiëren. In de volgende stap leer je hoe je een API-oproep kunt nabootsen voor het testen van asynchrone code.

Stap 3 — Het Nabootsen van de fetch-Methode

In deze stap zul je één benadering bekijken om de JavaScript fetch-methode na te bootsen. Hoewel er talloze manieren zijn om dit te bereiken, zal deze implementatie gebruikmaken van Jest’s spyOn en mockImplementation-methoden.

Wanneer je afhankelijk bent van externe API’s, bestaat er een kans dat hun API uitvalt of even duurt om een reactie terug te sturen. Het nabootsen van de fetch-methode biedt een consistente en voorspelbare omgeving, waardoor je meer vertrouwen hebt in je tests. Een API-nabootsingsmechanisme is noodzakelijk om tests die een externe API gebruiken, correct uit te voeren.

Let op: In een poging om dit project te vereenvoudigen, zal je de fetch-methode nabootsen. Je wordt echter geadviseerd om een robuustere oplossing zoals Mock Service Worker (MSW) te gebruiken bij het nabootsen van asynchrone code voor grotere, productieklare codebases.

Open src/mocks/mockFetch.js in je editor om te bekijken hoe de mockFetch-methode werkt:

src/mocks/mockFetch.js
const breedsListResponse = {
    message: {
        boxer: [],
        cattledog: [],
        dalmatian: [],
        husky: [],
    },
};

const dogImagesResponse = {
    message: [
        "https://images.dog.ceo/breeds/cattledog-australian/IMG_1042.jpg ",
        "https://images.dog.ceo/breeds/cattledog-australian/IMG_5177.jpg",
    ],
};

export default async function mockFetch(url) {
    switch (url) {
        case "https://dog.ceo/api/breeds/list/all": {
            return {
                ok: true,
                status: 200,
                json: async () => breedsListResponse,
            };
        }
        case "https://dog.ceo/api/breed/husky/images" :
        case "https://dog.ceo/api/breed/cattledog/images": {
            return {
                ok: true,
                status: 200,
                json: async () => dogImagesResponse,
            };
        }
        default: {
            throw new Error(`Unhandled request: ${url}`);
        }
    }
}

De mockFetch-methode retourneert een object dat sterk lijkt op de structuur van wat een fetch-oproep zou retourneren als reactie op API-oproepen binnen de applicatie. De mockFetch-methode is noodzakelijk om de asynchrone functionaliteit te testen op twee gebieden van de Doggy Directory-app: de select-dropdown die de lijst met rassen vult en de API-oproep om hondenafbeeldingen op te halen wanneer er een zoekopdracht wordt uitgevoerd.

Sluit src/mocks/mockFetch.js. Nu je begrijpt hoe de mockFetch-methode zal worden gebruikt in je tests, kan je deze importeren in je testbestand. De mockFetch-functie zal worden doorgegeven als een argument aan de mockImplementation-methode en zal vervolgens worden gebruikt als een nep-implementatie van de fetch API.

Voeg in src/App.test.js de gemarkeerde regels code toe om de mockFetch-methode te importeren:

src/App.test.js
import { render, screen } from '@testing-library/react';
import mockFetch from "./mocks/mockFetch";
import App from './App';

beforeEach(() => {
   jest.spyOn(window, "fetch").mockImplementation(mockFetch);
})

afterEach(() => {
   jest.restoreAllMocks()
});
...

Deze code zal de mock-implementatie opzetten en afbreken, zodat elke test begint vanuit een gelijk speelveld.

jest.spyOn(window, "fetch"); maakt een mockfunctie aan die oproepen naar de aan de globale window-variabele in de DOM gekoppelde fetch-methode zal volgen.

.mockImplementation(mockFetch); accepteert een functie die zal worden gebruikt om de nepmethode te implementeren. Omdat dit commando de oorspronkelijke fetch-implementatie overschrijft, wordt het uitgevoerd wanneer fetch wordt aangeroepen binnen de app-code.

Wanneer klaar, sla het bestand src/App.test.js op.

Als je nu naar je tests kijkt in de terminal, ontvang je de volgende output:

Output
console.error Warning: An update to App inside a test was not wrapped in act(...). When testing, code that causes React state updates should be wrapped into act(...): act(() => { /* fire events that update state */ }); /* assert on the output */ This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act at App (/home/sammy/doggy-directory/src/App.js:5:31) 18 | }) 19 | .then((json) => { > 20 | setBreeds(Object.keys(json.message)); | ^ 21 | }); 22 | }, []); 23 | ... PASS src/App.test.js ✓ renders the landing page (429 ms) Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 0 total Time: 1.178 s, estimated 2 s Ran all test suites related to changed files.

De waarschuwing vertelt je dat er een statusupdate heeft plaatsgevonden wanneer dat niet werd verwacht. Echter, de output geeft ook aan dat de tests succesvol de fetch-methode hebben gesimuleerd.

In deze stap heb je de fetch-methode gemockt en die methode in een test suite opgenomen. Hoewel de test slaagt, moet je nog steeds de waarschuwing aanpakken.

Stap 4 — Het oplossen van de act-waarschuwing

In deze stap leer je hoe je de act-waarschuwing kunt oplossen die is opgetreden na de wijzigingen in Stap 3.

De act-waarschuwing treedt op omdat je de fetch-methode hebt gemockt, en wanneer de component wordt gemonteerd, wordt er een API-oproep gedaan om de lijst met rassen op te halen. De lijst met rassen wordt opgeslagen in een statusvariabele die het option-element binnen de select-input vult.

De onderstaande afbeelding laat zien hoe de select-input eruitziet nadat er een succesvolle API-oproep is gedaan om de lijst met rassen te vullen:

De waarschuwing wordt weergegeven omdat de status wordt ingesteld nadat het testblok klaar is met het renderen van het component.

Om dit probleem op te lossen, voeg de gemarkeerde wijzigingen toe aan het testgeval in src/App.test.js:

src/App.test.js
...
test('renders the landing page', async () => {
   render(<App />);
   
   expect(screen.getByRole("heading")).toHaveTextContent(/Doggy Directory/);
   expect(screen.getByRole("combobox")).toHaveDisplayValue("Select a breed");
   expect(await screen.findByRole("option", { name: "husky"})).toBeInTheDocument();
   expect(screen.getByRole("button", { name: "Search" })).toBeDisabled();
   expect(screen.getByRole("img")).toBeInTheDocument();
});

Het async-sleutelwoord vertelt Jest dat asynchrone code wordt uitgevoerd als gevolg van de API-oproep die plaatsvindt wanneer het component wordt gemonteerd.

A new assertion with the findBy query verifies that the document contains an option with the value of husky. findBy queries are used when you need to test asynchronous code that is dependent on something being in the DOM after a period of time. Because the findBy query returns a promise that gets resolved when the requested element is found in the DOM, the await keyword is used within the expect method.

Als je klaar bent, sla dan de wijzigingen op die zijn aangebracht in src/App.test.js.

Met de nieuwe toevoegingen zul je nu zien dat de act-waarschuwing niet langer aanwezig is in je tests:

Output
PASS src/App.test.js ✓ renders the landing page (123 ms) Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 0 total Time: 0.942 s, estimated 2 s Ran all test suites related to changed files. Watch Usage: Press w to show more.

In deze stap heb je geleerd hoe je de act-waarschuwing kunt oplossen die kan optreden bij het werken met asynchrone code. Hierna voeg je een tweede testgeval toe om de interactieve functionaliteiten van de Doggy Directory applicatie te verifiëren.

Stap 5 — Testen van de zoekfunctie

In de laatste stap schrijf je een nieuw testgeval om de zoek- en afbeeldingsweergavefunctie te verifiëren. Je zult verschillende query’s en API-methoden benutten om de juiste testdekking te bereiken.

Keer terug naar het src/App.test.js bestand in je editor. Importeer bovenaan het bestand de user-event bijbehorende bibliotheek en de waitForElementToBeRemoved asynchrone methode in het testbestand met de volgende commando’s:

src/App.test.js
import { render, screen, waitForElementToBeRemoved } from '@testing-library/react';import userEvent from '@testing-library/user-event'; 
...

Je zult deze imports later in deze sectie gebruiken.

Na de initiële test() methode, voeg een nieuwe asynchrone testblok toe en render de App component met de volgende codeblok:

src/App.test.js
...
test("should be able to search and display dog image results", async () => {
   render(<App />);
})

Met de component weergegeven, kun je nu functies toevoegen die de interactieve functies van de Doggy Directory app verifiëren.

Nog steeds in src/App.test.js, voeg de gemarkeerde codeblokken toe binnen de tweede test() methode:

src/App.test.js
...
test("should be able to search and display dog image results", async () => {
   render(<App />);
   
   //Simuleer het selecteren van een optie en controleer de waarde
   const select = screen.getByRole("combobox");
   expect(await screen.findByRole("option", { name: "cattledog"})).toBeInTheDocument();
   userEvent.selectOptions(select, "cattledog");
   expect(select).toHaveValue("cattledog");
})

Het hierboven gemarkeerde gedeelte zal de selectie van een hondenras simuleren en controleren of de juiste waarde wordt weergegeven.

De getByRole query pakt het geselecteerde element en kent het toe aan de select variabele.

Vergelijkbaar met hoe je de act waarschuwing hebt opgelost in Stap 4, gebruik de findByRole query om te wachten tot de cattledog optie verschijnt in het document voordat je doorgaat met verdere beweringen.

Het eerder geïmporteerde userEvent-object zal gebruikelijke gebruikersinteracties simuleren. In dit voorbeeld selecteert de selectOptions-methode de cattledog-optie waarop je eerder hebt gewacht.

De laatste regel controleert dat de select-variabele de hierboven geselecteerde waarde cattledog bevat.

Het volgende gedeelte dat je aan het Javascript test()-blok toevoegt, zal het zoekverzoek initiëren om hondenafbeeldingen te vinden op basis van het geselecteerde ras en de aanwezigheid van een laadstatus bevestigen.

Voeg de gemarkeerde regels toe:

src/App.test.js
...
test("should be able to search and display dog image results", async () => {
   render(<App />);
    
   //...Simuleer het selecteren van een optie en controleer de waarde

  //Simuleer het starten van het zoekverzoek
   const searchBtn = screen.getByRole("button", { name: "Search" });
   expect(searchBtn).not.toBeDisabled();
   userEvent.click(searchBtn);

   //De laadstatus wordt weergegeven en verdwijnt zodra de resultaten worden weergegeven
   await waitForElementToBeRemoved(() => screen.queryByText(/Loading/i));
})

De getByRole-query lokaliseert de zoekknop en kent deze toe aan de variabele searchBtn.

De toBeDisabled-jest-dom-matcher zal controleren of de zoekknop niet is uitgeschakeld wanneer een rasselectie is gemaakt.

De click-methode op het userEvent-object simuleert het klikken op de zoekknop.

De waitForElementToBeRemoved asynchrone hulp functie die eerder is geïmporteerd, zal wachten op het verschijnen en verdwijnen van het laden bericht terwijl de zoek-API-oproep plaatsvindt. queryByText binnen de waitForElementToBeRemoved callback controleert op de afwezigheid van een element zonder een fout te veroorzaken.

De onderstaande afbeelding toont de laadstatus die wordt weergegeven wanneer er een zoekopdracht bezig is:

Voeg vervolgens de volgende JavaScript-code toe om de afbeelding en het resultaattellingweergave te valideren:

src/App.test.js
...
test("should be able to search and display dog image results", async () => {
   render(<App />)
   
   //...Simuleer het selecteren van een optie en controleer de waarde
   //...Simuleer het starten van de zoekopdracht
   //...De laadstatus wordt weergegeven en verdwijnt zodra de resultaten worden weergegeven
          
   //Controleer de afbeeldingsweergave en het resultaattelling
   const dogImages = screen.getAllByRole("img");
   expect(dogImages).toHaveLength(2);
   expect(screen.getByText(/2 Results/i)).toBeInTheDocument();
   expect(dogImages[0]).toHaveAccessibleName("cattledog 1 of 2");
   expect(dogImages[1]).toHaveAccessibleName("cattledog 2 of 2");
})

De getAllByRole query zal alle hondafbeeldingen selecteren en ze toewijzen aan de dogImages variabele. De *AllBy* variant van de query retourneert een array met meerdere elementen die overeenkomen met de opgegeven rol. De *AllBy* variant verschilt van de ByRole variant, die slechts één element kan retourneren.

De nagebootste fetch implementatie bevatte twee afbeeldings-URL’s binnen de respons. Met Jest’s toHaveLength matcher kun je verifiëren dat er twee afbeeldingen worden weergegeven.

De getByText query zal controleren of het juiste resultaataantal verschijnt in de rechterbovenhoek.

Twee assertions met behulp van de toHaveAccessibleName matchers verifiëren dat de juiste alt-tekst is gekoppeld aan individuele afbeeldingen.

A completed search displaying images of the dog based on the breed selected along with the number of results found will look like this:

Wanneer je alle onderdelen van de nieuwe JavaScript-code combineert, zal het App.test.js bestand er zo uitzien:

src/App.test.js
import {render, screen, waitForElementToBeRemoved} from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import mockFetch from "./mocks/mockFetch";
import App from './App';

beforeEach(() => {
   jest.spyOn(window, "fetch").mockImplementation(mockFetch);
})

afterEach(() => {
   jest.restoreAllMocks();
});

test('renders the landing page', async () => {
   render(<App />);

   expect(screen.getByRole("heading")).toHaveTextContent(/Doggy Directory/);
   expect(screen.getByRole("combobox")).toHaveDisplayValue("Select a breed");
   expect(await screen.findByRole("option", { name: "husky"})).toBeInTheDocument()
   expect(screen.getByRole("button", { name: "Search" })).toBeDisabled();
   expect(screen.getByRole("img")).toBeInTheDocument();
});

test("should be able to search and display dog image results", async () => {
   render(<App />);

   //Simuleer het selecteren van een optie en verifieer de waarde
   const select = screen.getByRole("combobox");
   expect(await screen.findByRole("option", { name: "cattledog"})).toBeInTheDocument();
   userEvent.selectOptions(select, "cattledog");
   expect(select).toHaveValue("cattledog");

   //Start het zoekverzoek
   const searchBtn = screen.getByRole("button", { name: "Search" });
   expect(searchBtn).not.toBeDisabled();
   userEvent.click(searchBtn);

   //Laadstatus wordt weergegeven en verwijderd zodra de resultaten worden weergegeven
   await waitForElementToBeRemoved(() => screen.queryByText(/Loading/i));

   //Verifieer afbeeldingsweergave en resultaataantal
   const dogImages = screen.getAllByRole("img");
   expect(dogImages).toHaveLength(2);
   expect(screen.getByText(/2 Results/i)).toBeInTheDocument();
   expect(dogImages[0]).toHaveAccessibleName("cattledog 1 of 2");
   expect(dogImages[1]).toHaveAccessibleName("cattledog 2 of 2");
})

Sla de wijzigingen op in src/App.test.js.

Wanneer je je tests bekijkt, zal de uiteindelijke uitvoer in de terminal nu de volgende uitvoer hebben:

Output
PASS src/App.test.js ✓ renders the landing page (273 ms) ✓ should be able to search and display dog image results (123 ms) Test Suites: 1 passed, 1 total Tests: 2 passed, 2 total Snapshots: 0 total Time: 4.916 s Ran all test suites related to changed files. Watch Usage: Press w to show more.

In deze laatste stap heb je een test toegevoegd die de zoek-, laad- en weergavefunctionaliteiten van de Doggy Directory applicatie verifieert. Met de laatste assertion geschreven, weet je nu dat je app werkt.

Conclusie

Gedurende deze tutorial schreef je testcases met behulp van Jest, React Testing Library en jest-dom matchers. Stapsgewijs heb je tests geschreven op basis van hoe een gebruiker met de UI omgaat. Je hebt ook geleerd over de verschillen tussen de getBy*, findBy* en queryBy* queries, en hoe je asynchrone code kunt testen.

Om meer te weten te komen over de genoemde onderwerpen, bekijk de officiële documentatie van Jest, React Testing Library en jest-dom. Je kunt ook Kent C. Dodds’ Common Mistakes with React Testing Library lezen om meer te leren over de beste praktijken bij het werken met React Testing Library. Voor meer informatie over het gebruik van snapshot tests binnen een React App, bekijk Hoe Snapshot Tests te Schrijven.

Source:
https://www.digitalocean.com/community/tutorials/how-to-test-a-react-app-with-jest-and-react-testing-library