Retour à l'accueil

PHPUnit covers : navigation et couverture de tests pour les développeurs

L'article explique comment utiliser les annotations et attributs covers dans PHPUnit pour améliorer la navigation entre les tests et le code de l'application. Il couvre les approches pour lier les tests aux méthodes, la configuration d'IDE et les limitations de couverture.

Améliorer les tests en PHP : guide sur covers dans PHPUnit
Advertisement 728x90

PHPUnit : Maîtriser les Covers pour une navigation et une couverture de tests optimale

Tester les contrôleurs web en PHP entraîne souvent des casse-tête pour naviguer entre les tests et le code de l'application. Explorons comment les annotations et attributs @covers de PHPUnit résolvent cela, en fluidifiant le développement sans sacrifier la couverture.

Le défi de navigation entre tests et code

Lors du test des contrôleurs via des requêtes HTTP, on ne peut pas appeler directement les méthodes, ce qui complique le saut du test vers le code. Par exemple, un test pour l'endpoint /hello ne référence pas directement GreetingController::hello(). Cela oblige à des recherches manuelles dans l'IDE, ce qui ralentit le travail.

Voici un exemple de contrôleur et de test :

Google AdInline article slot
final class GreetingController extends AbstractController
{  
    #[Route('/hello')]
    public function hello(): Response
    {
        return new Response($this->generate("Hello!"));
    }
}
class GreetingControllerTest extends WebTestCase
{
    public function test_hello(): void
    {
        $content = get('/hello');
        assert_starts_with('Hello!', $content);
    }
}

Trois façons de lier les tests au code

Les développeurs utilisent divers astuces pour améliorer la navigation.

1. Syntaxe native avec réflexion

Remplacer les chemins sous forme de chaînes par des appels de méthodes via la réflexion, comme request(GreetingController::hello(...)). Inconvénient : les tests perdent leur indépendance vis-à-vis du code de l'app, risquant de casser lors des changements.

Google AdInline article slot

2. Annotation @see

Utiliser PHPDoc pour lier :

/**
 * @see \App\Controller\GreetingController::hello()
 */
public function test_hello(): void { ... }

Avantages : support IDE. Inconvénients : nécessite les chemins complets des classes, tag générique sans traitement spécial.

Google AdInline article slot

3. Covers spécialisés de PHPUnit

Annotations ou attributs conçus pour la couverture et la navigation.

Utiliser les annotations Covers dans PHPUnit

Avant PHPUnit 12, @coversDefaultClass et @covers dominaient :

/**
 * @coversDefaultClass \App\Controller\GreetingController
 */
class GreetingControllerTest extends WebTestCase
{
    /**
     * @covers ::hello
     */
    public function test_hello(): void { ... }
}

Avantages :

  • Excellent support PhpStorm : autocomplétion, navigation, détection d'usage.
  • Modèles personnalisés pour la génération de tests.

Inconvénients des modèles PhpStorm :

  • Limités à deux modèles PHPUnit.
  • Noms confus.
  • Glitches occasionnels du générateur.

Passage aux attributs Covers dans PHPUnit 12+

PHPUnit 12 abandonne les annotations au profit des attributs, mais avec une limite : ils s'appliquent seulement aux classes, pas aux méthodes.

Utilisation de base :

#[CoversClass('App\Controller\GreetingController')]
class GreetingControllerTest extends WebTestCase
{
    public function test_hello(): void { ... }
}

Cela nuit à la précision de navigation sans spécificité des méthodes.

Spécifier les méthodes avec CoversMethod :

#[CoversMethod('App\Controller\GreetingController', 'hello')]
#[CoversMethod('App\Controller\GreetingController', 'bye')]
class GreetingControllerTest extends WebTestCase
{
    public function test_hello(): void { ... }
    public function test_bye(): void { ... }
}

Inconvénient : encombrement d'attributs pour les tests multi-méthodes.

Meilleure stratégie : Une classe de test par méthode

Des classes de test dédiées par méthode simplifient tout :

#[CoversMethod('App\Controller\GreetingController', 'hello')]
class HelloTest extends WebTestCase
{
    public function test_hello(): void { ... }
    public function test_hello2(): void { ... }
}

Avantages :

  • Moins de charge mentale.
  • Pas besoin de covers par méthode.
  • Favorise un design propre : un contrôleur, un endpoint.

Les modèles d'attributs fonctionnent comme les annotations mais nécessitent des ajustements manuels CoversMethod après génération.

Intégration IDE et évolutions futures

PhpStorm gère déjà les sauts test-classe via Ctrl+Shift+T. La navigation au niveau méthode arrive bientôt.

Points clés

  • Utilisez covers pour booster la navigation, mais surveillez l'impact sur la couverture.
  • Les attributs PHPUnit 12+ sont limités aux classes, adaptez vos tests.
  • Idéal : une classe de test par méthode pour une maintenance aisée.
  • Configurez les modèles IDE pour des covers automatiques.
  • Suivez les mises à jour PhpStorm pour un meilleur support des attributs.

Limites de couverture : Le plus gros défaut des Covers

Le rôle principal des covers est de limiter la couverture aux classes/méthodes. CoversClass exclut le code externe des rapports — idéal pour les projets stricts, mais la plupart des devs veulent juste repérer les lacunes.

Solutions de contournement pour désactiver :

  • Hack extrême : Scripts supprimant les tags avant exécution des tests.
  • Solution pratique : Patch de phpunit/php-code-coverage via Composer.

Choisissez selon les besoins du projet et les préférences de l'équipe.

— Editorial Team

Advertisement 728x90

Lire ensuite