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

Tests

« Failed asserting that two arrays are identical » : synchro HubSpot

Diagnostiquer un échec assertEquals entre deux tableaux visuellement identiques sur un test de synchronisation de contacts avec HubSpot.

Par WordPress Développement • 8 février 2024 • 4 min de lecture • Aucun commentaire
« Failed asserting that two arrays are identical » : synchro HubSpot

Failed asserting that two arrays are identical. Ce message, aussi laconique qu’agaçant, s’affichait sur un test qui vérifiait la synchronisation des contacts entre WordPress et HubSpot via l’API officielle. Le tableau attendu et le tableau obtenu semblaient, à l’affichage brut avec var_dump, parfaitement identiques.

Le test en question comparait la charge utile envoyée à l’endpoint /crm/v3/objects/contacts avec un tableau de référence figé dans une fixture PHP. Il tournait sans problème depuis des mois, jusqu’à ce qu’une mise à jour du connecteur HubSpot côté client change la façon dont les propriétés personnalisées étaient assemblées avant l’envoi.

Le piège de l’assertion sur des tableaux « identiques »

La méthode assertEquals de PHPUnit compare deux valeurs sans tenir compte de l’ordre des clés dans un tableau associatif, ce qui explique pourquoi le message d’échec parle d’identité alors que les deux tableaux affichés semblent pareils : PHPUnit détecte une différence que l’œil humain ne voit pas immédiatement en scrollant un var_dump verbeux de cinquante lignes.

$this->assertEquals( $tableau_attendu, $tableau_obtenu );

Le vrai coupable, une fois creusé avec un diff plus lisible, était une valeur de type string côté attendu contre une valeur de type int côté obtenu pour le champ hs_lead_status. PHPUnit signale bien ce genre d’écart, mais l’affichage par défaut ne le met pas suffisamment en évidence dans un tableau volumineux.

Obtenir une diff exploitable plutôt qu’un dump brut

L'essentiel à retenir : Distinguer assertEquals et assertSame sur les tableaux ; Repérer un ordre de clés différent avec une diff lisible ; Corriger le test sans masquer une vraie régression

La solution la plus efficace consiste à demander à PHPUnit d’afficher une diff structurée plutôt que de comparer manuellement deux blocs de texte. L’option --verbose combinée à un formateur de sortie amélioré aide, mais la méthode la plus fiable reste de comparer les tableaux champ par champ dans le test lui-même quand l’assertion globale échoue de façon récurrente.

foreach ( $tableau_attendu as $cle => $valeur ) {
    $this->assertSame(
        $valeur,
        $tableau_obtenu[ $cle ] ?? null,
        "Écart détecté sur la clé : {$cle}"
    );
}

Ce découpage transforme un message générique en message ciblé : Écart détecté sur la clé : hs_lead_status, ce qui a permis de localiser le problème en quelques secondes plutôt qu’en plusieurs minutes de comparaison visuelle fastidieuse.

assertEquals contre assertSame

Le choix entre assertEquals et assertSame mérite d’être fait consciemment. La première autorise une comparaison « souple » qui considère "1" et 1 comme égaux, ce qui masque justement ce genre de bug de typage. La seconde, plus stricte, aurait fait échouer le test bien plus tôt, dès le premier changement de type introduit par le connecteur HubSpot.

Corriger la cause plutôt que le symptôme

Une tentation fréquente face à ce genre d’échec consiste à modifier la fixture pour qu’elle corresponde au nouveau format produit par le code, sans se poser la question de savoir si ce changement de type est réellement voulu. Ici, le champ hs_lead_status attendait bien une chaîne de caractères côté API HubSpot, documentée comme telle dans la référence officielle des propriétés de contact.

  • Vérifier la documentation de l’API tierce avant de changer une fixture
  • Préférer assertSame aux comparaisons de type quand la stabilité du typage compte
  • Ajouter un test de régression qui fige explicitement le type attendu pour chaque champ sensible

Le correctif final a donc porté sur le code de synchronisation, en forçant un cast explicite en chaîne avant l’envoi, plutôt que sur le test qui, lui, avait raison depuis le début.

Prévenir la prochaine régression de ce type

Pour éviter de revivre cette perte de temps, la suite de tests inclut désormais une fonction utilitaire qui compare deux tableaux champ par champ et affiche systématiquement une diff lisible en cas d’échec, sans attendre qu’un développeur la réécrive à la main à chaque incident.

function assert_arrays_field_by_field( TestCase $test, array $expected, array $actual ) {
    foreach ( $expected as $key => $value ) {
        $test->assertSame( $value, $actual[ $key ] ?? null, "Écart sur : {$key}" );
    }
}

Un message d’échec « identiques » sur des tableaux qui se ressemblent cache presque toujours une différence de type, jamais une différence de contenu visible à l’œil.

En résumé

Ce genre d’échec de test, frustrant sur le moment, révèle souvent une vraie fragilité du code plutôt qu’un simple caprice de l’outil de test. La prochaine fois qu’un assertEquals échoue sur deux tableaux qui paraissent identiques, la première question à se poser porte sur le typage des valeurs, bien avant de suspecter PHPUnit ou de réécrire la fixture à la va-vite.

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