vendredi 25 septembre 2026

À propos

Contact

Tests

Tester vos hooks WordPress avec did_action, has_filter et des assertions ciblées

Vérifier qu'une action se déclenche, qu'un filtre est enregistré et qu'il modifie bien la valeur attendue, sans bibliothèque tierce.

Par Clément Hadrot • 13 novembre 2020 • 4 min de lecture • Aucun commentaire
Tester vos hooks WordPress avec did_action, has_filter et des assertions ciblées

Un correctif introduit par erreur un point-virgule en trop après un add_filter(), transformant l’appel en instruction morte et le filtre en simple commentaire silencieux. Le code compilait, aucune erreur PHP ne remontait, et le filtre censé arrondir les prix affichés ne s’exécutait tout simplement jamais. Un test qui vérifie qu’un hook est bien enregistré et bien déclenché aurait empêché ce genre de régression silencieuse de passer en revue de code.

WordPress expose trois fonctions simples pour ce genre de vérification : has_action() et has_filter() pour confirmer qu’un callback est accroché à un hook, et did_action() pour compter combien de fois une action donnée s’est réellement déclenchée pendant l’exécution. Combinées à des assertions classiques, elles couvrent l’essentiel des besoins sans dépendance externe.

Vérifier qu’un callback est bien enregistré

La première question à se poser n’est pas « le filtre fonctionne-t-il ? » mais « le filtre est-il seulement accroché ? ». C’est le rôle de has_filter() et has_action() :

class Test_Hooks_Catalogue extends WP_UnitTestCase {

    public function test_le_filtre_de_prix_est_enregistre() {
        $priorite = has_filter( 'mon_plugin_prix_affiche', 'mon_plugin_arrondir_prix' );

        $this->assertNotFalse( $priorite );
        $this->assertSame( 20, $priorite );
    }
}

has_filter() retourne la priorité du callback, ou false s’il n’est pas enregistré. Vérifier la priorité elle-même a du sens quand l’ordre d’exécution compte, par exemple si deux extensions modifient la même valeur et que l’ordre change le résultat final.

Compter les déclenchements réels avec did_action

Savoir qu’un callback est accroché ne dit rien sur son exécution effective. did_action() retourne le nombre de fois qu’une action a été déclenchée depuis le début de la requête, ce qui permet des assertions précises :

public function test_action_apres_creation_de_commande() {
    $this->assertSame( 0, did_action( 'mon_plugin_commande_creee' ) );

    mon_plugin_creer_commande( array( 'total' => 42.00 ) );

    $this->assertSame( 1, did_action( 'mon_plugin_commande_creee' ) );
}
L'essentiel à retenir : did_action compte les déclenchements réels ; has_filter confirme l'enregistrement ; apply_filters vérifie l'effet, pas juste la présence

Ce comptage est particulièrement utile pour détecter les déclenchements en double, un bug fréquent quand un hook est accroché à la fois sur save_post et sur un hook spécifique comme save_post_produit sans garde-fou.

Vérifier l’effet réel d’un filtre, pas seulement sa présence

La vérification la plus robuste reste d’appeler apply_filters() directement et de comparer l’entrée à la sortie, sans se soucier de savoir combien de callbacks sont accrochés :

public function test_le_prix_est_arrondi_au_centime_superieur() {
    $prix_arrondi = apply_filters( 'mon_plugin_prix_affiche', 19.994 );

    $this->assertSame( 20.00, $prix_arrondi );
}

Cette approche a un avantage : elle reste valide même si l’implémentation interne change de nom de fonction, tant que le contrat du filtre — sa signature d’entrée et de sortie — reste stable. C’est généralement le niveau de granularité le plus pertinent à tester en priorité.

Tester le retrait d’un hook

Un cas fréquent sur les projets avec plusieurs extensions maison : vérifier qu’une extension désactive correctement un comportement du cœur ou d’une autre extension via remove_action() :

  • Vérifier avant retrait que has_action() retourne bien une priorité
  • Appeler le code responsable du retrait
  • Vérifier après retrait que has_action() retourne false

Sans ce test, un changement de priorité par défaut dans une mise à jour du cœur ou d’une extension tierce peut faire échouer silencieusement le remove_action(), puisque WordPress exige que la priorité passée corresponde exactement à celle utilisée lors de l’enregistrement.

En résumé

Avant de sortir l’artillerie lourde pour simuler des fonctions du cœur, ces trois fonctions natives couvrent déjà la majorité des besoins de test sur les hooks : présence avec has_filter()/has_action(), fréquence de déclenchement avec did_action(), et effet réel avec apply_filters(). Les bibliothèques de mock comme Brain Monkey ont leur place, mais pour un autre usage : tester du code qui appelle des fonctions WordPress sans charger le cœur du tout.

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