Prev Next

Chapitre 16. Générateur de squelette

Le générateur de squelette de PHPUnit (Skeleton Generator) est un outil qui peut générer des squelettes de classes de test à partir des classes de code de production et vice versa. Il peut être installé en utilisant la commande suivante :

pear install phpunit/PHPUnit_SkeletonGenerator

Générer un squelettre de classe de cas de test

Quand vous écrivez des tests pour du code existant, vous avez à écrire les mêmes fragments de code tels que

public function testMethode()
{
}

encore et encore. Le générateur de squelette de PHPUnit peut vous aider en analysant le code d'une classe existante et en générant pour elle un squelette de classe de cas de test.

Exemple 16.1. La classe Calculateur

<?php
class Calculateur
{
public function additionner($a, $b)
{
return $a + $b;
}
}
?>

L'exemple suivant montre comment générer un squelette de classe de de test pour une classe appelée Calculateur (see Exemple 16.1, « La classe Calculateur »).

phpunit-skelgen --test Calculateur
PHPUnit Skeleton Generator 1.0.0 by Sebastian Bergmann.

Wrote skeleton for "CalculateurTest" to "/home/sb/CalculateurTest.php".

Pour chaque méthode de la classe originelle, il y a aura un cas de test incomplet (voir Chapitre 9, Tests incomplets et sautés) dans la classe de cas de test générée.

Classes sous espace de nom et le générateur de squelette

Lorsque vous utilisez le générateur de squelette pour générer du code basé sur une classe qui est déclarée dans un espace de nommage (namespace) vous devez fournir le nom qualifié de la classe ainsi que le chemin d'accès au fichier source dans lequel elle est déclarée.

Par exemple, pour une classe Calculateur qui est déclarée dans l'espace de nommage projet, vous devez invoquer le générateur de squelette comme ceci :

phpunit-skelgen --test -- "projet\Calculateur" Calculateur.php
PHPUnit Skeleton Generator 1.0.0 by Sebastian Bergmann.

Wrote skeleton for "projet\CalculateurTest" to "/home/sb/CalculateurTest.php".

Ci-dessous se trouve la sortie écran produite par le lancement de la classe de cas de test générée.

phpunit --bootstrap Calculateur.php --verbose CalculateurTest
PHPUnit 3.6.8 by Sebastian Bergmann.

I

Time: 0 seconds, Memory: 3.50Mb

There was 1 incomplete test:

1) CalculateurTest::testAdditionner
This test has not been implemented yet.

/home/sb/CalculateurTest.php:38
OK, but incomplete or skipped tests!
Tests: 1, Assertions: 0, Incomplete: 1.

Vous pouvez utiliser l'annotation @assert dans le bloc de documentation d'une méthode pour générer automatiquement des tests simples mais significatifs au lieu de cas de tests incomplets. Exemple 16.2, « La classe Calculateur avec des annotations @assert » montre un exemple.

Exemple 16.2. La classe Calculateur avec des annotations @assert

<?php
class Calculateur
{
/**
* @assert (0, 0) == 0
* @assert (0, 1) == 1
* @assert (1, 0) == 1
* @assert (1, 1) == 2
*/
public function additionner($a, $b)
{
return $a + $b;
}
}
?>

Chaque méthode de la classe originelle est contrôlée à la recherche d'annotations @assert. Celles-ci sont transformées en code de test comme

    /**
     * Generated from @assert (0, 0) == 0.
     */
    public function testAdditionner() {
        $o = new Calculateur;
        $this->assertEquals(0, $o->additionner(0, 0));
    }

Ci-dessous se trouve la sortie écran produite par le lancement de la classe de cas de test générée.

phpunit --bootstrap Calculateur.php --verbose CalculateurTest
PHPUnit 3.6.8 by Sebastian Bergmann.

....

Time: 0 seconds, Memory: 3.50Mb

OK (4 tests, 4 assertions)

Tableau 16.1, « Variantes gérées par l'annotation @assert » montre les variantes gérées par l'annotation @assert et de quelle façon elles sont transformées en code de test.

Tableau 16.1. Variantes gérées par l'annotation @assert

Annotation Transformée en
@assert (...) == X assertEquals(X, methode(...))
@assert (...) != X assertNotEquals(X, methode(...))
@assert (...) === X assertSame(X, methode(...))
@assert (...) !== X assertNotSame(X, methode(...))
@assert (...) > X assertGreaterThan(X, methode(...))
@assert (...) >= X assertGreaterThanOrEqual(X, methode(...))
@assert (...) < X assertLessThan(X, methode(...))
@assert (...) <= X assertLessThanOrEqual(X, methode(...))
@assert (...) throws X @expectedException X

Générer un squelette de classe à partir d'une classe de cas de test

Lorsque vous pratiquez le développement dirigé par les tests (voir Chapitre 12, Développement dirigé par les tests) et que vous écrivez vos tests avant le code que les tests vérifient, PHPUnit peut vous aider à générer des squelettes de classe à partir des classes de cas de test.

Suivant la convention selon laquelle les tests pour une classe Unit sont écrit dans une classe nommée UnitTest, le source de la classe de cas de test est inspecté à la recherche de variables qui référencent des objets de la classe Unit puis est analysé pour savoir quelles méthodes sont appelées sur ces objets. Par exemple, jetez un oeil à Exemple 16.4, « Le squelette généré de la classe JeuDeBowling » qui a été généré en se basant sur l'analyse de Exemple 16.3, « La classe JeuDeBowlingTest ».

Exemple 16.3. La classe JeuDeBowlingTest

<?php
class JeuDeBowlingTest extends PHPUnit_Framework_TestCase
{
protected $jeu;

protected function setUp()
{
$this->jeu = new JeuDeBowling;
}

protected function lancePlusieursEtRenverse($n, $quilles)
{
for ($i = 0; $i < $n; $i++) {
$this->jeu->renverse($quilles);
}
}

public function testScorePourJeuDansLaRigoleEst0()
{
$this->lancePlusieursEtRenverse(20, 0);
$this->assertEquals(0, $this->jeu->score());
}
}
?>

phpunit-skelgen --class JeuDeBowlingTest
PHPUnit Skeleton Generator 1.0.0 by Sebastian Bergmann.

Wrote skeleton for "JeuDeBowling" to "./JeuDeBowling.php".

Exemple 16.4. Le squelette généré de la classe JeuDeBowling

<?php
/**
* Generated by PHPUnit_SkeletonGenerator on 2012-01-09 at 16:55:58.
*/
class JeuDeBowling
{
/**
* @todo Implement renverse().
*/
public function renverse()
{
// Remove the following line when you implement this method.
throw new RuntimeException('Not yet implemented.');
}

/**
* @todo Implement score().
*/
public function score()
{
// Remove the following line when you implement this method.
throw new RuntimeException('Not yet implemented.');
}
}
?>

Ci-dessous se trouve la sortie écran produite par le lancement de la classe de cas de test générée.

phpunit --bootstrap JeuDeBowling.php JeuDeBowlingTest
PHPUnit 3.6.8 by Sebastian Bergmann.

E

Time: 0 seconds, Memory: 3.50Mb

There was 1 error:

1) JeuDeBowlingTest::testScorePourJeuDansLaRigoleEst0
RuntimeException: Not yet implemented.

/home/sb/JeuDeBowling.php:13
/home/sb/JeuDeBowlingTest.php:14
/home/sb/JeuDeBowlingTest.php:20

FAILURES!
Tests: 1, Assertions: 0, Errors: 1.
Prev Next
1. Automatiser les tests
2. Objectifs de PHPUnit
3. Installer PHPUnit
4. Ecrire des tests pour PHPUnit
Dépendances des tests
Fournisseur de données
Tester des exceptions
Tester les erreurs PHP
Tester la sortie écran
Assertions
assertArrayHasKey()
assertClassHasAttribute()
assertClassHasStaticAttribute()
assertContains()
assertContainsOnly()
assertCount()
assertEmpty()
assertEqualXMLStructure()
assertEquals()
assertFalse()
assertFileEquals()
assertFileExists()
assertGreaterThan()
assertGreaterThanOrEqual()
assertInstanceOf()
assertInternalType()
assertLessThan()
assertLessThanOrEqual()
assertNull()
assertObjectHasAttribute()
assertRegExp()
assertStringMatchesFormat()
assertStringMatchesFormatFile()
assertSame()
assertSelectCount()
assertSelectEquals()
assertSelectRegExp()
assertStringEndsWith()
assertStringEqualsFile()
assertStringStartsWith()
assertTag()
assertThat()
assertTrue()
assertXmlFileEqualsXmlFile()
assertXmlStringEqualsXmlFile()
assertXmlStringEqualsXmlString()
5. Le lanceur de tests en ligne de commandes
Options de la ligne de commandes
6. Fixtures
Plus de setUp() que de tearDown()
Variantes
Partager les Fixtures
Etat global
7. Organiser les tests
Composer une suite de tests en utilisant le système de fichiers
Composer une suite de tests en utilisant la configuration XML
8. Tester des bases de données
Systèmes gérés pour tester des bases de données
Difficultés pour tester les bases de données
Les quatre phases d'un test de base de données
1. Nettoyer la base de données
2. Configurer les fixtures
3–5. Exécuter les tests, vérifier les résultats et nettoyer
Configuration d'un cas de test de base de données PHPUnit
Implémenter getConnection()
Implémenter getDataSet()
Qu'en est-il du schéma de base de données (DDL)?
Astuce: utilisez votre propre cas de tests abstrait de base de données
Comprendre DataSets et DataTables
Implémentations disponibles
Attention aux clefs étrangères
Implementer vos propres DataSets/DataTables
L'API de connexion
API d'assertion de base de données
Faire une assertion sur le nombre de lignes d'une table
Faire une assertion sur l'état d'une table
Faire une assertion sur le résultat d'une requête
Faire une assertion sur l'état de plusieurs tables
Foire aux questions
PHPUnit va-t'il (re-)créer le schéma de base de données pour chaque test ?
Suis-je obligé d'utiliser PDO dans mon application pour que l'extension de base de données fonctionne ?
Que puis-je faire quand j'obtiens une erreur « Too much Connections (Trop de connexions) » ?
Comment gérer les valeurs NULL avec les DataSets au format XML à plat / CSV ?
9. Tests incomplets et sautés
Tests incomplets
Sauter des tests
10. Doublure de test
Bouchons
Objets simulacres (Mock Objects)
Bouchon et simulacre pour Web Services
Simuler le système de fichiers
11. Pratiques de test
Pendant le développement
Pendant le débogage
12. Développement dirigé par les tests
Exemple du compte bancaire
13. Développement dirigé par le comportement
Exemple du jeu de Bowling
14. Analyse de couverture de code
Spécifier les méthodes couvertes
Ignorer des blocs de code
Inclure et exclure des fichiers
Cas limites
15. Autres utilisations des tests
Documentation agile
Tests transverses à l'équipe
16. Générateur de squelette
Générer un squelettre de classe de cas de test
Générer un squelette de classe à partir d'une classe de cas de test
17. PHPUnit et Selenium
Selenium Server
Installation
PHPUnit_Extensions_Selenium2TestCase
PHPUnit_Extensions_SeleniumTestCase
18. Journalisation
Résultats de test (XML)
Résultats de test (TAP)
Résultats de test (JSON)
Couverture de code (XML)
Couverture de code (TEXTE)
19. Etendre PHPUnit
Sous-classe PHPUnit_Framework_TestCase
Ecrire des assertions personnalisées
Implémenter PHPUnit_Framework_TestListener
Sous classer PHPUnit_Extensions_TestDecorator
Implémenter PHPUnit_Framework_Test
A. Assertions
B. Annotations
@assert
@author
@backupGlobals
@backupStaticAttributes
@codeCoverageIgnore*
@covers
@dataProvider
@depends
@expectedException
@expectedExceptionCode
@expectedExceptionMessage
@group
@outputBuffering
@runTestsInSeparateProcesses
@runInSeparateProcess
@test
@testdox
@ticket
C. Le fichier de configuration Configuration
PHPUnit
Série de tests
Groupes
Inclure et exclure des fichiers de la couverture de code
Journalisation
Moniteurs de tests
Configurer les réglages de PHP INI, les constantes et les variables globales
Configurer les navigateurs pour Selenium RC
D. Index
Index
E. Bibliographie
F. Copyright