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

Tests

Un jeu de fixtures partagé entre classes de test, plutôt qu’un setUp répété

Recréer les mêmes objets de test dans chaque classe alourdit une suite sans raison. Voici comment mutualiser un jeu de fixtures entre plusieurs classes PHPUnit.

Par WordPress Développement • 18 novembre 2023 • 4 min de lecture • Aucun commentaire
Un jeu de fixtures partagé entre classes de test, plutôt qu'un setUp répété

Six classes de test différentes, six méthodes setUp() qui recréent, presque à l’identique, la même arborescence de catégories et le même jeu d’articles de démonstration. C’est le point de départ de ce cas : une extension de gestion éditoriale dont la suite de tests avait grossi organiquement, chaque nouvelle classe copiant le bloc de préparation de la précédente plutôt que de le mutualiser.

Le symptôme le plus visible n’était pas la duplication de code en elle-même, mais la durée d’exécution de la suite complète : chaque classe recréait sa propre arborescence en base de données, alors que rien n’empêchait de la construire une seule fois pour un ensemble de classes qui en avaient l’usage identique.

Le réflexe initial : setUp répété

La méthode setUp() de PHPUnit s’exécute avant chaque méthode de test, ce qui garantit un état propre à chaque cas, mais ce n’est pas toujours nécessaire : quand plusieurs classes de test ont besoin exactement du même jeu de données en lecture seule, reconstruire ce jeu de données à chaque méthode gaspille du temps sans apporter de garantie supplémentaire.

class ArticlesParCategorieTest extends WP_UnitTestCase
{
    private int $categorieParenteId;

    public function setUp(): void
    {
        parent::setUp();
        $this->categorieParenteId = self::factory()->category->create(['name' => 'Actualités']);
        self::factory()->category->create(['name' => 'Locales', 'parent' => $this->categorieParenteId]);
        self::factory()->post->create_many(5, ['post_category' => [$this->categorieParenteId]]);
    }
}

Mutualiser avec setUpBeforeClass

Quand le jeu de données reste identique pour l’ensemble des méthodes d’une même classe, wpSetUpBeforeClass() — la variante statique fournie par WP_UnitTestCase, appelée une seule fois avant toutes les méthodes de la classe — évite de recréer les mêmes objets à chaque test :

class ArticlesParCategorieTest extends WP_UnitTestCase
{
    private static int $categorieParenteId;

    public static function wpSetUpBeforeClass(WP_UnitTest_Factory $factory): void
    {
        self::$categorieParenteId = $factory->category->create(['name' => 'Actualités']);
        $factory->post->create_many(5, ['post_category' => [self::$categorieParenteId]]);
    }

    public function test_les_articles_sont_rattaches_a_la_categorie(): void
    {
        $articles = get_posts(['category' => self::$categorieParenteId]);

        $this->assertCount(5, $articles);
    }
}
L'essentiel à retenir : setUpBeforeClass et une méthode statique partagée évitent de recréer les mêmes objets ; Un trait dédié aux fixtures se réutilise dans plusieurs classes de test sans héritage lourd ; La mutualisation réduit aussi le temps d'exécution, pas seulement la duplication de code

Partager entre plusieurs classes avec un trait

Pour aller plus loin, quand plusieurs classes de test distinctes ont besoin de la même arborescence de catégories, un trait dédié centralise la construction du jeu de fixtures, sans imposer une hiérarchie d’héritage entre les classes :

trait ArborescenceCategoriesFixture
{
    private static int $categorieParenteId;
    private static int $categorieEnfantId;

    public static function creerArborescenceCategories(WP_UnitTest_Factory $factory): void
    {
        self::$categorieParenteId = $factory->category->create(['name' => 'Actualités']);
        self::$categorieEnfantId = $factory->category->create([
            'name' => 'Locales',
            'parent' => self::$categorieParenteId,
        ]);
    }
}

class ArticlesParCategorieTest extends WP_UnitTestCase
{
    use ArborescenceCategoriesFixture;

    public static function wpSetUpBeforeClass(WP_UnitTest_Factory $factory): void
    {
        self::creerArborescenceCategories($factory);
    }
}

Six classes qui utilisaient chacune leur propre variante de cette arborescence ont pu adopter le même trait, ce qui a réduit la construction de données redondantes en base et rendu explicite, pour quiconque ouvre l’une de ces classes, que la structure de catégories provient d’une source commune documentée à un seul endroit.

La précaution à ne pas oublier

Un jeu de fixtures partagé entre méthodes d’une même classe reste en lecture depuis toutes les méthodes qui suivent : une méthode de test qui modifierait ces objets partagés (renommer une catégorie, par exemple) affecterait silencieusement les méthodes suivantes de la classe. La règle à observer est simple : les fixtures partagées via wpSetUpBeforeClass ou un trait commun doivent rester strictement en lecture ; toute modification nécessaire à un test précis doit passer par une fixture créée localement dans ce test, pas par une modification du jeu partagé.

En résumé

Remplacer un setUp() répété par un jeu de fixtures construit une seule fois, via wpSetUpBeforeClass et, au besoin, un trait partagé entre classes, réduit à la fois la duplication de code et le temps d’exécution d’une suite. La seule discipline à maintenir est de traiter ces fixtures partagées comme des données en lecture seule, jamais modifiées par un test individuel.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Partager :

À propos de l'auteur

WordPress Développement

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

Voir tous ses articles

Dans la même veine

À lire aussi