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

Tests

Un assertEquals qui masque une différence de type entre deux valeurs

Un test reste vert alors qu'un bug de type s'est glissé entre deux valeurs comparées. La comparaison souple d'assertEquals en est souvent la cause silencieuse.

Par Clément Hadrot • 27 février 2026 • 4 min de lecture • Aucun commentaire
Un assertEquals qui masque une différence de type entre deux valeurs

assertEquals('12', 12) retourne vrai dans PHPUnit, sans le moindre avertissement. Cette comparaison souple, qui applique les règles de conversion de type de PHP avant de comparer deux valeurs, explique un cas de test resté vert malgré un bug réel, rencontré sur une extension qui calcule le nombre de places disponibles pour un atelier de médiation numérique en bibliothèque.

La fonction censée retourner un entier représentant le nombre de places restantes retournait, à la suite d’une refactorisation, une chaîne de caractères issue d’un appel à get_post_meta() jamais converti en entier. Le test existant, écrit avec assertEquals, n’a rien détecté : la valeur numérique était correcte, seul son type avait changé.

Symptôme : un test vert, un bug bien réel

Le bug s’est révélé non pas par un échec de test, mais par un comportement inattendu côté interface : un composant JavaScript qui comparait strictement cette valeur à 0 avec l’opérateur === ne détectait plus jamais l’épuisement des places, puisque la chaîne "0" n’est jamais strictement égale à l’entier 0 en JavaScript non plus. Le test PHP, lui, restait silencieusement vert.

Diagnostic : la comparaison souple en cause

L'essentiel à retenir : assertEquals compare les valeurs après conversion de type implicite, pas leur type réel ; Un entier et une chaîne numériquement identiques passent la comparaison sans avertissement ; assertSame vérifie le type en plus de la valeur, et révèle ce genre d'écart immédiatement

Le test original comparait la valeur retournée à un entier attendu, en utilisant assertEquals, qui applique en interne les mêmes règles de comparaison souple que l’opérateur == de PHP :

// Le test original, resté vert malgré le bug
public function ilRetourneLeNombreDePlacesRestantes(): void
{
    update_post_meta($this->atelier_id, 'places_restantes', '0');

    $resultat = wpm_places_restantes($this->atelier_id);

    $this->assertEquals(0, $resultat); // vrai, que $resultat soit 0 ou "0"
}

Le résultat réel de la fonction, une fois le bug introduit, était la chaîne "0". assertEquals(0, "0") retourne vrai, car PHP convertit implicitement la chaîne en entier avant de comparer, exactement comme le ferait l’opérateur ==.

Correctif : remplacer assertEquals par assertSame

assertSame compare à la fois la valeur et le type, sans aucune conversion implicite, de la même façon que l’opérateur === de PHP :

public function ilRetourneLeNombreDePlacesRestantesCommeEntier(): void
{
    update_post_meta($this->atelier_id, 'places_restantes', '0');

    $resultat = wpm_places_restantes($this->atelier_id);

    $this->assertSame(0, $resultat); // échoue si $resultat est la chaîne "0"
}

Avec ce changement, le test échoue immédiatement dès que la fonction retourne une chaîne au lieu d’un entier, révélant le bug avant même qu’il n’atteigne un environnement de production.

Corriger également la fonction, pas seulement le test

La correction complète a nécessité un cast explicite dans la fonction elle-même, puisque get_post_meta() retourne systématiquement une chaîne de caractères par défaut dans WordPress, indépendamment du type de la valeur stockée à l’origine :

function wpm_places_restantes(int $atelier_id): int
{
    return (int) get_post_meta($atelier_id, 'places_restantes', true);
}

Prévention : quand préférer assertSame par défaut

  • Pour toute valeur dont le type est significatif pour l’appelant, notamment un entier, un booléen ou un objet précis, assertSame devrait constituer le choix par défaut.
  • assertEquals garde son utilité pour comparer des objets porteurs de logique d’égalité personnalisée, ou des valeurs dont seule l’équivalence numérique importe réellement.
  • Une revue de code peut signaler systématiquement tout assertEquals comparant un entier littéral à une valeur retournée par une fonction, comme point de vigilance à vérifier au cas par cas.

Une comparaison souple pardonne un bug de type ; une comparaison stricte le signale immédiatement, au moment où il coûte le moins cher à corriger.

En résumé

assertEquals a laissé passer un bug de type qui a changé le comportement réel d’une fonction sans jamais faire échouer le test censé la couvrir. Remplacer cette assertion par assertSame, plus stricte, a suffi à révéler l’écart entre une chaîne et un entier numériquement identiques, un cas fréquent dès qu’une valeur transite par les métadonnées WordPress sans conversion de type explicite.

Partager :

À propos de l'auteur

Clément Hadrot

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

Voir tous ses articles

Dans la même veine

À lire aussi