# Tests snapshot du HTML rendu par vos blocs et shortcodes WordPress

> Utiliser des snapshots PHPUnit pour détecter les changements de rendu inattendus dans un shortcode ou un bloc, et savoir les maintenir sans qu'ils deviennent un fardeau.

- Auteur : Clément Hadrot
- Publié le : 2021-03-26
- Mis à jour le : 2021-03-26
- Catégorie : Tests
- URL : https://wpmoderne.dev.wordpress-developpement.fr/tests/tests-snapshot-html-blocs-shortcodes/

## L’essentiel

- Un snapshot capture le HTML rendu à un instant donné
- Toute différence doit être relue, jamais acceptée sans regarder
- Un HTML instable rend les snapshots inutilisables

Une refonte de shortcode censée n'ajouter qu'une classe CSS supplémentaire avait, par effet de bord, aussi supprimé un attribut `data-id` utilisé par un script tiers du client pour du tracking analytique. Rien n'avait cassé visuellement, aucun test fonctionnel n'avait échoué, et pourtant le tracking s'est tu pendant deux semaines avant d'être repéré. Un test snapshot, qui compare le HTML généré à une référence enregistrée, aurait fait échouer immédiatement le build sur ce changement non intentionnel.

Le principe du snapshot testing est simple : la première exécution enregistre le rendu HTML d'un shortcode ou d'un bloc comme référence ; chaque exécution suivante compare le nouveau rendu à cette référence et échoue si quoi que ce soit diffère, même un espace ou un attribut. Le développeur décide ensuite si la différence est voulue ou non.

## Écrire un premier test snapshot avec spatie/phpunit-snapshot-assertions

La bibliothèque `spatie/phpunit-snapshot-assertions`, installable via Composer, ajoute une assertion dédiée qui gère la création et la comparaison automatiquement :

```
use Spatie\Snapshots\MatchesSnapshots;

class Test_Shortcode_Avis extends WP_UnitTestCase {
    use MatchesSnapshots;

    public function test_le_rendu_du_shortcode_avis() {
        $produit_id = self::factory()->post->create( array( 'post_type' => 'produit' ) );

        $html = do_shortcode( '[avis produit_id="' . $produit_id . '"]' );

        $this->assertMatchesHtmlSnapshot( $html );
    }
}
```

Au premier lancement, aucun snapshot n'existe : la bibliothèque crée le fichier de référence dans `__snapshots__/` et le test passe automatiquement. Les lancements suivants comparent le rendu au fichier enregistré et échouent à la moindre différence.

## Gérer les identifiants et dates variables dans le rendu

Un piège classique : le HTML contient un identifiant de post généré dynamiquement (`post_id="482"`), ce qui fait échouer le snapshot à chaque exécution puisque l'identifiant change d'une base de test à l'autre. Il faut neutraliser ces valeurs avant la comparaison :

```
$html_normalise = preg_replace( '/post-\d+/', 'post-ID', $html );
$this->assertMatchesHtmlSnapshot( $html_normalise );
```

> L'essentiel à retenir : Un snapshot capture le HTML rendu à un instant donné ; Toute différence doit être relue, jamais acceptée sans regarder ; Un HTML instable rend les snapshots inutilisables

La même précaution s'applique aux dates affichées en relatif (« il y a 3 jours »), aux nonces générés par `wp_nonce_field()`, ou à tout identifiant de session : tout ce qui varie naturellement d'une exécution à l'autre doit être normalisé, sinon le snapshot devient inutilisable.

## Maintenir les snapshots sans les accepter à l'aveugle

Quand un changement de rendu est intentionnel, la commande `vendor/bin/phpunit -d --update-snapshots` régénère les fichiers de référence. Le vrai danger n'est pas technique mais humain : accepter les nouveaux snapshots sans relire le diff revient à désactiver le test. La discipline à adopter :

- Toujours consulter le diff généré par PHPUnit avant de mettre à jour un snapshot
- Relier chaque mise à jour de snapshot à une ligne du changelog ou du message de commit
- Ne jamais mettre à jour un snapshot « en masse » sans avoir relu chaque fichier concerné

> Un snapshot n'est utile que si son échec fait réfléchir. Le jour où l'équipe accepte les diffs sans les lire par habitude, autant supprimer le test : il ne protège plus rien.

## Quand éviter les snapshots

Les tests snapshot conviennent bien aux rendus stables et structurés, mais deviennent un fardeau sur un HTML qui change souvent pour des raisons légitimes, comme un compteur d'avis ou une classe active selon un état d'interface. Dans ce cas, une assertion ciblée sur un fragment précis du HTML, via une expression régulière ou un sélecteur, reste plus robuste et plus lisible qu'un snapshot complet qui échoue à chaque petit changement volontaire.

## Ne traite pas ici la régression visuelle

Un test snapshot HTML ne capture que la structure du balisage, jamais le rendu visuel final après application des feuilles de style. Détecter qu'un bouton a changé de couleur ou de position à l'écran relève d'une catégorie d'outils différente, orientée capture d'image plutôt que comparaison de texte.
