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

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
assertSameaux 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.