Kodokon kodokon.com

Qualité : Testing Library, StrictMode, Profiler

Testez le comportement plutôt que l'implémentation, exploitez les doubles invocations de StrictMode et mesurez les rendus avec Profiler.

10 min · 3 questions

Ouvrir cette leçon dans Kodokon

La philosophie de Testing Library tient en une phrase : tester ce que l'utilisateur perçoit, jamais les détails d'implémentation. Concrètement, on interroge le DOM via l'arbre d'accessibilité : getByRole d'abord (la requête reine, qui valide au passage vos rôles ARIA), puis getByLabelText, getByText, et getByTestId en tout dernier recours. Pour les interactions, préférez user-event à fireEvent : là où fireEvent.change émet un événement isolé, user.type reproduit la séquence complète (focus, keydown, keypress, input, keyup), exactement comme un vrai clavier. Les variantes findBy* combinent une requête et une attente asynchrone : indispensables après un chargement.

JSX
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

test('ajoute une tache a la liste', async () => {
  const user = userEvent.setup();
  render(<TodoApp />);

  await user.type(
    screen.getByRole('textbox'),
    'Relire le rapport'
  );
  await user.click(
    screen.getByRole('button', { name: /ajouter/i })
  );

  expect(
    await screen.findByText('Relire le rapport')
  ).toBeInTheDocument();
});
Un test centré sur le comportement, pas sur l'implémentation.

StrictMode est un outil de développement, sans aucun effet en production. En développement, il appelle deux fois vos fonctions de composant, initialiseurs d'état et fonctions passées à setState, pour débusquer les rendus impurs : si deux exécutions donnent des résultats différents, vous avez un effet de bord caché. Depuis React 18, il exécute aussi chaque effet selon le cycle montage, démontage, remontage : un effet dont le nettoyage n'est pas parfaitement symétrique (abonnement non résilié, requête non annulée) se trahit immédiatement. C'est une préparation directe aux fonctionnalités où React démonte puis remonte un écran en préservant son état.

JSX
useEffect(() => {
  const controller = new AbortController();
  fetch('/api/user', { signal: controller.signal })
    .then((res) => res.json())
    .then(setUser)
    .catch(() => {});
  return () => controller.abort();
}, []);
Un effet symétrique survit au double montage de StrictMode.

Pour mesurer, React fournit le composant <Profiler> et son pendant graphique dans les DevTools. Son callback onRender reçoit notamment phase (mount, update ou nested-update), actualDuration (temps réellement passé à rendre le sous-arbre pour ce commit) et baseDuration (estimation du temps de rendu du sous-arbre entier sans aucune mémoïsation). L'écart entre les deux mesure l'efficacité de vos memo et useMemo : un actualDuration très inférieur au baseDuration signifie que la mémoïsation travaille pour vous.

JSX
import { Profiler } from 'react';

function App() {
  return (
    <Profiler
      id="Sidebar"
      onRender={(id, phase, actualDuration) => {
        console.log(id, phase, actualDuration);
      }}
    >
      <Sidebar />
    </Profiler>
  );
}
Mesure du coût de rendu réel d'un sous-arbre.

Quiz de validation

Vérifiez que vous avez bien retenu les points clés de cette leçon.

  1. Pourquoi StrictMode monte, démonte puis remonte chaque effet en développement ?
    • Pour simuler la latence réseau du serveur
    • Pour vérifier que le nettoyage de chaque effet est symétrique
    • Pour vider le cache interne de React
    • Pour forcer le batching des mises à jour
  2. Quelle requête Testing Library faut-il privilégier en premier ?
    • getByTestId, la plus stable
    • getByClassName, la plus précise
    • getByRole, alignée sur l'arbre d'accessibilité
    • querySelector, la plus flexible
  3. Que représente baseDuration dans le callback du Profiler ?
    • Le temps du dernier commit uniquement
    • Le temps de rendu estimé du sous-arbre sans aucune mémoïsation
    • Le temps écoulé depuis le montage du composant
    • La durée moyenne des dix derniers rendus