Testarea este adesea văzută ca un proces obositor. Este un cod suplimentar pe care trebuie să îl scrieți și, în unele cazuri, pentru a fi sincer, nu este necesar. Dar fiecare dezvoltator ar trebui să cunoască cel puțin elementele de bază ale testării. Crește încrederea în produsele pe care le construiesc, iar pentru majoritatea companiilor este o cerință.

În lumea React, există o bibliotecă uimitoare numită react-testing-library ceea ce vă ajută să testați aplicațiile React mai eficient. O folosești cu Jest.

În acest articol, vom vedea cei 8 pași simpli pe care îi puteți face pentru a începe să testați aplicațiile React ca un șef.

  • Condiții prealabile
  • Noțiuni de bază
  • Ce este React Testing Library?
  • 1. Cum se creează un instantaneu de testare?
  • 2. Testarea elementelor DOM
  • 3. Testarea evenimentelor
  • 4. Testarea acțiunilor asincrone
  • 5. Testarea React Redux
  • 6. Testarea contextului React
  • 7. Testarea routerului React
  • 8. Testarea cererii HTTP
  • Gânduri finale
  • Pasii urmatori

Condiții prealabile

Acest tutorial presupune că aveți cel puțin o înțelegere de bază despre React. Mă voi concentra doar pe partea de testare.

Și pentru a continua, trebuie să clonați proiectul rulând în terminalul dvs.:

ad-banner
  git clone https://github.com/ibrahima92/prep-react-testing-library-guide

Apoi, executați:

  yarn

Sau, dacă utilizați NPM:

npm install

Si asta e! Acum să ne scufundăm în câteva elemente de bază.

Noțiuni de bază

Unele lucruri cheie vor fi folosite mult în acest articol, iar înțelegerea rolului lor vă poate ajuta cu înțelegerea dvs.

it or test: descrie testul în sine. Ia ca parametri numele testului și o funcție care deține testele.

expect: condiția pe care trebuie să o treacă testul. Acesta va compara parametrul primit cu un meci.

a matcher: o funcție care se aplică condiției așteptate.

render: metoda utilizată pentru redarea unei componente date.

import React from 'react'
import {render} from '@testing-library/react'
import App from './App'
 
 it('should take a snapshot', () => {
    const { asFragment } = render(<App />)
    
    expect(asFragment(<App />)).toMatchSnapshot()
   })
});

După cum puteți vedea, descriem testul cu it, apoi, utilizați render pentru a afișa componenta aplicației și așteptați acest lucru asFragment(<App />) chibrituri toMatchSnapshot() (meciul furnizat de jest-dom).

Apropo, render metoda returnează mai multe metode pe care le putem folosi pentru a ne testa caracteristicile. De asemenea, am folosit destructurarea pentru a obține metoda.

Acestea fiind spuse, să trecem mai departe și să aflăm mai multe despre React Testing Library în secțiunea următoare.

Ce este biblioteca React Testing?

Biblioteca React Testing este un pachet foarte ușor creat de Kent C. Dodds. Este un înlocuitor pentru Enzimă și oferă funcții de utilitate ușoară deasupra react-dom și react-dom/test-utils.

Biblioteca React Testing Library este o bibliotecă de testare DOM, ceea ce înseamnă că, în loc să se ocupe de instanțele componentelor React redate, gestionează elementele DOM și cum se comportă în fața utilizatorilor reali.

Este o bibliotecă excelentă, este (relativ) ușor de început și încurajează bune practici de testare. Notă – îl puteți folosi și fără Jest.

„Cu cât testele tale seamănă mai mult cu modul în care este folosit software-ul tău, cu atât îți pot oferi mai multă încredere.”

Deci, să începem să-l folosim în secțiunea următoare. Apropo, nu trebuie să instalați niciun pachet, deoarece create-react-app vine cu biblioteca și dependențele sale.

1. Cum se creează un instantaneu de testare

Un instantaneu, așa cum sugerează și numele, ne permite să salvăm instantaneul unei componente date. Ajută foarte mult atunci când actualizați sau faceți o refacturare și doriți să obțineți sau să comparați modificările.

Acum, să facem un instantaneu al fișierului App.js fişier.

  • App.test.js
import React from 'react'
import {render, cleanup} from '@testing-library/react'
import App from './App'

 afterEach(cleanup)
 
 it('should take a snapshot', () => {
    const { asFragment } = render(<App />)
    
    expect(asFragment(<App />)).toMatchSnapshot()
   })
});

Pentru a face un instantaneu, trebuie mai întâi să importăm render și cleanup. Aceste două metode vor fi folosite foarte mult pe parcursul acestui articol.

render, după cum ați putea ghici, ajută la redarea unei componente React. Și cleanup este transmis ca parametru către afterEach pentru a curăța totul după fiecare test pentru a evita scurgerile de memorie.

Apoi, putem reda componenta aplicației cu render și întoarce-te asFragment ca valoare returnată din metodă. Și, în cele din urmă, asigurați-vă că fragmentul componentei aplicației se potrivește instantaneului.

Acum, pentru a rula testul, deschideți terminalul și navigați la rădăcina proiectului și rulați următoarea comandă:

  yarn test

Sau, dacă utilizați npm:

  npm test

Ca urmare, va crea un folder nou __snapshots__ și un dosar App.test.js.snap în src care va arăta astfel:

  • App.test.js.snap
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Take a snapshot should take a snapshot 1`] = `
<DocumentFragment>
  <div class="App">
    <h1>Testing</h1>
  </div>
</DocumentFragment>
`;

Și dacă mai faci o schimbare App.js, testul va eșua, deoarece instantaneul nu va mai corespunde condiției. Pentru a trece, apăsați u pentru a-l actualiza. Și veți avea instantaneul actualizat în App.test.js.snap.

Acum, să mergem mai departe și să începem să ne testăm elementele.

2. Testarea elementelor DOM

Pentru a testa elementele DOM, trebuie mai întâi să ne uităm la TestElements.js fişier.

  • TestElements.js
import React from 'react'

const TestElements = () => {
 const [counter, setCounter] = React.useState(0)
  
 return (
  <>
    <h1 data-testid="counter">{ counter }</h1>
    <button data-testid="button-up" onClick={() => setCounter(counter + 1)}> Up</button>
    <button disabled data-testid="button-down" onClick={() => setCounter(counter - 1)}>Down</button>
 </>
    )
  }
  
export default TestElements

Aici, singurul lucru pe care trebuie să-l reții este data-testid. Acesta va fi folosit pentru a selecta aceste elemente din fișierul de testare. Acum, să scriem testul unitar:

Testați dacă contorul este egal cu 0:

TestElements.test.js

import React from 'react';
import { render, cleanup } from '@testing-library/react';
import TestElements from './TestElements'

afterEach(cleanup);

  it('should equal to 0', () => {
    const { getByTestId } = render(<TestElements />); 
    expect(getByTestId('counter')).toHaveTextContent(0)
   });

După cum puteți vedea, sintaxa este destul de similară cu testul anterior. Singura diferență este că folosim getByTestId pentru a selecta elementele necesare (amintiți – vă data-testid) și verificați dacă a trecut testul. Cu alte cuvinte, verificăm dacă conținutul textului <h1 data-testid="counter">{ counter }</h1> este egal cu 0.

Testați dacă butoanele sunt activate sau dezactivate:

TestElements.test.js (adăugați următorul bloc de cod în fișier)

   it('should be enabled', () => {
    const { getByTestId } = render(<TestElements />);
    expect(getByTestId('button-up')).not.toHaveAttribute('disabled')
  });

  it('should be disabled', () => {
    const { getByTestId } = render(<TestElements />); 
    expect(getByTestId('button-down')).toBeDisabled()
  });

Aici, ca de obicei, folosim getByTestId pentru a selecta elemente și pentru a verifica primul test dacă butonul are un disabled atribut. Și pentru al doilea, dacă butonul este dezactivat sau nu.

Și dacă salvați fișierul sau rulați din nou în terminal yarn test, testul va trece.

Felicitări! Primul dvs. test a trecut!

felicitări

Acum, să învățăm cum să testăm un eveniment în secțiunea următoare.

3. Testarea evenimentelor

Înainte de a scrie testele noastre unitare, să verificăm mai întâi ce este TestEvents.js se pare ca.

  • TestEvents.js
import React from 'react'

const TestEvents = () => {
  const [counter, setCounter] = React.useState(0)
  
return (
  <>
    <h1 data-testid="counter">{ counter }</h1>
    <button data-testid="button-up" onClick={() => setCounter(counter + 1)}> Up</button>
    <button data-testid="button-down" onClick={() => setCounter(counter - 1)}>Down</button>
 </>
    )
  }
  
  export default TestEvents

Acum, să scriem testele.

Testați dacă contorul crește și descrește corect atunci când facem clic pe butoane:

TestEvents.test.js

import React from 'react';
import { render, cleanup, fireEvent } from '@testing-library/react';
import TestEvents from './TestEvents'

  afterEach(cleanup);
  
  it('increments counter', () => {
    const { getByTestId } = render(<TestEvents />); 
    
    fireEvent.click(getByTestId('button-up'))

    expect(getByTestId('counter')).toHaveTextContent('1')
  });

  it('decrements counter', () => {
    const { getByTestId } = render(<TestEvents />); 
    
    fireEvent.click(getByTestId('button-down'))

    expect(getByTestId('counter')).toHaveTextContent('-1')
  });

După cum puteți vedea, aceste două teste sunt foarte similare, cu excepția conținutului text așteptat.

Primul test declanșează un eveniment de clic cu fireEvent.click() pentru a verifica dacă contorul crește la 1 când se face clic pe buton.

Și al doilea verifică dacă contorul scade la -1 când se face clic pe buton.

fireEvent are mai multe metode pe care le puteți folosi pentru a testa evenimentele, așa că nu ezitați să vă scufundați în documentație pentru a afla mai multe.

Acum, că știm cum să testăm evenimentele, să trecem mai departe și să învățăm în secțiunea următoare cum să facem față acțiunilor asincrone.

4. Testarea acțiunilor asincrone

O acțiune asincronă este ceva care poate dura mult timp. Poate fi o cerere HTTP, un cronometru și așa mai departe.

Acum, să verificăm TestAsync.js fişier.

  • TestAsync.js
import React from 'react'

const TestAsync = () => {
  const [counter, setCounter] = React.useState(0)

  const delayCount = () => (
    setTimeout(() => {
      setCounter(counter + 1)
    }, 500)
  )
  
return (
  <>
    <h1 data-testid="counter">{ counter }</h1>
    <button data-testid="button-up" onClick={delayCount}> Up</button>
    <button data-testid="button-down" onClick={() => setCounter(counter - 1)}>Down</button>
 </>
    )
  }
  
  export default TestAsync

Aici, folosim setTimeout() pentru a întârzia evenimentul incremental cu 0,5 secunde.

Testați dacă contorul este incrementat după 0,5 secunde:

TestAsync.test.js

import React from 'react';
import { render, cleanup, fireEvent, waitForElement } from '@testing-library/react';
import TestAsync from './TestAsync'

afterEach(cleanup);
  
  it('increments counter after 0.5s', async () => {
    const { getByTestId, getByText } = render(<TestAsync />); 

    fireEvent.click(getByTestId('button-up'))

    const counter = await waitForElement(() => getByText('1')) 

    expect(counter).toHaveTextContent('1')
  });

Pentru a testa evenimentul de creștere, trebuie mai întâi să folosim async / await pentru a gestiona acțiunea, deoarece, așa cum am spus mai devreme, este nevoie de timp pentru a finaliza.

Apoi, folosim o nouă metodă de ajutor getByText(). Acest lucru este similar cu getByTestId(), cu excepția că getByText() selectează conținutul textului în loc de id sau data-testid.

Acum, după ce faceți clic pe buton, așteptăm ca contorul să fie incrementat cu waitForElement(() => getByText('1')). Și odată ce contorul a crescut la 1, putem trece acum la condiție și putem verifica dacă contorul este efectiv egal cu 1.

Acestea fiind spuse, să trecem acum la cazuri de testare mai complexe.

Sunteți gata?

gata

5. Testarea React Redux

Dacă sunteți nou în React Redux, Acest articol s-ar putea să vă ajute. În caz contrar, să verificăm ce TestRedux.js se pare ca.

  • TestRedux.js
import React from 'react'
import { connect } from 'react-redux'

const TestRedux = ({counter, dispatch}) => {

 const increment = () => dispatch({ type: 'INCREMENT' })
 const decrement = () => dispatch({ type: 'DECREMENT' })
  
 return (
  <>
    <h1 data-testid="counter">{ counter }</h1>
    <button data-testid="button-up" onClick={increment}>Up</button>
    <button data-testid="button-down" onClick={decrement}>Down</button>
 </>
    )
  }
  
export default connect(state => ({ counter: state.count }))(TestRedux)

Și pentru reductor:

  • store/reducer.js
export const initialState = {
    count: 0,
  }
  
  export function reducer(state = initialState, action) {
    switch (action.type) {
      case 'INCREMENT':
        return {
          count: state.count + 1,
        }
      case 'DECREMENT':
        return {
          count: state.count - 1,
        }
      default:
        return state
    }
  }

După cum puteți vedea, nu este nimic fantezist – este doar o componentă de bază a contorului gestionată de React Redux.

Acum, să scriem testele unitare.

Testați dacă starea inițială este egală cu 0:

TestRedux.test.js

import React from 'react'
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import { render, cleanup, fireEvent } from '@testing-library/react';
import { initialState, reducer } from '../store/reducer'
import TestRedux from './TestRedux'

const renderWithRedux = (
  component,
  { initialState, store = createStore(reducer, initialState) } = {}
) => {
  return {
    ...render(<Provider store={store}>{component}</Provider>),
    store,
  }
}

 afterEach(cleanup);

it('checks initial state is equal to 0', () => {
    const { getByTestId } = renderWithRedux(<TestRedux />)
    expect(getByTestId('counter')).toHaveTextContent('0')
  })

Există câteva lucruri pe care trebuie să le importăm pentru a testa React Redux. Și aici, creăm propria noastră funcție de ajutor renderWithRedux() pentru a reda componenta, deoarece va fi folosită de mai multe ori.

renderWithRedux() primește ca parametri componenta de redat, starea inițială și magazinul. Dacă nu există un magazin, acesta va crea unul nou și, dacă nu primește o stare inițială sau un magazin, returnează un obiect gol.

Apoi, folosim render() pentru a reda componenta și a transmite magazinul către Furnizor.

Acestea fiind spuse, acum putem trece componenta TestRedux la renderWithRedux() pentru a testa dacă contorul este egal cu 0.

Testați dacă contorul crește și descrește corect:

TestRedux.test.js (adăugați următorul bloc de cod în fișier)

it('increments the counter through redux', () => {
  const { getByTestId } = renderWithRedux(<TestRedux />, 
    {initialState: {count: 5}
})
  fireEvent.click(getByTestId('button-up'))
  expect(getByTestId('counter')).toHaveTextContent('6')
})

it('decrements the counter through redux', () => {
  const { getByTestId} = renderWithRedux(<TestRedux />, {
    initialState: { count: 100 },
  })
  fireEvent.click(getByTestId('button-down'))
  expect(getByTestId('counter')).toHaveTextContent('99')
})

Pentru a testa evenimentele de incrementare și descreștere, trecem o stare inițială ca un al doilea argument către renderWithRedux(). Acum, putem face clic pe butoane și putem testa dacă rezultatul așteptat se potrivește sau nu cu starea.

Acum, să trecem la secțiunea următoare și să introducem React Context.

React Router și Axios vor veni în continuare – ești încă cu mine?

desigur

6. Testarea contextului React

Dacă nu sunteți nou în React Context, verificați Acest articol primul. În caz contrar, să verificăm TextContext.js fişier.

  • TextContext.js
import React from "react"

export const CounterContext = React.createContext()

const CounterProvider = () => {
  const [counter, setCounter] = React.useState(0)
  const increment = () => setCounter(counter + 1)
  const decrement = () => setCounter(counter - 1)

  return (
    <CounterContext.Provider value={{ counter, increment, decrement }}>
      <Counter />
    </CounterContext.Provider>
  )
}

export const Counter = () => {  
    const { counter, increment, decrement } = React.useContext(CounterContext)   
    return (
     <>
       <h1 data-testid="counter">{ counter }</h1>
       <button data-testid="button-up" onClick={increment}> Up</button>
       <button data-testid="button-down" onClick={decrement}>Down</button>
    </>
       )
}

export default CounterProvider

Acum, statul contrar este gestionat prin React Context. Să scriem testul unitar pentru a verifica dacă se comportă așa cum era de așteptat.

Testați dacă starea inițială este egală cu 0:

TextContext.test.js

import React from 'react'
import { render, cleanup,  fireEvent } from '@testing-library/react'
import CounterProvider, { CounterContext, Counter } from './TestContext'

const renderWithContext = (
  component) => {
  return {
    ...render(
        <CounterProvider value={CounterContext}>
            {component}
        </CounterProvider>)
  }
}

afterEach(cleanup);

it('checks if initial state is equal to 0', () => {
    const { getByTestId } = renderWithContext(<Counter />)
    expect(getByTestId('counter')).toHaveTextContent('0')
})

Ca și în secțiunea anterioară cu React Redux, aici folosim aceeași abordare, prin crearea unei funcții de ajutor renderWithContext() pentru a reda componenta. Dar de data aceasta, primește doar componenta ca parametru. Și pentru a crea un nou context, trecem CounterContext către Furnizor.

Acum, putem testa dacă contorul este inițial egal cu 0 sau nu.

Testați dacă contorul crește și descrește corect:

TextContext.test.js (adăugați următorul bloc de cod în fișier)

  it('increments the counter', () => {
    const { getByTestId } = renderWithContext(<Counter />)

    fireEvent.click(getByTestId('button-up'))
    expect(getByTestId('counter')).toHaveTextContent('1')
  })

  it('decrements the counter', () => {
    const { getByTestId} = renderWithContext(<Counter />)

    fireEvent.click(getByTestId('button-down'))
    expect(getByTestId('counter')).toHaveTextContent('-1')
  })

După cum puteți vedea, aici lansăm un eveniment de clic pentru a testa dacă contorul crește corect la 1 și scade la -1.

Acestea fiind spuse, acum putem trece la următoarea secțiune și să introducem React Router.

7. Testarea routerului React

Dacă doriți să vă scufundați în React Router, Acest articol s-ar putea să te ajute. În caz contrar, să verificăm TestRouter.js fişier.

  • TestRouter.js
import React from 'react'
import { Link, Route, Switch,  useParams } from 'react-router-dom'

const About = () => <h1>About page</h1>

const Home = () => <h1>Home page</h1>

const Contact = () => {
  const { name } = useParams()
  return <h1 data-testid="contact-name">{name}</h1>
}

const TestRouter = () => {
    const name="John Doe"
    return (
    <>
    <nav data-testid="navbar">
      <Link data-testid="home-link" to="/">Home</Link>
      <Link data-testid="about-link" to="/about">About</Link>
      <Link data-testid="contact-link" to={`/contact/${name}`}>Contact</Link>
    </nav>
    
      <Switch>
        <Route exact path="/" component={Home} />
        <Route path="/about" component={About} />
        <Route path="/about:name" component={Contact} />
      </Switch>
    </>
  )
}

export default TestRouter

Aici avem câteva componente de redat atunci când navigați pe pagina principală.

Acum, să scriem testele:

  • TestRouter.test.js
import React from 'react'
import { Router } from 'react-router-dom'
import { render, fireEvent } from '@testing-library/react'
import { createMemoryHistory } from 'history'
import TestRouter from './TestRouter'


const renderWithRouter = (component) => {
    const history = createMemoryHistory()
    return { 
    ...render (
    <Router history={history}>
        {component}
    </Router>
    )
  }
}

it('should render the home page', () => {

  const { container, getByTestId } = renderWithRouter(<TestRouter />) 
  const navbar = getByTestId('navbar')
  const link = getByTestId('home-link')

  expect(container.innerHTML).toMatch('Home page')
  expect(navbar).toContainElement(link)
})

Pentru a testa React Router, trebuie să avem mai întâi un istoric de navigare pentru a începe. De aceea folosim createMemoryHistory() până și numele ghicit pentru a crea un istoric de navigare.

Apoi, folosim funcția noastră de ajutor renderWithRouter() pentru a reda componenta și a trece history la Router componentă. Cu aceasta, putem testa acum dacă pagina încărcată la început este sau nu pagina principală. Și dacă bara de navigare este încărcată cu linkurile așteptate.

Testați dacă navighează către alte pagini cu parametrii atunci când facem clic pe linkuri:

TestRouter.test.js (adăugați următorul bloc de cod în fișier)

it('should navigate to the about page', ()=> {
  const { container, getByTestId } = renderWithRouter(<TestRouter />) 

  fireEvent.click(getByTestId('about-link'))

  expect(container.innerHTML).toMatch('About page')
})

it('should navigate to the contact page with the params', ()=> {
  const { container, getByTestId } = renderWithRouter(<TestRouter />) 
   
  fireEvent.click(getByTestId('contact-link'))
   
  expect(container.innerHTML).toMatch('John Doe')
})

Acum, pentru a verifica dacă navigarea funcționează, trebuie să declanșăm un eveniment de clic pe linkurile de navigare.

Pentru primul test, verificăm dacă conținutul este egal cu textul din pagina Despre, iar pentru al doilea, testăm parametrii de rutare și verificăm dacă a trecut corect.

Acum putem trece la secțiunea finală și putem învăța cum să testăm o solicitare Axios.

Aproape am terminat!

inca aici

8. Testarea cererii HTTP

Ca de obicei, să vedem mai întâi ce este TextAxios.js fișierul arată.

  • TextAxios.js
import React from 'react'
import axios from 'axios'

const TestAxios = ({ url }) => {
  const [data, setData] = React.useState()

  const fetchData = async () => {
    const response = await axios.get(url)
    setData(response.data.greeting)    
 }     
 
 return (
  <>
    <button onClick={fetchData} data-testid="fetch-data">Load Data</button>
    { 
    data ?
    <div data-testid="show-data">{data}</div>:
    <h1 data-testid="loading">Loading...</h1>
    }
  </>
     )
}

export default TestAxios

După cum puteți vedea aici, avem o componentă simplă care are un buton pentru a face o solicitare. Și dacă datele nu sunt disponibile, va afișa un mesaj de încărcare.

Acum, să scriem testele.

Testați dacă datele sunt preluate și afișate corect:

TextAxios.test.js

import React from 'react'
import { render, waitForElement, fireEvent } from '@testing-library/react'
import axiosMock from 'axios'
import TestAxios from './TestAxios'

jest.mock('axios')

it('should display a loading text', () => {

 const { getByTestId } = render(<TestAxios />)

  expect(getByTestId('loading')).toHaveTextContent('Loading...')
})

it('should load and display the data', async () => {
  const url="/greeting"
  const { getByTestId } = render(<TestAxios url={url} />)

  axiosMock.get.mockResolvedValueOnce({
    data: { greeting: 'hello there' },
  })

  fireEvent.click(getByTestId('fetch-data'))

  const greetingData = await waitForElement(() => getByTestId('show-data'))

  expect(axiosMock.get).toHaveBeenCalledTimes(1)
  expect(axiosMock.get).toHaveBeenCalledWith(url)
  expect(greetingData).toHaveTextContent('hello there')
})

Acest caz de testare este puțin diferit, deoarece trebuie să ne ocupăm de o solicitare HTTP. Și pentru a face acest lucru, trebuie să ne batem joc de o cerere axios cu ajutorul jest.mock('axios').

Acum, putem folosi axiosMock și aplicați un get() metoda la aceasta. În cele din urmă vom folosi funcția Jest mockResolvedValueOnce() pentru a transmite datele batjocorite ca parametru.

Cu aceasta, acum pentru al doilea test, putem face clic pe butonul pentru a prelua datele și a folosi async / await pentru a le rezolva. Și acum trebuie să testăm 3 lucruri:

  1. Dacă solicitarea HTTP a fost efectuată corect
  2. Dacă solicitarea HTTP a fost efectuată cu url
  3. Dacă datele preluate se potrivesc cu așteptările.

Și pentru primul test, verificăm doar dacă mesajul de încărcare este afișat atunci când nu avem date de afișat.

Acestea fiind spuse, acum am terminat cu cei 8 pași simpli pentru a începe să vă testați aplicațiile React.

Nu vă speriați să testați.

nu sunt speriat

Gânduri finale

Biblioteca React Testing este un pachet excelent pentru testarea aplicațiilor React. Ne oferă acces la jest-dom potrivitoare pe care le putem folosi pentru a ne testa componentele mai eficient și cu bune practici. Sperăm că acest articol a fost util și vă va ajuta să creați aplicații robuste React în viitor.

Puteți găsi proiectul finalizat aici

Mulțumesc că l-ai citit!

Citiți mai multe articoleAbonați-vă la newsletter-ul meuUrmăriți-mă pe twitter

Puteți citi și alte articole de genul acesta blogul meu.

Pasii urmatori

Documente React Testing Library

Foaie de trucuri React Testing Library

Foaie de trăsături Jest DOM matchers

Jest Docs