Grouper des tests

Pour enchaîner nous allons remplir des blancs et créer une suite de tests.

Un autre test

Ajouter un autre test peut être aussi simple qu'ajouter une nouvelle méthode à un scénario de test...

class TestOfLogging extends UnitTestCase {
    function TestOfLogging() {
        $this->UnitTestCase('Log class test');
    }
    function testCreatingNewFile() {
        @unlink('../temp/test.log');
        $log = new Log('../temp/test.log');
        $this->assertFalse(file_exists('../temp/test.log'), 'Created before message');
        $log->message('Should write this to a file');
        $this->assertTrue(file_exists('../temp/test.log'), 'File created');
        @unlink('../temp/test.log');
    }
    function testAppendingToFile() {
        @unlink('../temp/test.log');
        $log = new Log('../temp/test.log');
        $log->message('Test line 1');
        $messages = file('../temp/test.log');
        $this->assertWantedPattern('/Test line 1/', $messages[0]);
        $log->message('Test line 2');
        $messages = file('../temp/test.log');
        $this->assertWantedPattern('/Test line 2/', $messages[1]);
        @unlink('../temp/test.log');
    }
}
La méthode du scénario de test assertWantedPattern() utilise les expressions rationnelles Perl pour vérifier qu'une chaîne respecte un certain motif.

Tout ce que nous faisons dans ce nouveau test, c'est écrire une ligne dans un fichier, puis la lire, le tout deux fois de suite. Nous souhaitons simplement vérifier que le loggueur ajoute le texte à la fin plutôt qu'écraser les données déjà existantes. Quelque peu pédant, mais après tout il s'agit d'un tutorial !

De toute façon ce test passe directement...

Log class test

1/1 test cases complete. 4 passes and 0 fails.
Notre code contient actuellement beaucoup de répétitions, nous devons effacer le fichier de test avant et après chaque test. De même que
JUnit, SimpleTest utilise les méthodes setUp() et tearDown() qui sont exécutées respectivement avant et après chaque test. La suppression du fichier est commune à tous les tests : nous devrions donc y mettre cette opération.

Nos tests sont verts donc nous pouvons faire un peu de remaniement...

class TestOfLogging extends UnitTestCase {
    function TestOfLogging() {
        $this->UnitTestCase('Log class test');
    }
    function setUp() {
        @unlink('../temp/test.log');
    }
    function tearDown() {
        @unlink('../temp/test.log');
    }
    function testCreatingNewFile() {
        $log = new Log('../temp/test.log');
        $this->assertFalse(file_exists('../temp/test.log'), 'Created before message');
        $log->message('Should write this to a file');
        $this->assertTrue(file_exists('../temp/test.log'), 'File created');
    }
    function testAppendingToFile() {
        $log = new Log('../temp/test.log');
        $log->message('Test line 1');
        $messages = file('../temp/test.log');
        $this->assertWantedPattern('/Test line 1/', $messages[0]);
        $log->message('Test line 2');
        $messages = file('../temp/test.log');
        $this->assertWantedPattern('/Test line 2/', $messages[1]);
    }
}
Le test reste vert. Nous pouvons continuer à ajouter des méthodes sans test au scénario, il suffit que leur nom ne commence pas par la chaîne "test". Seules les méthodes commençant par "test" sont exécutées. Nous pouvons donc continuer le remaniement...
class TestOfLogging extends UnitTestCase {
    function TestOfLogging() {
        $this->UnitTestCase('Log class test');
    }
    function setUp() {
        @unlink('../temp/test.log');
    }
    function tearDown() {
        @unlink('../temp/test.log');
    }
    function getFileLine($filename, $index) {
        $messages = file($filename);
        return $messages[$index];
    }
    function testCreatingNewFile() {
        $log = new Log('../temp/test.log');
        $this->assertFalse(file_exists('../temp/test.log'), 'Created before message');
        $log->message('Should write this to a file');
        $this->assertTrue(file_exists('../temp/test.log'), 'File created');
    }
    function testAppendingToFile() {
        $log = new Log('../temp/test.log');
        $log->message('Test line 1');
        $this->assertWantedPattern('/Test line 1/', $this->getFileLine('../temp/test.log', 0));
        $log->message('Test line 2');
        $this->assertWantedPattern('/Test line 2/', $this->getFileLine('../temp/test.log', 1));
    }
}
Que vous préfériez cette version ou la précédente ne dépend que de votre goût personnel. Il y a un peu plus de code dans cette dernière mais la logique du test est plus claire.

Un groupe de tests

Un scénario de test ne fonctionne pas tout seul pendant très longtemps. Quand on code pour de vrai nous souhaitons exécuter un maximum de tests aussi souvent et aussi rapidement que possible. Ça veut dire les grouper dans des suites de tests qui incluent l'ensemble des tests de l'application.

Premièrement nous devons supprimer le code d'exécution des tests se trouvant dans notre scénario de test.

<?php
require_once('../classes/log.php');

class TestOfLogging extends UnitTestCase {
    ...
}
?>
Nous n'avons plus besoin de la constante SIMPLE_TEST. Ensuite nous créons un groupe de tests appelé all_tests.php dans le répertoire tests...
<?php
    if (! defined('SIMPLE_TEST')) {
        define('SIMPLE_TEST', 'simpletest/');
    }
    require_once(SIMPLE_TEST . 'unit_tester.php');
    require_once(SIMPLE_TEST . 'reporter.php');
    require_once('log_test.php');

    $test = &new GroupTest('All tests');
    $test->addTestCase(new TestOfLogging());
    $test->run(new HtmlReporter());
?>
Il n'y a presque de pas de différence tant que les choses marchent...

All tests

1/1 test cases complete. 4 passes and 0 fails.
Les tests du groupe s'ajoutent au compteur des scénarios de test. Ajouter des nouveaux scénarios de test est très simple. Il suffit d'inclure le fichier d'un scénario et d'ajouter individuellement tous les scénarios autonomes. Vous pouvez aussi emboîter les groupes de test les uns dans les autres (tout en faisant bien attention d'éviter les boucles).

Dans la page suivante nous les ajouterons encore plus rapidement.

Ajouter un autres test au scénario existant et remanier.
La technique brute pour grouper des tests unitaires.
Ensuite vient le contrôle de comment la classe sous le test interagit avec le reste du système.
Avant il y a la création du premier test.
Vous aurez besoin de SimpleTest pour exécuter ces exemples.