vendredi 25 septembre 2026

À propos

Contact

Tests

Yoast PHPUnit Polyfills : faire tourner vos tests de PHPUnit 5 à 9

Pourquoi la suite de tests de WordPress impose désormais les polyfills de Yoast, ce que ça change dans vos assertions, et comment migrer sans tout casser.

Par Clément Hadrot • 11 août 2023 • 5 min de lecture • Aucun commentaire
Yoast PHPUnit Polyfills : faire tourner vos tests de PHPUnit 5 à 9

« Ça marchait très bien avant, pourquoi ça casse maintenant ? » C’est la question qu’on entend systématiquement quand une équipe met à jour son environnement local et voit sa suite de tests PHPUnit refuser de démarrer, avec un message qui parle de méthodes introuvables comme assertContains appliquée à une chaîne, ou de setExpectedException disparue sans prévenir. La cause est presque toujours la même : plusieurs versions de PHPUnit cohabitent dans l’écosystème WordPress, et chacune a ses propres règles.

C’est exactement le problème que résolvent les Yoast PHPUnit Polyfills, une bibliothèque devenue quasi incontournable dès qu’un projet doit faire tourner la même suite de tests sur plusieurs versions majeures de PHPUnit, typiquement pour couvrir plusieurs versions de PHP en parallèle sur une matrice de CI.

Le problème que les polyfills résolvent

PHPUnit a beaucoup changé entre la version 5, encore courante il y a quelques années sur des environnements PHP anciens, et la version 9, alors la référence pour PHP 7.3 à 8.0. Des méthodes ont été renommées (assertNotRegExp vers assertDoesNotMatchRegularExpression, entre autres), d’autres supprimées, et certaines annotations de dépréciation ont changé de comportement. Un projet qui veut faire tourner exactement le même fichier de tests sur PHPUnit 7 et PHPUnit 9 se heurte vite à des incompatibilités d’API pures, indépendantes de la logique métier testée.

La suite de tests officielle de WordPress, celle qui fournit WP_UnitTestCase et le bootstrap partagé par tout l’écosystème des extensions et thèmes, a elle-même besoin de cette compatibilité : elle doit rester utilisable aussi bien par un vieux plugin encore sur PHP 7.2 avec PHPUnit 5, que par un projet moderne sur PHPUnit 9. C’est pour cette raison que le cœur a intégré la dépendance aux polyfills dans son propre bootstrap de tests.

Ce que la bibliothèque fournit concrètement

Les polyfills ajoutent, sous forme de traits PHP à utiliser dans vos classes de tests, les méthodes manquantes selon la version de PHPUnit réellement installée. Deux traits couvrent l’essentiel des besoins :

  • Yoast\PHPUnitPolyfills\TestCases\TestCase, une classe de base à étendre à la place de PHPUnit\Framework\TestCase directement
  • Yoast\PHPUnitPolyfills\Polyfills\AssertionRenames, un trait qui réintroduit les anciens noms de méthodes d’assertion sous une signature compatible avec toutes les versions cibles

Concrètement, une assertion écrite une seule fois fonctionne identiquement, que le CI exécute PHPUnit 7 sur PHP 7.4 ou PHPUnit 9 sur PHP 8.1 :

use Yoast\PHPUnitPolyfills\TestCases\TestCase;

class Test_Mon_Service extends TestCase {

    public function test_le_service_retourne_un_tableau() {
        $resultat = ( new Mon_Service() )->calculer();
        $this->assertIsArray( $resultat );
        $this->assertArrayHasKey( 'total', $resultat );
    }
}
L'essentiel à retenir : Un seul jeu de tests, plusieurs versions de PHPUnit supportées ; Les assertions dépréciées doivent être renommées, pas contournées ; La suite de tests du cœur impose désormais la dépendance

Migrer un projet existant

La migration se fait en trois passes distinctes, qu’il vaut mieux ne pas mélanger dans un même commit pour garder un historique lisible.

1. Installer la dépendance et adapter le bootstrap

composer require --dev yoast/phpunit-polyfills

Puis, dans le fichier phpunit.xml, s’assurer que l’autoload Composer est bien chargé avant le bootstrap de WordPress, condition nécessaire pour que les traits soient disponibles dans toutes les classes de tests.

2. Remplacer l’héritage des classes de tests

Toute classe qui étend directement PHPUnit_Framework_TestCase (l’ancienne notation sans espace de noms, encore présente dans du code très ancien) ou PHPUnit\Framework\TestCase doit être basculée vers la classe fournie par les polyfills, ou à défaut intégrer le trait correspondant si elle hérite déjà d’une autre classe de base spécifique au projet.

3. Passer un script de recherche-remplacement sur les assertions renommées

La documentation du paquet fournit un tableau exhaustif de correspondance entre anciens et nouveaux noms d’assertions. Un simple script shell balaie le dossier de tests et signale les occurrences des noms historiques les plus fréquents, à corriger un par un plutôt qu’en remplacement aveugle, certains renommages changeant légèrement l’ordre ou la nature des arguments attendus.

Le piège des annotations @expectedException

Le cas qui casse le plus souvent silencieusement une migration concerne les anciennes annotations de docblock comme @expectedException, supprimées depuis longtemps de PHPUnit. Un test qui utilisait cette annotation ne signale aucune erreur de syntaxe : il continue simplement de s’exécuter sans jamais vérifier l’exception attendue, ce qui rend le test silencieusement inutile plutôt que rouge. Il faut les remplacer explicitement par $this->expectException( Ma_Classe_Exception::class ) appelé avant le code qui doit lever l’exception.

Un test qui ne vérifie plus rien mais reste vert est plus dangereux qu’un test qui échoue franchement : personne ne va le regarder tant qu’il ne casse pas.

Vérifier la matrice après migration

Une fois la migration faite, on rejoue systématiquement la matrice complète de versions ciblées en CI, PHP et PHPUnit croisés, plutôt que de se fier à une exécution locale unique. Sur un projet qui visait PHP 7.4 à 8.2, la matrice comportait quatre combinaisons PHP/PHPUnit ; deux d’entre elles ont révélé des assertions oubliées lors du premier passage, corrigées seulement grâce à cette exécution croisée.

En résumé

Les Yoast PHPUnit Polyfills ne sont pas un simple confort : ils sont devenus une dépendance de fait pour tout projet WordPress qui doit maintenir une compatibilité PHP et PHPUnit large, condition quasi systématique pour une extension distribuée publiquement. La migration demande de la rigueur sur les annotations d’exception et les assertions renommées, mais elle évite ensuite de dupliquer une suite de tests par version de PHPUnit supportée, ce qui aurait vite tourné au cauchemar de maintenance sur un projet à plusieurs extensions.

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