Publie le 24 mars 2026 Par

Tester une application React en 2026 : Vitest, Testing Library, guide pratique

Les tests sont la compétence qui fait le plus souvent la différence entre un junior qu’on recrute et un junior qu’on laisse de côté. En 2026, l’écosystème de tests React s’est stabilisé autour de Vitest et Testing Library. Ce guide vous donne les bases pratiques pour tester vos composants de façon utile — pas pour cocher une case.

L’écosystème de tests React en 2026

  • Vitest : le runner de tests, remplace Jest pour les projets Vite. API identique à Jest, mais 10-20x plus rapide.
  • React Testing Library (RTL) : pour tester les composants React. Philosophie : tester le comportement visible par l’utilisateur, pas les détails d’implémentation.
  • Playwright ou Cypress : pour les tests end-to-end (E2E) qui testent le flux complet dans un vrai navigateur.

Setup Vitest + Testing Library

npm install -D vitest @testing-library/react @testing-library/user-event @testing-library/jest-dom jsdom

# vite.config.ts
export default defineConfig({
  test: {
    environment: 'jsdom',
    globals: true,
    setupFiles: './src/test/setup.ts',
  },
})

# src/test/setup.ts
import '@testing-library/jest-dom' // étend les matchers de Vitest

Le premier test — la philosophie RTL

Testing Library impose une philosophie : requêtez le DOM comme un utilisateur le verrait, pas comme un développeur qui connaît l’implémentation. Préférez getByRole et getByText à getByTestId.

// LoginForm.tsx — le composant à tester
function LoginForm({ onSubmit }: { onSubmit: (data: FormData) => void }) {
  return (
    
) } // LoginForm.test.tsx import { render, screen } from '@testing-library/react' import userEvent from '@testing-library/user-event' describe('LoginForm', () => { it('soumet le formulaire avec les bonnes données', async () => { const user = userEvent.setup() const handleSubmit = vi.fn() render() // Trouver par rôle et label — comme un utilisateur await user.type(screen.getByLabelText('Email'), 'test@example.com') await user.type(screen.getByLabelText('Mot de passe'), 'password123') await user.click(screen.getByRole('button', { name: 'Se connecter' })) expect(handleSubmit).toHaveBeenCalledWith({ email: 'test@example.com', password: 'password123', }) }) it('affiche une erreur si l'email est invalide', async () => { const user = userEvent.setup() render() await user.type(screen.getByLabelText('Email'), 'pas-un-email') await user.click(screen.getByRole('button', { name: 'Se connecter' })) expect(screen.getByText(/email invalide/i)).toBeInTheDocument() }) })

Tester les hooks avec renderHook

import { renderHook, act } from '@testing-library/react'

// Le hook à tester
function useCounter(initialValue = 0) {
  const [count, setCount] = useState(initialValue)
  const increment = () => setCount(c => c + 1)
  const reset = () => setCount(initialValue)
  return { count, increment, reset }
}

// Le test
it('incrémente et reset correctement', () => {
  const { result } = renderHook(() => useCounter(5))

  expect(result.current.count).toBe(5)

  act(() => result.current.increment())
  expect(result.current.count).toBe(6)

  act(() => result.current.reset())
  expect(result.current.count).toBe(5)
})

Mocker les appels réseau

// Avec MSW (Mock Service Worker) — la meilleure approche
// Les requêtes fetch réelles sont interceptées, pas mockées dans le code

// src/test/server.ts
import { setupServer } from 'msw/node'
import { http, HttpResponse } from 'msw'

export const server = setupServer(
  http.get('/api/users', () => {
    return HttpResponse.json([
      { id: '1', name: 'Alice' },
      { id: '2', name: 'Bob' },
    ])
  })
)

// setup.ts
beforeAll(() => server.listen())
afterEach(() => server.resetHandlers())
afterAll(() => server.close())

// Test avec données réseau
it('affiche la liste des utilisateurs', async () => {
  render()
  expect(screen.getByText('Chargement...')).toBeInTheDocument()
  expect(await screen.findByText('Alice')).toBeInTheDocument()
  expect(screen.getByText('Bob')).toBeInTheDocument()
})

Quelle couverture viser

Pas d’objectif arbitraire de couverture (80%, 100%). Testez ce qui compte :

  • Logique métier critique : calculs, validations, transformations de données
  • Interactions utilisateur : formulaires, boutons, flux de navigation
  • Cas d’erreur : que se passe-t-il quand l’API échoue ?
  • Ne testez pas : les détails d’implémentation, les composants purement visuels sans logique, les librairies tierces

Offres développeur React

Des postes pour développeurs React qui savent tester leur code — une compétence rare et appréciée des recruteurs.

À lire aussi : Hooks ReactPerformances ReactNext.js pour débutant

Categories : JavaScript & React