Annexe B. Annotations

Une annotation est une forme spéciale de métadonnée syntaxique qui peut être ajoutée au code source de certains langages de programmation. Bien que PHP n'ait pas de fonctionnalité dédiée à l'annotation du code source, l'utilisation d'étiquettes telles que @annotation arguments dans les blocs de documentation s'est établi dans la communauté PHP pour annoter le code source. En PHP, les blocs de documentation sont réflexifs : ils peuvent être accédés via la méthode de l'API de réflexivité getDocComment() au niveau des fonctions, classes, méthodes et attributs. Des applications telles que PHPUnit utilisent ces informations durant l'exécution pour adapter leur comportement.

Note

Un "doc comment" en PHP doit commencé par /** et se terminer avec */. Les annotations se trouvant des des commentaires d'un autre style seront ignorées.

Cette annexe montre toutes les sortes d'annotations gérées par PHPUnit.

@author

L'annotation @author est un alias pour l'annotation @group (voir la section intitulée « @group ») et permet de filtrer des tests selon leurs auteurs.

@after

L'annotation @after peut être utilisé pour spécifier des méthodes devant être appelées après chaque méthode de test dans une classe de cas de tests.

use PHPUnit\Framework\TestCase;

class MyTest extends TestCase
{
    /**
     * @after
     */
    public function tearDownSomeFixtures()
    {
        // ...
    }

    /**
     * @after
     */
    public function tearDownSomeOtherFixtures()
    {
        // ...
    }
}

@afterClass

L'annotation @afterClass peut-être utilisées pour spécifier des méthodes statiques devant être appelées après chaque méthode de test dans une classe de test pour être exécuté afin de nettoyer des fixtures partagées.

use PHPUnit\Framework\TestCase;

class MyTest extends TestCase
{
    /**
     * @afterClass
     */
    public static function tearDownSomeSharedFixtures()
    {
        // ...
    }

    /**
     * @afterClass
     */
    public static function tearDownSomeOtherSharedFixtures()
    {
        // ...
    }
}

@backupGlobals

Les opérations de sauvegarde et de restauration des variables globales peuvent être complètement désactivées pour tous les tests d'une classe de cas de test comme ceci :

use PHPUnit\Framework\TestCase;

/**
 * @backupGlobals disabled
 */
class MyTest extends TestCase
{
    // ...
}

L'annotation @backupGlobals peut également être utilisée au niveau d'une méthode. Cela permet une configuration fine des des opérations de sauvegarde et de restauration :

use PHPUnit\Framework\TestCase;

/**
 * @backupGlobals disabled
 */
class MyTest extends TestCase
{
    /**
     * @backupGlobals enabled
     */
    public function testThatInteractsWithGlobalVariables()
    {
        // ...
    }
}

@backupStaticAttributes

L'annotation @backupStaticAttributes peut être utilisée pour enregistrer tous les attributs statiques dans toutes les classes déclarées avant chaque test et les restaurer après. Elle peut être utilisé au niveau de la classe ou au niveau de la méthode :

use PHPUnit\Framework\TestCase;

/**
 * @backupStaticAttributes enabled
 */
class MyTest extends TestCase
{
    /**
     * @backupStaticAttributes disabled
     */
    public function testThatInteractsWithStaticAttributes()
    {
        // ...
    }
}

Note

@backupStaticAttributes est limitée par le fonctionnement interne de PHP et peut entrainer la persistance inattendue de valeurs statique et fuiter dans les tests suivants tests dans certaines circonstances.

Voir la section intitulée « Etat global » pour les détails.

@before

L'annotation @before peut être utilisée pour spécifier des méthodes devant être appelées avant chaque méthode de test dans une classe de cas de test.

use PHPUnit\Framework\TestCase;

class MyTest extends TestCase
{
    /**
     * @before
     */
    public function setupSomeFixtures()
    {
        // ...
    }

    /**
     * @before
     */
    public function setupSomeOtherFixtures()
    {
        // ...
    }
}

@beforeClass

L'annotation @beforeClass peut être utilisée pour spécifier des méthodes statiques qui doivent être appellées avant chaque méthodes de test dans une classe de test qui sont exécutés pour paramétrer des fixtures partagées.

use PHPUnit\Framework\TestCase;

class MyTest extends TestCase
{
    /**
     * @beforeClass
     */
    public static function setUpSomeSharedFixtures()
    {
        // ...
    }

    /**
     * @beforeClass
     */
    public static function setUpSomeOtherSharedFixtures()
    {
        // ...
    }
}

@codeCoverageIgnore*

Les annotations @codeCoverageIgnore, @codeCoverageIgnoreStart et @codeCoverageIgnoreEnd peuvent être utilisées pour exclure des lignes de code de l'analyse de couverture.

Pour la manière de les utiliser, voir la section intitulée « Ignorer des blocs de code ».

@covers

L'annotation @covers peut être utilisée dans le code de test pour indique quelle(s) méthode(s) une méthode de test veut tester:

/**
 * @covers BankAccount::getBalance
 */
public function testBalanceIsInitiallyZero()
{
    $this->assertEquals(0, $this->ba->getBalance());
}

Si elle est fournie, seule l'information de couverture de code pour la(les) méthode(s) sera prise en considération.

Tableau B.1, « Annotations pour indiquer quelles méthodes sont couvertes par un test » montre la syntaxe de l'annotation @covers.

Tableau B.1. Annotations pour indiquer quelles méthodes sont couvertes par un test

AnnotationDescription
@covers ClassName::methodNameIndique que la méthode de test annotée couvre la méthode indiquée.
@covers ClassNameIndique que la méthode de test annotée couvre toutes les méthodes d'une classe donnée.
@covers ClassName<extended>Indique que la méthode de test annotée couvre toutes les méthodes d'une classe donnée ainsi que les classe(s) et interface(s) parentes.
@covers ClassName::<public>Indique que la méthode de test annotée couvre toutes les méthodes publiques d'une classe donnée.
@covers ClassName::<protected>Indique que la méthode de test annotée couvre toutes les méthodes protected d'une classe donnée.
@covers ClassName::<private>Indique que la méthode de test annotée couvre toutes les méthodes privées d'une classe donnée.
@covers ClassName::<!public>Indique que la méthode de test annotée couvre toutes les méthodes d'une classe donnée qui ne sont pas publiques.
@covers ClassName::<!protected>Indique que la méthode de test annotée couvre toutes les méthodes d'une classe donnée qui ne sont pas protected.
@covers ClassName::<!private>Indique que la méthode de test annotée couvre toutes les méthodes d'une classe donnée qui ne sont pas privées.
@covers ::functionNameIndique que la méthode de test annotée couvre la méthode globale spécifiée.


@coversDefaultClass

L'annotation @coversDefaultClass peut être utilisée pour spécifier un espace de nom ou un nom de classe par défaut. Ainsi, les noms long n'ont pas besoin d'être répétés pour chaque annotation @covers. Voir Exemple B.1, « Utiliser @coversDefaultClass pour simplifier les annotations ».

Exemple B.1. Utiliser @coversDefaultClass pour simplifier les annotations

<?php
use PHPUnit\Framework\TestCase;

/**
 * @coversDefaultClass \Foo\CoveredClass
 */
class CoversDefaultClassTest extends TestCase
{
    /**
     * @covers ::publicMethod
     */
    public function testSomething()
    {
        $o = new Foo\CoveredClass;
        $o->publicMethod();
    }
}
?>


@coversNothing

L'annotation @coversNothing peut être utilisée dans le code de test pour indiquer qu'aucune information de couverture de code ne sera enregistrée pour le cas de test annoté.

Ceci peut être utilisé pour les tests d'intégration. Voir Exemple 11.3, « Un test qui indique qu'aucune méthode ne doit être couverte » pour un exemple.

L'annotation peut être utilisée au niveau de la classe et de la méthode et sera surchargée par toute étiquette @covers.

@dataProvider

Une méthode de test peut accepter des paramètres arbitraires. Ces paramètres peuvent être fournis pas une méthode fournisseuse de données ((provider() dans Exemple 2.5, « Utiliser un fournisseur de données qui renvoie un tableau de tableaux »). La méthode fournisseur de données peut être indiquée en utilisant l'annotation @dataProvider.

Voir la section intitulée « Fournisseur de données » pour plus de détails.

@depends

PHPUnit gère la déclaration des dépendances explicites entre les méthodes de test. De telles dépendances ne définissent pas l'ordre dans lequel les méthodes de test doivent être exécutées mais elles permettent de retourner l'instance d'une fixture de test par un producteur et de la passer aux consommateurs dépendants. Exemple 2.2, « Utiliser l'annotation @depends pour exprimer des dépendances » montre comment utiliser l'annotation @depends pour exprimer des dépendances entre méthodes de test.

Voir la section intitulée « Dépendances des tests » pour plus de détails.

@expectedException

Exemple 2.10, « Utiliser la méthode expectException() » montre comment utiliser l'annotation @expectedException pour tester si une exception est levée dans le code testé.

Voir la section intitulée « Tester des exceptions » pour plus de détails.

@expectedExceptionCode

L'annotation @expectedExceptionCode, en conjonction avec @expectedException permet de faire des assertions sur le code d'erreur d'une exception levée ce qui permet de cibler une exception particulière.

use PHPUnit\Framework\TestCase;

class MyTest extends TestCase
{
    /**
     * @expectedException     MyException
     * @expectedExceptionCode 20
     */
    public function testExceptionHasErrorcode20()
    {
        throw new MyException('Some Message', 20);
    }
}

Pour faciliter les tests et réduire la duplication, un raccourci peut être utilisé pour indiquer une constante de classe comme un @expectedExceptionCode en utilisant la syntaxe "@expectedExceptionCode ClassName::CONST".

use PHPUnit\Framework\TestCase;

class MyTest extends TestCase
{
    /**
      * @expectedException     MyException
      * @expectedExceptionCode MyClass::ERRORCODE
      */
    public function testExceptionHasErrorcode20()
    {
      throw new MyException('Some Message', 20);
    }
}
class MyClass
{
    const ERRORCODE = 20;
}

@expectedExceptionMessage

L'annotation @expectedExceptionMessage fonctionne de manière similaire à @expectedExceptionCode et vous permet de faire une assertion sur le message d'erreur d'une exception.

use PHPUnit\Framework\TestCase;

class MyTest extends TestCase
{
    /**
     * @expectedException        MyException
     * @expectedExceptionMessage Some Message
     */
    public function testExceptionHasRightMessage()
    {
        throw new MyException('Some Message', 20);
    }
}

Le message attendu peut être une partie d'une chaîne d'un message d'exception. Ceci peut être utile pour faire une assertion sur le fait qu'un nom ou un paramètre qui est passé s'affiche dans une exception sans fixer la totalité du message d'exception dans le test.

use PHPUnit\Framework\TestCase;

class MyTest extends TestCase
{
     /**
      * @expectedException        MyException
      * @expectedExceptionMessage broken
      */
     public function testExceptionHasRightMessage()
     {
         $param = "broken";
         throw new MyException('Invalid parameter "'.$param.'".', 20);
     }
}

Pour faciliter les tests et réduire la duplication, un raccourci peut être utilisé pour indiquer une constante de classe comme un @expectedExceptionCode en utilisant la syntaxe "@expectedExceptionCode ClassName::CONST". Un exemple peut être trouvé dans la section intitulée « @expectedExceptionCode ».

@expectedExceptionMessageRegExp

Le message d'exception attendu peut aussi être spécifié par une expression régulière en utilisant l'annotation @expectedExceptionMessageRegExp. C'est utile pour des situations où une sous-chaine n'est pas adaptée pour correspondre au message donné.

use PHPUnit\Framework\TestCase;

class MyTest extends TestCase
{
     /**
      * @expectedException              MyException
      * @expectedExceptionMessageRegExp /Argument \d+ can not be an? \w+/
      */
     public function testExceptionHasRightMessage()
     {
         throw new MyException('Argument 2 can not be an integer');
     }
}

@group

Un test peut être marqué comme appartement à un ou plusieurs groupes en utilisant l'annotation @group comme ceci

use PHPUnit\Framework\TestCase;

class MyTest extends TestCase
{
    /**
     * @group specification
     */
    public function testSomething()
    {
    }

    /**
     * @group regresssion
     * @group bug2204
     */
    public function testSomethingElse()
    {
    }
}

Des tests peuvent être sélectionnés pour l'exécution en se basant sur les groupes en utilisant les options --group et --exclude-group du lanceur de test en ligne de commandes ou en utilisant les directives respectives du fichier de configuration XML.

@large

L'annotation @large est un alias pour @group large.

Si le paquet PHP_Invoker est installé et que le mode strict est activé, un test "large" échouera s'il prend plus de 60 secondes pour s'exécuter. Ce délai est configurable via l'attribut timeoutForLargeTests dans le fichier de configuration XML.

@medium

L'annotation @medium est un alias pour @group medium. Un test "medium" ne doit pas dépendre d'un test marqué comme @large.

Si le paquet PHP_Invoker est installé et que le mode strict est activé, un test "medium" échouera s'il prend plus de 10 secondes pour s'exécuter. Ce délai est configurable via l'attribut timeoutForMediumTests dans le fichier de configuration XML.

@preserveGlobalState

Quand un test est exécuté dans un processus séparé, PHPUnit va tenter de conserver l'état global du processus parent en sérialisant toutes les globales dans le processus parent et en les désérialisant dans le processus enfant. Cela peut poser des problèmes si le processus parent contient des globales qui ne sont pas sérialisable. Pour corriger cela, vous pouvez empécher PHPUnit de conserver l'état global avec l'annotation @preserveGlobalState.

use PHPUnit\Framework\TestCase;

class MyTest extends TestCase
{
    /**
     * @runInSeparateProcess
     * @preserveGlobalState disabled
     */
    public function testInSeparateProcess()
    {
        // ...
    }
}

@requires

L'annotation @requires peut être utilisée pour sauter des tests lorsque des pré-requis communs, comme la version de PHP ou des extensions installées, ne sont pas fournis.

Une liste complète des possibilités et des exemples peuvent être trouvés à Tableau 7.3, « Usages possibles de @requires »

@runTestsInSeparateProcesses

Indique que tous les tests d'une classe de tests doivent être executés dans un processus PHP séparé.

use PHPUnit\Framework\TestCase;

/**
 * @runTestsInSeparateProcesses
 */
class MyTest extends TestCase
{
    // ...
}

Note: Par défaut, PHPUnit va essayer de conserver l'état global depuis le processus parent en sérialisant toutes les globales dans le processus parent et en les désérialisant dans le processus enfant. Cela peut poser des problèmes si le processus parent contient des globales qui ne sont pas sérialisable. Voir la section intitulée « @preserveGlobalState » pour plus d'information sur comment le corriger.

@runInSeparateProcess

Indique qu'un test doit être executé dans un processus PHP séparé.

use PHPUnit\Framework\TestCase;

class MyTest extends TestCase
{
    /**
     * @runInSeparateProcess
     */
    public function testInSeparateProcess()
    {
        // ...
    }
}

Note: Par défaut, PHPUnit va essayer de conserver l'état global depuis le processus parent en sérialisant toutes les globales dans le processus parent et en les désérialisant dans le processus enfant. Cela peut poser des problèmes si le processus parent contient des globales qui ne sont pas sérialisable. Voir la section intitulée « @preserveGlobalState » pour plus d'information sur comment le corriger.

@small

L'annotation @small est un alias pour @group small. Un test "small" ne doit pas dépendre d'un test marqué comme @medium ou @large.

Si le paquet PHP_Invoker est installé et que le mode strict est activé, un test "small" va échoué s'il prend plus d'1 seconde pour s'executer. Ce délai est configurable via l'attrubut timeoutForSmallTests dans le fichier de configuration XML.

Note

Les tests doivent être explicitement annotés par soit @small, @medium, ou @large pour activer les temps limites d'execution.

@test

Comme alternative à préfixer vos noms de méthodes de test avec test, vous pouvez utiliser l'annotation @test dans le bloc de documentation d'une méthode pour la marquer comme méthode de test.

/**
 * @test
 */
public function initialBalanceShouldBe0()
{
    $this->assertEquals(0, $this->ba->getBalance());
}

@testdox

@ticket

@uses

L'annotation @uses spécifies du code qui sera exécuté par un test, mais qui n'et pas destiné à être couvert par le test. Un bon exemple est un objet-valeur qui est nécessaire pour tester une partie du code.

/**
 * @covers BankAccount::deposit
 * @uses   Money
 */
public function testMoneyCanBeDepositedInAccount()
{
    // ...
}

Cette annotation est spéciali This annotation is notamment utile en mode de couverture stricte où du code involontairement couvert va faire échouer un test. Voir la section intitulée « Code non-intentionnellement couvert » fpour plus d'informations sur le mode de couverture stricte.

Ouvrez un ticket sur GitHub pour proposer des améliorations à cette page. Merci!

粤公网安备 44190002002837号