vendredi 25 septembre 2026

À propos

Contact

Tests

Tester les abilities de WordPress 6.9 avec PHPUnit, pas à pas

Écrire des tests PHPUnit fiables pour une ability enregistrée dans WordPress 6.9 : schémas d'entrée et de sortie, permissions, et exécution correcte.

Par Clément Hadrot • 22 décembre 2025 • 5 min de lecture • Aucun commentaire
Tester les abilities de WordPress 6.9 avec PHPUnit, pas à pas

Un jour après la sortie de WordPress 6.9, un client a demandé la conversion d’une action AJAX maison, celle qui recalculait le tarif d’un devis personnalisé, en une véritable ability enregistrée via l’Abilities API. L’objectif métier était de la rendre appelable proprement par un futur agent automatisé, sans passer par une route AJAX peu documentée. La conversion en elle-même était rapide ; écrire des tests solides pour cette nouvelle ability a demandé une réflexion un peu différente de ce qu’on fait habituellement pour un simple hook ou une route REST classique.

Une ability, dans l’esprit de l’Abilities API, se compose de trois éléments testables séparément : un schéma d’entrée qui valide les paramètres reçus, un callback d’exécution qui produit le résultat, et un callback de permission qui décide si l’appelant a le droit de l’exécuter. Une suite de tests complète couvre ces trois facettes indépendamment, plutôt que de se contenter d’un seul test d’exécution de bout en bout.

Rappel du contexte : l’ability testée

L’ability enregistrée ressemble à ceci, simplifiée pour l’exemple :

wp_register_ability( 'mon-extension/calculer-devis', [
    'label'               => __( 'Calculer un devis personnalisé', 'mon-extension' ),
    'input_schema'        => [
        'type'       => 'object',
        'required'   => [ 'produit_id', 'quantite' ],
        'properties' => [
            'produit_id' => [ 'type' => 'integer' ],
            'quantite'   => [ 'type' => 'integer', 'minimum' => 1 ],
        ],
    ],
    'output_schema'       => [
        'type'       => 'object',
        'properties' => [
            'total_ht' => [ 'type' => 'number' ],
        ],
    ],
    'execute_callback'    => 'mon_extension_executer_calcul_devis',
    'permission_callback' => 'mon_extension_verifier_permission_devis',
] );

Premier axe : le schéma d’entrée rejette les données invalides

Le test le plus souvent négligé consiste à vérifier que le schéma d’entrée rejette bien les paramètres invalides, pas seulement qu’il accepte les paramètres valides. On récupère l’ability enregistrée via wp_get_ability() et on tente une exécution avec des données volontairement incorrectes :

public function test_rejette_quantite_negative() {
    $ability = wp_get_ability( 'mon-extension/calculer-devis' );

    $resultat = $ability->execute( [
        'produit_id' => 42,
        'quantite'   => -3,
    ] );

    $this->assertWPError( $resultat );
    $this->assertSame( 'rest_invalid_param', $resultat->get_error_code() );
}
L'essentiel à retenir : Une ability se teste comme une petite API à trois facettes ; Le schéma d'entrée doit rejeter les données invalides, pas seulement accepter les valides ; Le callback de permission mérite un test dédié, séparé de l'exécution

Deuxième axe : le callback de permission, testé isolément

Tester la permission séparément de l’exécution évite un piège classique : un test qui vérifie l’exécution complète avec un utilisateur autorisé ne dit rien sur ce qui se passe avec un utilisateur non autorisé. On teste explicitement les deux cas, en changeant l’utilisateur courant avant chaque appel :

public function test_refuse_execution_sans_capacite() {
    wp_set_current_user( $this->factory()->user->create( [ 'role' => 'subscriber' ] ) );

    $ability  = wp_get_ability( 'mon-extension/calculer-devis' );
    $resultat = $ability->execute( [ 'produit_id' => 42, 'quantite' => 2 ] );

    $this->assertWPError( $resultat );
    $this->assertSame( 'rest_forbidden', $resultat->get_error_code() );
}

public function test_autorise_execution_avec_capacite_adequate() {
    wp_set_current_user( $this->factory()->user->create( [ 'role' => 'shop_manager' ] ) );

    $ability  = wp_get_ability( 'mon-extension/calculer-devis' );
    $resultat = $ability->execute( [ 'produit_id' => 42, 'quantite' => 2 ] );

    $this->assertIsArray( $resultat );
}

Troisième axe : le résultat respecte le schéma de sortie

Comme pour une route REST classique, il ne suffit pas de vérifier que l’exécution ne plante pas : il faut vérifier que la structure retournée respecte le schéma de sortie déclaré. On réutilise ici la même logique que pour un test de contrat d’API, en validant le résultat contre le output_schema déclaré par l’ability :

public function test_resultat_respecte_le_schema_de_sortie() {
    wp_set_current_user( $this->factory()->user->create( [ 'role' => 'shop_manager' ] ) );

    $ability  = wp_get_ability( 'mon-extension/calculer-devis' );
    $resultat = $ability->execute( [ 'produit_id' => 42, 'quantite' => 3 ] );

    foreach ( $ability->get_output_schema()['properties'] as $cle => $regle ) {
        $this->assertArrayHasKey( $cle, $resultat );
    }
    $this->assertIsFloat( $resultat['total_ht'] );
}

Cas particulier : les erreurs métier au sein d’une exécution autorisée

Un point facile à oublier : un appelant peut avoir toutes les permissions nécessaires et fournir des paramètres valides selon le schéma, tout en déclenchant malgré tout une erreur métier légitime, comme un produit désormais archivé. Ce cas mérite son propre test, distinct des deux précédents, pour vérifier que l’ability retourne une erreur explicite plutôt qu’un résultat silencieusement incorrect :

  • Créer un produit de test, puis le marquer comme archivé avant l’appel
  • Vérifier que l’exécution retourne une erreur spécifique, avec un code distinct de celui d’un refus de permission
  • Vérifier qu’aucune donnée partielle ou incohérente n’est retournée dans ce cas d’erreur

Une ability mal testée n’expose pas seulement un bug à un utilisateur humain distrait : elle l’expose potentiellement à un agent automatisé qui agira sur la base d’un résultat erroné sans jamais remettre en question sa plausibilité.

En résumé

Tester une ability WordPress 6.9 demande de séparer clairement trois responsabilités distinctes : la validation du schéma d’entrée, la vérification de la permission, et la conformité du résultat au schéma de sortie. Traiter ces trois axes comme un seul test d’exécution de bout en bout, comme on le ferait par réflexe sur une simple fonction, laisse passer des trous de couverture précis, en particulier sur les cas de refus de permission et de rejet de paramètres invalides, deux zones où une ability appelée par un agent automatisé a justement le plus besoin d’un comportement prévisible et bien vérifié.

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