Introduction au test logiciel/Tests unitaires/PHPUnit

Un livre de Wikilivres.
Sauter à la navigation Sauter à la recherche

PHPUnit est utilisé dans un certain nombre de frameworks connus. Sa documentation en anglais est disponible au format PDF[1].

Installation du binaire[modifier | modifier le wikicode]

Une fois le .phar téléchargé depuis le site officiel[2], le copier dans le dossier où il sera toujours exécuté. Exemple :

  • Unix-like :
mv phpunit.phar /usr/local/bin/phpunit
chmod +x phpunit.phar
  • Windows :
    1. Ajouter à la variable d'environnement PATH, le dossier où se trouve le fichier (ex : ;C:\bin).
    2. Créer un fichier exécutable à côté (ex : C:\bin\phpunit.cmd) contenant le code : @php "%~dp0phpunit.phar" %*.
  • Test de l'installation en shell ou DOS :
phpunit --version

Par ailleurs, le code source de cet exécutable est sur GitHub[3].

Utilisation[modifier | modifier le wikicode]

Il faut indiquer au programme les dossiers contenant des tests dans le fichier phpunit.xml.dist. Exemple sur Symfony[4] :

<?xml version="1.0" encoding="UTF-8"?>

<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/6.0/phpunit.xsd"
         backupGlobals="false"
         colors="true"
         bootstrap="vendor/autoload.php"
>
    <php>
        <ini name="error_reporting" value="-1" />
        <server name="KERNEL_CLASS" value="AppKernel" />
        <env name="SYMFONY_DEPRECATIONS_HELPER" value="weak" />
    </php>

    <testsuites>
        <testsuite name="Project Test Suite">
            <directory>tests</directory>
        </testsuite>
    </testsuites>

    <filter>
        <whitelist>
            <directory>src</directory>
            <exclude>
                <directory>src/*</directory>
            </exclude>
        </whitelist>
    </filter>

    <listeners>
        <listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener" />
    </listeners>

</phpunit>

Ensuite, pour tester tous les fichiers du dossier /test et ignorer ceux de /src, il suffit de lancer :

./bin/phpunit

Si les tests sont longs et qu'on ne travaille que sur une seule classe, on peut demander à ne tester qu'elle en précisant son nom :

./bin/phpunit --filter=MaClasseTest

Écriture des tests[modifier | modifier le wikicode]

use PHPUnit\Framework\TestCase;

class SuiteDeTests1 extends TestCase
{
    protected function setUp()
    {
        // Création des mocks et instanciation de la classe à tester...
    }

    protected function tearDown()
    {
        // Libération des ressources après les tests...
    }

    protected function test1()
    {
        // Lancement du premier test...
        $this->assertTrue($condition);
    }
}

La classe de test PHPUnit propose des dizaines d'assertions différentes.

MockObject[modifier | modifier le wikicode]

Les mocks permettent de simuler des résultats de classes existantes[5].

willReturn[modifier | modifier le wikicode]

Par exemple, pour simuler le résultat de deux classes imbriquées (en appelant la méthode d'une méthode), on leur crée une méthode de test chacune :

    public function mainTest()
    {
        $this->monMock1
            ->expects($this->once())
            ->method('MaMéthode1')
            ->willReturn($this->mockProvider())
        ;

        $this->assertEquals(null, $this->monMock1->MaMéthode1()->MaMéthode2());
    }

    private function mockProvider()
    {
        $monMock = $this
            ->getMockBuilder('MaClasse1')
            ->getMock()
        ;
        $monMock->method('MaMéthode2')
            ->willReturn('MonRésultat1')
        ;

        return $monMock;
    }

Ici, expects() est un espion qui compte le nombre de passage dans la méthode, et le test échoue si ce résultat n'est pas 1. Ses valeurs possibles sont :

  • $this->never() : 0.
  • $this->once() : 1.
  • $this->exactly(x) : x.
  • $this->any().

onConsecutiveCalls[modifier | modifier le wikicode]

Si la valeur retournée par le mock doit changer à chaque appel, il faut remplacer willReturn() par onConsecutiveCalls().

Exemple :

        $this->enumProvider->method('getEnumFromVariable')
            ->will($this->onConsecutiveCalls(
                ProductStatusEnum::ON_LINE,
                OrderStatusEnum::VALIDATED
            ));
        ;
À faire...
link={{{link}}}


Ajouter des exemples de :

  • ->with()
  • ->disableOriginalConstructor()
  • ->setExpectedException()


Annotations[modifier | modifier le wikicode]

À faire...
link={{{link}}}


  • @covers
  • @uses
  • @dataProvider
  • @expectedException


JavaScript[modifier | modifier le wikicode]

En PHP, Selenium peut s'interfacer avec PHPUnit[6] pour tester du JavaScript.

Références[modifier | modifier le wikicode]