# Tester ses blocs Gutenberg : Jest, e2e-test-utils et intégration continue

> Un bloc sans tests casse tôt ou tard silencieusement. Panorama des outils officiels pour tester unitairement et bout en bout vos blocs Gutenberg.

- Auteur : Clément Hadrot
- Publié le : 2023-12-05
- Mis à jour le : 2023-12-05
- Catégorie : Blocs Gutenberg
- URL : https://wpmoderne.dev.wordpress-developpement.fr/blocs/tester-blocs-gutenberg-jest-e2e-test-utils/

## L’essentiel

- @wordpress/jest-preset-default couvre les tests unitaires JavaScript
- e2e-test-utils-playwright simule un vrai parcours dans l'éditeur
- Tester la validation du markup évite bien des régressions

Un bloc Gutenberg mélange plusieurs couches techniques : logique JavaScript côté éditeur, rendu PHP côté serveur pour les blocs dynamiques, et markup HTML validé à chaque ouverture de l'éditeur. Chacune de ces couches peut casser indépendamment des autres, souvent de façon silencieuse, révélée seulement quand un utilisateur tombe sur un bloc invalide plusieurs mois après la mise en production d'un changement anodin.

WordPress fournit un ensemble d'outils de test officiels, pensés spécifiquement pour les blocs. Cet article présente les deux niveaux de tests les plus utiles au quotidien : les tests unitaires avec Jest, et les tests de bout en bout qui simulent un vrai parcours utilisateur dans l'éditeur.

## Les tests unitaires avec @wordpress/jest-preset-default

Le paquet `@wordpress/jest-preset-default` configure Jest avec les transformations nécessaires pour tester du code React et JSX écrit avec `@wordpress/element`, sans configuration manuelle. Il s'installe et se déclare simplement dans le `package.json` :

```
{
  "scripts": {
    "test-unit": "wp-scripts test-unit-js"
  },
  "devDependencies": {
    "@wordpress/scripts": "^26.0.0"
  }
}
```

La commande `wp-scripts test-unit-js`, fournie par `@wordpress/scripts`, embarque déjà ce preset. Un test unitaire typique vérifie qu'une fonction de transformation d'attributs, ou une fonction `save()`, produit bien le résultat attendu :

```
import { render, screen } from '@testing-library/react';
import Edit from '../src/edit';

test( 'affiche le message par défaut si aucun texte n\'est saisi', () => {
    render(
        <Edit attributes={ { message: '' } } setAttributes={ () => {} } />
    );

    expect( screen.getByText( /Saisissez votre message/i ) ).toBeInTheDocument();
} );
```

Ces tests unitaires sont rapides à exécuter (quelques secondes pour l'ensemble d'une suite), ce qui les rend adaptés à une exécution systématique avant chaque commit, ou dans une étape d'intégration continue.

## Tester la fonction save() et la validation du markup

> L'essentiel à retenir : @wordpress/jest-preset-default couvre les tests unitaires JavaScript ; e2e-test-utils-playwright simule un vrai parcours dans l'éditeur ; Tester la validation du markup évite bien des régressions

Un test particulièrement utile, souvent négligé, consiste à vérifier que le HTML produit par `save()` reste stable pour un jeu d'attributs donné. C'est exactement le type de régression qui déclenche une erreur de validation de bloc en production : un changement anodin dans `save()` qui modifie le markup sans déprécation associée.

```
import { serialize, createBlock } from '@wordpress/blocks';

test( 'le markup du bloc reste stable', () => {
    const block = createBlock( 'wpmoderne/bandeau-alerte', {
        message: 'Attention aux mises à jour',
        niveau: 'alerte',
    } );

    expect( serialize( block ) ).toMatchSnapshot();
} );
```

Ce test par « snapshot » échoue automatiquement dès que le markup change, forçant le développeur à se poser la question : ce changement nécessite-t-il une entrée dans le tableau `deprecated` du bloc ? C'est un excellent filet de sécurité, particulièrement sur un projet avec plusieurs contributeurs.

## Les tests de bout en bout avec e2e-test-utils-playwright

Les tests unitaires ne couvrent pas tout : ils ne vérifient pas qu'un bloc s'insère correctement depuis l'inserteur, que les contrôles de l'inspecteur répondent bien au clic, ou que le contenu se sauvegarde sans erreur. Pour cela, WordPress fournit `@wordpress/e2e-test-utils-playwright`, une surcouche de Playwright avec des utilitaires prêts à l'emploi pour piloter l'éditeur.

```
import { test, expect } from '@wordpress/e2e-test-utils-playwright';

test( 'insère le bloc bandeau d\'alerte et modifie son niveau', async ( { editor, page } ) => {
    await editor.insertBlock( { name: 'wpmoderne/bandeau-alerte' } );

    await page.getByLabel( 'Niveau' ).selectOption( 'erreur' );

    const content = await editor.getEditedPostContent();
    expect( content ).toContain( 'wp:wpmoderne/bandeau-alerte' );
    expect( content ).toContain( '"niveau":"erreur"' );
} );
```

Ce type de test démarre un vrai navigateur, ouvre une véritable instance de WordPress (généralement via un environnement `@wordpress/env` local), et interagit avec l'interface exactement comme le ferait un utilisateur. Plus lent qu'un test unitaire, mais bien plus proche de la réalité d'usage.

## Organiser sa stratégie de tests

Sur un projet de taille moyenne avec une dizaine de blocs personnalisés, une répartition efficace consiste à réserver les tests unitaires aux fonctions pures (transformation d'attributs, validation, calculs) et aux snapshots de `save()`, puis à limiter les tests de bout en bout aux parcours les plus critiques : insertion du bloc, remplissage des champs principaux, et vérification que le contenu sauvegardé est valide.

1. Un snapshot de `save()` par bloc, pour détecter tout changement de markup non intentionnel.
2. Des tests unitaires ciblés sur la logique métier de `edit()` (affichage conditionnel, calculs d'attributs dérivés).
3. Un test de bout en bout par bloc pour le parcours d'insertion de base, et davantage pour les blocs avec une logique d'édition complexe.

> Un snapshot qui casse n'est jamais une mauvaise nouvelle en soi : c'est une question posée par le test. La vraie erreur, c'est de répondre « oui, tout va bien » sans avoir vérifié qu'une déprécation n'était pas nécessaire.

## Intégrer les tests à la chaîne de publication

Sur nos projets, les tests unitaires s'exécutent à chaque push via une action d'intégration continue, en quelques secondes. Les tests de bout en bout, plus longs, tournent plutôt sur les pull requests visant la branche principale, avec un environnement `@wordpress/env` démarré dans un conteneur dédié. Cette séparation évite de ralentir le cycle de développement quotidien tout en gardant un filet de sécurité solide avant chaque mise en production.

## En résumé

Tester ses blocs Gutenberg ne demande pas d'outillage exotique : WordPress fournit tout le nécessaire avec `@wordpress/jest-preset-default` pour l'unitaire et `@wordpress/e2e-test-utils-playwright` pour le bout en bout. Le réflexe le plus rentable reste le snapshot de `save()` : peu coûteux à écrire, il attrape justement les régressions les plus sournoises, celles qui ne se révèlent qu'en production, longtemps après le déploiement.
