Le WordPress d'aujourd'hui, décodé pour les développeurs

Tests

Figer par un test le format de données que deux extensions échangent via un hook

Quand une extension consomme les données qu'une autre publie via un hook d'action, un test dédié fige la forme exacte de ce contrat, avant qu'un changement silencieux ne le rompe.

Par WordPress Développement • 15 juin 2024 • 4 min de lecture • Aucun commentaire
Figer par un test le format de données que deux extensions échangent via un hook

Deux extensions maintenues par la même équipe communiquent par un hook d’action personnalisé : la première publie un événement via do_action(), la seconde s’y accroche via add_action() pour réagir. Ce mécanisme fonctionne parfaitement tant que la forme des données transmises reste stable ; il se rompt silencieusement dès qu’une des deux extensions évolue sans que l’autre en soit informée.

Ce sujet ne traite pas du test contractuel d’une réponse REST, qui répond à une problématique voisine mais distincte : ici, l’interface concernée est un hook d’action interne, pas un point de terminaison HTTP exposé.

Le contrat implicite d’un hook partagé

Une extension de gestion de réservations publie un événement à chaque confirmation, consommé par une seconde extension chargée d’envoyer une notification :

// Extension A : publication de l'événement
do_action('reservation_confirmee', [
    'id_reservation' => $reservation->id,
    'email_client'   => $reservation->email,
    'date_creneau'   => $reservation->creneau->format('Y-m-d H:i'),
]);

// Extension B : consommation de l'événement
add_action('reservation_confirmee', function (array $donnees): void {
    envoyer_notification($donnees['email_client'], $donnees['date_creneau']);
});

Rien, dans ce code, ne documente formellement que le tableau doit contenir exactement ces trois clés, avec ces types précis. Un renommage de email_client en email dans l’extension A, effectué sans concertation, casse silencieusement l’extension B : aucune erreur PHP ne survient, la clé attendue est simplement absente, et envoyer_notification() reçoit une valeur nulle sans avertissement.

Le schéma du contrat, en arborescence

reservation_confirmee (hook d'action)
├── id_reservation   : int
├── email_client     : string (adresse e-mail valide)
└── date_creneau     : string (format Y-m-d H:i)
L'essentiel à retenir : Un hook d'action partagé entre extensions constitue un contrat implicite, rarement documenté ; Un test qui fige la forme exacte des données passées transforme ce contrat en garantie vérifiée ; Ce test se distingue d'un test contractuel de réponse REST, qui porte sur un autre type d'interface

Le test qui fige ce contrat

Le test s’accroche lui-même au hook, capture les données réellement transmises lors d’une action déclenchée en conditions de test, puis vérifie leur forme exacte :

class ContratReservationConfirmeeTest extends WP_UnitTestCase
{
    public function test_le_hook_transmet_le_format_attendu(): void
    {
        $donneesCapturees = null;

        add_action('reservation_confirmee', function (array $donnees) use (&$donneesCapturees): void {
            $donneesCapturees = $donnees;
        });

        declencher_confirmation_de_test();

        $this->assertIsArray($donneesCapturees);
        $this->assertArrayHasKey('id_reservation', $donneesCapturees);
        $this->assertIsInt($donneesCapturees['id_reservation']);
        $this->assertArrayHasKey('email_client', $donneesCapturees);
        $this->assertMatchesRegularExpression(
            '/^[^@\s]+@[^@\s]+\.[^@\s]+$/',
            $donneesCapturees['email_client']
        );
        $this->assertArrayHasKey('date_creneau', $donneesCapturees);
        $this->assertMatchesRegularExpression(
            '/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/',
            $donneesCapturees['date_creneau']
        );
    }
}

Ce test appartient à l’extension qui publie l’événement, l’extension A : c’est elle qui prend l’engagement de respecter ce format, et c’est donc à elle de le vérifier à chaque modification de son propre code, avant même que l’extension B ne soit sollicitée pour vérifier quoi que ce soit.

Où placer ce test dans l’architecture du projet

  • Le test de contrat vit dans le dépôt de l’extension productrice de l’événement, pas dans celui de l’extension consommatrice.
  • Toute modification de la structure des données publiées doit obligatoirement s’accompagner d’une modification de ce test, ce qui rend le changement visible dans la revue de code plutôt que silencieux.
  • Un changement volontaire de format s’accompagne d’une communication explicite vers l’équipe qui maintient l’extension consommatrice, le test de contrat servant alors de preuve écrite du nouveau format à adopter de part et d’autre.

En résumé

Un hook d’action partagé entre deux extensions constitue un contrat de données aussi engageant qu’une interface REST documentée, même s’il ne prend jamais cette forme visible. Un test qui capture et vérifie la structure exacte des données transmises transforme ce contrat implicite en garantie automatisée, et rend visible, dans la revue de code, toute rupture qui serait autrement passée inaperçue jusqu’à ce qu’un client signale une notification jamais reçue.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Partager :

À propos de l'auteur

WordPress Développement

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi