# Tests contractuels entre un WordPress headless et son front

> Décrire une chaîne où un changement de schéma côté WordPress déclenche automatiquement une vérification côté front avant tout déploiement, plutôt qu'après l'incident.

- Auteur : Clément Hadrot
- Publié le : 2026-02-22
- Mis à jour le : 2026-02-22
- Catégorie : Tests
- URL : https://wpmoderne.dev.wordpress-developpement.fr/tests/tests-contractuels-wordpress-headless-front/

## L’essentiel

- Un contrat versionné remplace la confiance implicite entre les deux équipes
- Le front vérifie le contrat, le back publie le contrat
- Le pipeline bloque la fusion avant que l'incompatibilité n'atteigne la production

Sur une architecture headless où un WordPress sert de back-office de contenu via l'API REST à un front Next.js déployé indépendamment, l'incident le plus fréquent que nous rencontrons n'est ni un bug PHP ni un bug JavaScript : c'est un désaccord silencieux entre les deux, quand une équipe renomme un champ côté endpoint personnalisé sans que l'autre équipe, qui consomme ce champ dans un composant d'affichage, ne le sache avant la mise en production. Les deux dépôts passent leurs propres tests indépendamment, chacun de son côté, et pourtant l'ensemble casse en production.

## Arborescence du dispositif de test contractuel

```
architecture-tests-contractuels/
├── wordpress-back/
│   ├── src/RestEndpoints/ArticleEndpoint.php
│   └── contrats/
│       └── article.contract.json      (publié à chaque build)
├── front-nextjs/
│   ├── composants/CarteArticle.tsx
│   └── tests/
│       └── contrat-article.test.ts    (consomme le contrat publié)
└── pipeline-partage/
    └── publier-et-verifier-contrat.yml
```

## Étape 1 : le back génère et publie son contrat à chaque build

> L'essentiel à retenir : Un contrat versionné remplace la confiance implicite entre les deux équipes ; Le front vérifie le contrat, le back publie le contrat ; Le pipeline bloque la fusion avant que l'incompatibilité n'atteigne la production

Le contrat est un schéma JSON généré directement à partir de la déclaration `register_rest_field` et du `args` de l'endpoint, jamais écrit à la main séparément, pour éviter qu'il ne dérive silencieusement du code réel :

```
function generer_contrat_article() {
    return [
        '$schema'    => 'http://json-schema.org/draft-07/schema#',
        'type'       => 'object',
        'properties' => [
            'id'               => [ 'type' => 'integer' ],
            'titre'            => [ 'type' => 'string' ],
            'image_principale' => [ 'type' => 'string', 'format' => 'uri' ],
            'auteur'           => [
                'type'       => 'object',
                'properties' => [
                    'nom'   => [ 'type' => 'string' ],
                    'photo' => [ 'type' => 'string', 'format' => 'uri' ],
                ],
                'required'   => [ 'nom' ],
            ],
        ],
        'required'   => [ 'id', 'titre', 'image_principale', 'auteur' ],
    ];
}
```

Ce contrat est publié comme artefact du pipeline CI du dépôt back, sous une URL stable, à chaque fusion sur la branche principale.

## Étape 2 : le front vérifie ses hypothèses contre le contrat publié

```
import Ajv from 'ajv';
import contratArticle from './contrat-article.json'; // récupéré depuis le dépôt back publié

test('le composant CarteArticle respecte le contrat publié par le back', async () => {
  const reponseExemple = await fetch(process.env.WP_API_URL + '/wp-json/mon-site/v1/articles/1')
    .then(r => r.json());

  const ajv = new Ajv();
  const validationConforme = ajv.validate(contratArticle, reponseExemple);

  expect(validationConforme).toBe(true);
  expect(reponseExemple.auteur.nom).toBeDefined(); // hypothèse dont dépend CarteArticle.tsx
});
```

## Étape 3 : orchestrer la vérification croisée dans le pipeline

```
jobs:
  publier-contrat-back:
    steps:
      - run: php bin/generer-contrat.php > article.contract.json
      - uses: actions/upload-artifact@v4
        with: { name: contrat-article, path: article.contract.json }

  verifier-front-contre-contrat:
    needs: publier-contrat-back
    steps:
      - uses: actions/download-artifact@v4
        with: { name: contrat-article }
      - run: npm test -- contrat-article.test.ts
```

Le job front ne démarre qu'après la publication du contrat par le back, ce qui garantit qu'il vérifie toujours la version la plus récente, même dans deux dépôts Git totalement distincts sans historique partagé.

## Ce que ce dispositif ne couvre pas

Ce billet ne traite pas de WPGraphQL en tant que tel, qui propose sa propre approche de contrat via l'introspection de schéma GraphQL, une mécanique différente bien que poursuivant un objectif similaire. Il ne couvre pas non plus les changements de comportement qui ne touchent pas la structure des données, comme un changement de tri par défaut, qu'un schéma JSON ne peut pas exprimer et qui nécessite un test fonctionnel classique en complément.

## En résumé

Un contrat versionné et généré automatiquement à partir du code réel, plutôt qu'écrit à la main en parallèle, transforme une confiance implicite entre deux équipes en une vérification automatisée et bloquante. Le coût d'installation est réel — deux pipelines à faire communiquer plutôt qu'un seul — mais il évite l'incident le plus fréquent d'une architecture headless : un changement invisible d'un côté qui casse silencieusement l'autre.
