Apgūstiet React komponentu testēšanu ar React Testing Library. Uzziniet labākās prakses, kā rakstīt uzturamus, efektīvus testus, kas vērsti uz lietotāja uzvedību un pieejamību.
React Testing Library: Komponentu testēšanas labākās prakses globālām komandām
Nepārtraukti mainīgajā tīmekļa izstrādes pasaulē jūsu React lietojumprogrammu uzticamības un kvalitātes nodrošināšana ir vissvarīgākā. Tas jo īpaši attiecas uz globālām komandām, kas strādā pie projektiem ar daudzveidīgu lietotāju bāzi un pieejamības prasībām. React Testing Library (RTL) nodrošina jaudīgu un uz lietotāju orientētu pieeju komponentu testēšanai. Atšķirībā no tradicionālajām testēšanas metodēm, kas koncentrējas uz implementācijas detaļām, RTL mudina jūs testēt savas komponentes tā, kā lietotājs ar tām mijiedarbotos, tādējādi radot robustākus un uzturamus testus. Šī visaptverošā rokasgrāmata iedziļināsies labākajās praksēs RTL izmantošanai jūsu React projektos, koncentrējoties uz lietojumprogrammu izveidi, kas piemērotas globālai auditorijai.
Kāpēc React Testing Library?
Pirms iedziļināties labākajās praksēs, ir svarīgi saprast, kāpēc RTL izceļas starp citām testēšanas bibliotēkām. Šeit ir dažas galvenās priekšrocības:
- Lietotājorientēta pieeja: RTL prioritāte ir komponentu testēšana no lietotāja perspektīvas. Jūs mijiedarbojaties ar komponenti, izmantojot tās pašas metodes, ko lietotājs (piemēram, noklikšķinot uz pogām, rakstot ievades laukos), nodrošinot reālistiskāku un uzticamāku testēšanas pieredzi.
- Uz pieejamību vērsta: RTL veicina pieejamu komponenšu rakstīšanu, mudinot jūs tās testēt tā, lai ņemtu vērā lietotājus ar invaliditāti. Tas atbilst globālajiem pieejamības standartiem, piemēram, WCAG.
- Samazināta uzturēšana: Izvairoties no implementācijas detaļu testēšanas (piemēram, iekšējā stāvokļa, specifisku funkciju izsaukumu), RTL testi ir mazāk pakļauti bojājumiem, kad jūs refaktorējat savu kodu. Tas nodrošina uzturamus un noturīgus testus.
- Uzlabots koda dizains: RTL lietotājorientētā pieeja bieži noved pie labāka komponentu dizaina, jo esat spiests domāt par to, kā lietotāji mijiedarbosies ar jūsu komponentēm.
- Kopiena un ekosistēma: RTL lepojas ar lielu un aktīvu kopienu, kas nodrošina plašus resursus, atbalstu un paplašinājumus.
Testēšanas vides iestatīšana
Lai sāktu darbu ar RTL, jums būs jāiestata sava testēšanas vide. Šeit ir pamata iestatīšana, izmantojot Create React App (CRA), kas nāk ar iepriekš konfigurētu Jest un RTL:
npx create-react-app my-react-app
cd my-react-app
npm install --save-dev @testing-library/react @testing-library/jest-dom
Paskaidrojums:
- `npx create-react-app my-react-app`: Izveido jaunu React projektu, izmantojot Create React App.
- `cd my-react-app`: Pārvietojas uz jaunizveidotā projekta direktoriju.
- `npm install --save-dev @testing-library/react @testing-library/jest-dom`: Instalē nepieciešamās RTL pakotnes kā izstrādes atkarības. `@testing-library/react` nodrošina galveno RTL funkcionalitāti, savukārt `@testing-library/jest-dom` nodrošina noderīgus Jest saskaņotājus (matchers) darbam ar DOM.
Ja neizmantojat CRA, jums būs jāinstalē Jest un RTL atsevišķi un jākonfigurē Jest, lai izmantotu RTL.
Labākās prakses komponentu testēšanai ar React Testing Library
1. Rakstiet testus, kas atgādina lietotāja mijiedarbību
RTL pamatprincips ir testēt komponentes tā, kā to darītu lietotājs. Tas nozīmē koncentrēties uz to, ko lietotājs redz un dara, nevis uz iekšējām implementācijas detaļām. Izmantojiet `screen` objektu, ko nodrošina RTL, lai vaicātu elementus, pamatojoties uz to tekstu, lomu vai pieejamības etiķetēm.
Piemērs: Pogas klikšķa testēšana
Pieņemsim, ka jums ir vienkārša pogas komponente:
// Button.js
import React from 'react';
function Button({ onClick, children }) {
return ;
}
export default Button;
Šādi to testētu, izmantojot RTL:
// Button.test.js
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import Button from './Button';
describe('Button Component', () => {
it('calls the onClick handler when clicked', () => {
const handleClick = jest.fn();
render();
const buttonElement = screen.getByText('Click Me');
fireEvent.click(buttonElement);
expect(handleClick).toHaveBeenCalledTimes(1);
});
});
Paskaidrojums:
- `render()`: Renderē Button komponenti ar imitētu (mock) `onClick` apstrādātāju.
- `screen.getByText('Click Me')`: Vaicā dokumentā elementu, kas satur tekstu "Click Me". Šādi lietotājs identificētu pogu.
- `fireEvent.click(buttonElement)`: Simulē klikšķa notikumu uz pogas elementa.
- `expect(handleClick).toHaveBeenCalledTimes(1)`: Apstiprina, ka `onClick` apstrādātājs tika izsaukts vienu reizi.
Kāpēc tas ir labāk nekā testēt implementācijas detaļas: Iedomājieties, ka jūs refaktorējat Button komponenti, lai izmantotu citu notikumu apstrādātāju vai mainītu iekšējo stāvokli. Ja jūs testētu konkrēto notikumu apstrādātāja funkciju, jūsu tests sabruktu. Koncentrējoties uz lietotāja mijiedarbību (noklikšķinot uz pogas), tests paliek spēkā arī pēc refaktorēšanas.
2. Piešķiriet prioritāti vaicājumiem, pamatojoties uz lietotāja nodomu
RTL nodrošina dažādas vaicājumu metodes elementu atrašanai. Piešķiriet prioritāti šiem vaicājumiem šādā secībā, jo tie vislabāk atspoguļo, kā lietotāji uztver un mijiedarbojas ar jūsu komponentēm:
- getByRole: Šis vaicājums ir vispieejamākais un tam vajadzētu būt jūsu pirmajai izvēlei. Tas ļauj jums atrast elementus, pamatojoties uz to ARIA lomām (piem., button, link, heading).
- getByLabelText: Izmantojiet šo, lai atrastu elementus, kas saistīti ar konkrētu etiķeti, piemēram, ievades laukus.
- getByPlaceholderText: Izmantojiet šo, lai atrastu ievades laukus, pamatojoties uz to viettura tekstu.
- getByText: Izmantojiet šo, lai atrastu elementus, pamatojoties uz to teksta saturu. Esiet specifisks un izvairieties no vispārīga teksta, kas varētu parādīties vairākās vietās.
- getByDisplayValue: Izmantojiet šo, lai atrastu ievades laukus, pamatojoties uz to pašreizējo vērtību.
Piemērs: Formas ievades lauka testēšana
// Input.js
import React from 'react';
function Input({ label, placeholder, value, onChange }) {
return (
);
}
export default Input;
Šādi to testētu, izmantojot ieteicamo vaicājumu secību:
// Input.test.js
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import Input from './Input';
describe('Input Component', () => {
it('updates the value when the user types', () => {
const handleChange = jest.fn();
render();
const inputElement = screen.getByLabelText('Name');
fireEvent.change(inputElement, { target: { value: 'John Doe' } });
expect(handleChange).toHaveBeenCalledTimes(1);
expect(handleChange).toHaveBeenCalledWith(expect.objectContaining({ target: { value: 'John Doe' } }));
});
});
Paskaidrojums:
- `screen.getByLabelText('Name')`: Izmanto `getByLabelText`, lai atrastu ievades lauku, kas saistīts ar etiķeti "Name". Tas ir vispieejamākais un lietotājam draudzīgākais veids, kā atrast ievades lauku.
3. Izvairieties no implementācijas detaļu testēšanas
Kā jau minēts iepriekš, izvairieties no iekšējā stāvokļa, funkciju izsaukumu vai specifisku CSS klašu testēšanas. Tās ir implementācijas detaļas, kas var mainīties un var novest pie trausliem testiem. Koncentrējieties uz komponentes novērojamo uzvedību.
Piemērs: Izvairieties no stāvokļa tiešas testēšanas
Tā vietā, lai testētu, vai konkrēts stāvokļa mainīgais tiek atjaunināts, testējiet, vai komponente renderē pareizo izvadi, pamatojoties uz šo stāvokli. Piemēram, ja komponente parāda ziņojumu, pamatojoties uz Būla stāvokļa mainīgo, testējiet, vai ziņojums tiek parādīts vai paslēpts, nevis testējiet pašu stāvokļa mainīgo.
4. Izmantojiet `data-testid` specifiskos gadījumos
Lai gan parasti vislabāk ir izvairīties no `data-testid` atribūtu izmantošanas, ir specifiski gadījumi, kad tie var būt noderīgi:
- Elementi bez semantiskas nozīmes: Ja jums ir nepieciešams mērķēt uz elementu, kuram nav jēgpilnas lomas, etiķetes vai teksta, varat izmantot `data-testid`.
- Sarežģītas komponentu struktūras: Sarežģītās komponentu struktūrās `data-testid` var palīdzēt mērķēt uz konkrētiem elementiem, nepaļaujoties uz trausliem selektoriem.
- Pieejamības testēšana: `data-testid` var izmantot, lai identificētu konkrētus elementus pieejamības testēšanas laikā ar rīkiem, piemēram, Cypress vai Playwright.
Piemērs: `data-testid` izmantošana
// MyComponent.js
import React from 'react';
function MyComponent() {
return (
This is my component.
);
}
export default MyComponent;
// MyComponent.test.js
import React from 'react';
import { render, screen } from '@testing-library/react';
import MyComponent from './MyComponent';
describe('MyComponent', () => {
it('renders the component container', () => {
render( );
const containerElement = screen.getByTestId('my-component-container');
expect(containerElement).toBeInTheDocument();
});
});
Svarīgi: Izmantojiet `data-testid` reti un tikai tad, kad citas vaicājumu metodes nav piemērotas.
5. Rakstiet jēgpilnus testu aprakstus
Skaidri un kodolīgi testu apraksti ir būtiski, lai saprastu katra testa mērķi un novērstu kļūmes. Izmantojiet aprakstošus nosaukumus, kas skaidri paskaidro, ko tests pārbauda.
Piemērs: Labi vs. slikti testu apraksti
Slikti: `it('works')`
Labi: `it('displays the correct greeting message')`
Vēl labāk: `it('displays the greeting message "Hello, World!" when the name prop is not provided')`
Labākais piemērs skaidri norāda komponentes gaidīto uzvedību konkrētos apstākļos.
6. Saglabājiet testus mazus un fokusētus
Katram testam jākoncentrējas uz viena komponentes uzvedības aspekta pārbaudi. Izvairieties no lielu, sarežģītu testu rakstīšanas, kas aptver vairākus scenārijus. Mazi, fokusēti testi ir vieglāk saprotami, uzturami un atkļūdojami.
7. Atbilstoši izmantojiet testu dubultniekus (Mocks and Spies)
Testu dubultnieki ir noderīgi, lai izolētu komponenti, kuru testējat, no tās atkarībām. Izmantojiet imitācijas (mocks) un spiegotājus (spies), lai simulētu ārējos pakalpojumus, API izsaukumus vai citas komponentes.
Piemērs: API izsaukuma imitēšana
// UserList.js
import React, { useState, useEffect } from 'react';
function UserList() {
const [users, setUsers] = useState([]);
useEffect(() => {
async function fetchUsers() {
const response = await fetch('/api/users');
const data = await response.json();
setUsers(data);
}
fetchUsers();
}, []);
return (
{users.map(user => (
- {user.name}
))}
);
}
export default UserList;
// UserList.test.js
import React from 'react';
import { render, screen, waitFor } from '@testing-library/react';
import UserList from './UserList';
global.fetch = jest.fn(() =>
Promise.resolve({
json: () => Promise.resolve([
{ id: 1, name: 'John Doe' },
{ id: 2, name: 'Jane Smith' },
]),
})
);
describe('UserList Component', () => {
it('fetches and displays a list of users', async () => {
render( );
// Wait for the data to load
await waitFor(() => screen.getByText('John Doe'));
expect(screen.getByText('John Doe')).toBeInTheDocument();
expect(screen.getByText('Jane Smith')).toBeInTheDocument();
});
});
Paskaidrojums:
- `global.fetch = jest.fn(...)`: Imitē `fetch` funkciju, lai atgrieztu iepriekš definētu lietotāju sarakstu. Tas ļauj jums testēt komponenti, nepaļaujoties uz reālu API galapunktu.
- `await waitFor(() => screen.getByText('John Doe'))`: Gaida, līdz dokumentā parādās teksts "John Doe". Tas ir nepieciešams, jo dati tiek ielādēti asinhroni.
8. Testējiet robežgadījumus un kļūdu apstrādi
Netestējiet tikai "laimīgo ceļu". Noteikti testējiet robežgadījumus, kļūdu scenārijus un robežnosacījumus. Tas palīdzēs jums agrīni identificēt potenciālās problēmas un nodrošināt, ka jūsu komponente graciozi apstrādā neparedzētas situācijas.
Piemērs: Kļūdu apstrādes testēšana
Iedomājieties komponenti, kas ielādē datus no API un parāda kļūdas ziņojumu, ja API izsaukums neizdodas. Jums vajadzētu uzrakstīt testu, lai pārbaudītu, vai kļūdas ziņojums tiek pareizi parādīts, kad API izsaukums neizdodas.
9. Koncentrējieties uz pieejamību
Pieejamība ir izšķiroša, lai izveidotu iekļaujošas tīmekļa lietojumprogrammas. Izmantojiet RTL, lai testētu savu komponenšu pieejamību un nodrošinātu, ka tās atbilst pieejamības standartiem, piemēram, WCAG. Daži galvenie pieejamības apsvērumi ietver:
- Semantiskais HTML: Izmantojiet semantiskos HTML elementus (piem., `<button>`, `<nav>`, `<article>`), lai nodrošinātu satura struktūru un nozīmi.
- ARIA atribūti: Izmantojiet ARIA atribūtus, lai sniegtu papildu informāciju par elementu lomu, stāvokli un īpašībām, īpaši pielāgotām komponentēm.
- Navigācija ar tastatūru: Nodrošiniet, ka visi interaktīvie elementi ir pieejami, izmantojot tastatūras navigāciju.
- Krāsu kontrasts: Izmantojiet pietiekamu krāsu kontrastu, lai nodrošinātu, ka teksts ir salasāms lietotājiem ar vāju redzi.
- Ekrāna lasītāju saderība: Testējiet savas komponentes ar ekrāna lasītāju, lai nodrošinātu, ka tās sniedz jēgpilnu un saprotamu pieredzi lietotājiem ar redzes traucējumiem.
Piemērs: Pieejamības testēšana ar `getByRole`
// MyAccessibleComponent.js
import React from 'react';
function MyAccessibleComponent() {
return (
);
}
export default MyAccessibleComponent;
// MyAccessibleComponent.test.js
import React from 'react';
import { render, screen } from '@testing-library/react';
import MyAccessibleComponent from './MyAccessibleComponent';
describe('MyAccessibleComponent', () => {
it('renders an accessible button with the correct aria-label', () => {
render( );
const buttonElement = screen.getByRole('button', { name: 'Close' });
expect(buttonElement).toBeInTheDocument();
});
});
Paskaidrojums:
- `screen.getByRole('button', { name: 'Close' })`: Izmanto `getByRole`, lai atrastu pogas elementu ar pieejamo nosaukumu "Close". Tas nodrošina, ka poga ir pareizi marķēta ekrāna lasītājiem.
10. Integrējiet testēšanu savā izstrādes darbplūsmā
Testēšanai jābūt neatņemamai jūsu izstrādes darbplūsmas daļai, nevis pēcaprūpei. Integrējiet savus testus savā CI/CD konveijerā, lai automātiski palaistu testus ikreiz, kad kods tiek iesniegts vai izvietots. Tas palīdzēs jums agrīni atklāt kļūdas un novērst regresijas.
11. Apsveriet lokalizāciju un internacionalizāciju (i18n)
Globālām lietojumprogrammām ir ļoti svarīgi testēšanas laikā ņemt vērā lokalizāciju un internacionalizāciju (i18n). Nodrošiniet, ka jūsu komponentes pareizi renderējas dažādās valodās un lokalizācijās.
Piemērs: Lokalizācijas testēšana
Ja lokalizācijai izmantojat tādu bibliotēku kā `react-intl` vai `i18next`, varat savos testos imitēt lokalizācijas kontekstu, lai pārbaudītu, vai jūsu komponentes parāda pareizo tulkoto tekstu.
12. Izmantojiet pielāgotas renderēšanas funkcijas atkārtoti lietojamai iestatīšanai
Strādājot pie lielākiem projektiem, jūs varat atklāt, ka atkārtojat tos pašus iestatīšanas soļus vairākos testos. Lai izvairītos no dublēšanās, izveidojiet pielāgotas renderēšanas funkcijas, kas ietver kopējo iestatīšanas loģiku.
Piemērs: Pielāgota renderēšanas funkcija
// test-utils.js
import React from 'react';
import { render } from '@testing-library/react';
import { ThemeProvider } from 'styled-components';
import theme from './theme';
const AllTheProviders = ({ children }) => {
return (
{children}
);
}
const customRender = (ui, options) =>
render(ui, { wrapper: AllTheProviders, ...options })
// re-export everything
export * from '@testing-library/react'
// override render method
export { customRender as render }
// MyComponent.test.js
import React from 'react';
import { render, screen } from './test-utils'; // Import the custom render
import MyComponent from './MyComponent';
describe('MyComponent', () => {
it('renders correctly with the theme', () => {
render( );
// Your test logic here
});
});
Šis piemērs izveido pielāgotu renderēšanas funkciju, kas ietin komponenti ar ThemeProvider. Tas ļauj jums viegli testēt komponentes, kas paļaujas uz tēmu, neatkārtojot ThemeProvider iestatīšanu katrā testā.
Noslēgums
React Testing Library piedāvā jaudīgu un uz lietotāju orientētu pieeju komponentu testēšanai. Ievērojot šīs labākās prakses, jūs varat rakstīt uzturamus, efektīvus testus, kas koncentrējas uz lietotāja uzvedību un pieejamību. Tas novedīs pie robustākām, uzticamākām un iekļaujošākām React lietojumprogrammām globālai auditorijai. Atcerieties piešķirt prioritāti lietotāju mijiedarbībai, izvairīties no implementācijas detaļu testēšanas, koncentrēties uz pieejamību un integrēt testēšanu savā izstrādes darbplūsmā. Pieņemot šos principus, jūs varat veidot augstas kvalitātes React lietojumprogrammas, kas atbilst lietotāju vajadzībām visā pasaulē.
Galvenās atziņas:
- Koncentrējieties uz lietotāju mijiedarbību: Testējiet komponentes tā, kā lietotājs ar tām mijiedarbotos.
- Piešķiriet prioritāti pieejamībai: Nodrošiniet, ka jūsu komponentes ir pieejamas lietotājiem ar invaliditāti.
- Izvairieties no implementācijas detaļām: Netestējiet iekšējo stāvokli vai funkciju izsaukumus.
- Rakstiet skaidrus un kodolīgus testus: Padariet savus testus viegli saprotamus un uzturamus.
- Integrējiet testēšanu savā darbplūsmā: Automatizējiet savus testus un regulāri tos palaidiet.
- Apsveriet globālas auditorijas: Nodrošiniet, ka jūsu komponentes labi darbojas dažādās valodās un lokalizācijās.