From 322bb9cd2be9e51422cb2b82684692e825c2bfb7 Mon Sep 17 00:00:00 2001 From: brettp Date: Fri, 2 Oct 2009 18:40:04 +0000 Subject: Added simpletest and start of unit tests. git-svn-id: http://code.elgg.org/elgg/trunk@3503 36083f99-b078-4883-b0ff-0f9b5a30f544 --- vendors/simpletest/docs/fr/index.html | 572 ++++++++++++++++++++++++++++++++++ 1 file changed, 572 insertions(+) create mode 100755 vendors/simpletest/docs/fr/index.html (limited to 'vendors/simpletest/docs/fr/index.html') diff --git a/vendors/simpletest/docs/fr/index.html b/vendors/simpletest/docs/fr/index.html new file mode 100755 index 000000000..a13cb5787 --- /dev/null +++ b/vendors/simpletest/docs/fr/index.html @@ -0,0 +1,572 @@ + + + + + Prise en main rapide de SimpleTest pour PHP - + Tests unitaire et objets fantaisie pour PHP + + + + + +

Prise en main rapide de SimpleTest

+ This page... + +
+ +

+ Le présent article présuppose que vous soyez familier avec + le concept de tests unitaires ainsi que celui de développement + web avec le langage PHP. Il s'agit d'un guide pour le nouvel + et impatient utilisateur de + SimpleTest. + Pour une documentation plus complète, particulièrement si + vous découvrez les tests unitaires, consultez la + documentation + en cours, et pour des exemples de scénarios de test, + consultez le + tutorial + sur les tests unitaires. +

+ +

Utiliser le testeur rapidement

+

+ Parmi les outils de test pour logiciel, le testeur unitaire + est le plus proche du développeur. Dans un contexte de + développement agile, le code de test se place juste à côté + du code source étant donné que tous les deux sont écrits + simultanément. Dans ce contexte, SimpleTest aspire à être + une solution complète de test pour un développeur PHP et + s'appelle "Simple" parce qu'elle devrait être simple à + utiliser et à étendre. Ce nom n'était pas vraiment un bon + choix. Non seulement cette solution inclut toutes les + fonctions classiques qu'on est en droit d'attendre de la + part des portages de JUnit et des PHPUnit, + mais elle inclut aussi les objets fantaisie ou + "mock objects". +

+

+ Ce qui rend cet outil immédiatement utile pour un développeur PHP, + c'est son navigateur web interne. + Il permet des tests qui parcourent des sites web, remplissent + des formulaires et testent le contenu des pages. + Etre capable d'écrire ces tests en PHP veut dire qu'il devient + facile d'écrire des tests de recette (ou d'intégration). + Un exemple serait de confirmer qu'un utilisateur a bien été ajouté + dans une base de données après s'être enregistré sur une site web. +

+

+ La démonstration la plus rapide : l'exemple +

+

+ Supposons que nous sommes en train de tester une simple + classe de log dans un fichier : elle s'appelle + Log dans classes/Log.php. Commençons + par créer un script de test, appelé + tests/log_test.php. Son contenu est le suivant... +

+<?php
+require_once('simpletest/autorun.php');
+require_once('../classes/log.php');
+
+class TestOfLogging extends UnitTestCase {
+}
+?>
+
+ Ici le répertoire simpletest est soit dans le + dossier courant, soit dans les dossiers pour fichiers + inclus. Vous auriez à éditer ces arborescences suivant + l'endroit où vous avez installé SimpleTest. + Le fichier "autorun.php" fait plus que juste inclure + les éléments de SimpleTest : il lance aussi les tests pour nous. +

+

+ TestOfLogging est notre premier scénario de test + et il est pour l'instant vide. + Chaque scénario de test est une classe qui étend une des classes + de base de SimpleTest. Nous pouvons avoir autant de classes de ce type + que nous voulons. +

+

+ Avec ces trois lignes d'échafaudage + l'inclusion de notre classe Log, nous avons une suite + de tests. Mais pas encore de test ! +

+

+ Pour notre premier test, supposons que la classe Log + prenne le nom du fichier à écrire au sein du constructeur, + et que nous avons un répertoire temporaire dans lequel placer + ce fichier. +

+<?php
+require_once('simpletest/autorun.php');
+require_once('../classes/log.php');
+
+class TestOfLogging extends UnitTestCase {
+    function testLogCreatesNewFileOnFirstMessage() {
+        @unlink('/temp/test.log');
+        $log = new Log('/temp/test.log');
+        $this->assertFalse(file_exists('/temp/test.log'));
+        $log->message('Should write this to a file');
+        $this->assertTrue(file_exists('/temp/test.log'));
+    }
+}
+?>
+
+ Au lancement du scénario de test, toutes les méthodes qui + commencent avec la chaîne test sont + identifiées puis exécutées. + Si la méthode commence par test, c'est un test. + Remarquez bien le nom très long de notre exemple : + testLogCreatesNewFileOnFirstMessage(). + C'est bel et bien délibéré : ce style est considéré désirable + et il rend la sortie du test plus lisible. +

+

+ D'ordinaire nous avons bien plusieurs méthodes de tests. + Mais ce sera pour plus tard. +

+

+ Les assertions dans les + méthodes de test envoient des messages vers le framework de + test qui affiche immédiatement le résultat. Cette réponse + immédiate est importante, non seulement lors d'un crash + causé par le code, mais aussi de manière à rapprocher + l'affichage de l'erreur au plus près du scénario de test + concerné via un appel à printcode>. +

+

+ Pour voir ces résultats lançons effectivement les tests. + Aucun autre code n'est nécessaire, il suffit d'ouvrir + la page dans un navigateur. +

+

+ En cas échec, l'affichage ressemble à... +

+

TestOfLogging

+ Fail: testcreatingnewfile->True assertion failed.
+
1/1 test cases complete. + 1 passes and 1 fails.
+
+ ...et si ça passe, on obtient... +
+

TestOfLogging

+
1/1 test cases complete. + 2 passes and 0 fails.
+
+ Et si vous obtenez ça... +
+ Fatal error: Failed opening required '../classes/log.php' (include_path='') in /home/marcus/projects/lastcraft/tutorial_tests/Log/tests/log_test.php on line 7 +
+ c'est qu'il vous manque le fichier classes/Log.php + qui pourrait ressembler à : +
+<?php
+class Log {
+    function Log($file_path) {
+    }
+
+    function message() {
+    }
+}
+?>
+
+ C'est largement plus sympathique d'écrire le code après le test. + Plus que sympatique même - cette technique s'appelle + "Développement Piloté par les Tests" ou + "Test Driven Development" en anglais. +

+

+ Pour plus de renseignements sur le testeur, voyez la + documentation pour les tests de régression. +

+ +

Construire des groupes de tests

+

+ Il est peu probable que dans une véritable application on + ait uniquement besoin de passer un seul scénario de test. + Cela veut dire que nous avons besoin de grouper les + scénarios dans un script de test qui peut, si nécessaire, + lancer tous les tests de l'application. +

+

+ Notre première étape est de créer un nouveau fichier appelé + tests/all_tests.php et d'y inclure le code suivant... +

+<?php
+require_once('simpletest/autorun.php');
+
+class AllTests extends TestSuite {
+    function AllTests() {
+        $this->TestSuite('All tests');
+        $this->addFile('log_test.php');
+    }
+}
+?>
+
+ L'inclusion de "autorun" permettra à notre future suite + de tests d'être lancée juste en invoquant ce script. +

+

+ La sous-classe TestSuite doit chaîner + son constructeur. Cette limitation sera supprimée dans + les versions à venir. +

+

+ The method TestSuite::addFile() + will include the test case file and read any new classes + that are descended from SimpleTestCase. + + Cette méthode TestSuite::addTestFile() va + inclure le fichier de scénarios de test et lire parmi + toutes les nouvelles classes créées celles qui sont issues + de SimpleTestCase. + UnitTestCase est juste un exemple de classe dérivée + depuis SimpleTestCase et vous pouvez créer les vôtres. + TestSuite::addFile() peut aussi inclure d'autres suites. +

+

+ La classe ne sera pas encore instanciée. + Quand la suite de tests est lancée, elle construira chaque instance + une fois le test atteint, et le détuira juste ensuite. + Cela veut dire que le constructeur n'est lancé qu'une fois avant + chaque initialisation de ce scénario de test et que le destructeur + est lui aussi lancé avant que le test suivant ne commence. +

+

+ Il est commun de grouper des scénarios de test dans des super-classes + qui ne sont pas sensées être lancées, mais qui deviennent une classe de base + pour d'autres tests. + Pour que "autorun" fonctionne proprement les fichiers + des scénarios de test ne devraient pas lancer aveuglement + d'autres extensions de scénarios de test qui ne lanceraient pas + effectivement des tests. + Cela pourrait aboutir à un mauvais comptages des scénarios de test + pendant la procédure. + Pas vraiement un problème majeure, mais pour éviter cet inconvénient + il suffit de marquer vos classes de base comme abstract. + SimpleTest ne lance pas les classes abstraites. Et si vous utilisez encore + PHP4 alors une directive SimpleTestOptions::ignore() + dans votre fichier de scénario de test aura le même effet. +

+

+ Par ailleurs, le fichier avec le scénario de test ne devrait pas + avoir été inclus ailleurs. Sinon aucun scénario de test + ne sera inclus à ce groupe. + Ceci pourrait se transformer en un problème plus grave : + si des fichiers ont déjà été inclus par PHP alors la méthode + TestSuite::addFile() ne les détectera pas. +

+

+ Pour afficher les résultats, il est seulement nécessaire + d'invoquer tests/all_tests.php à partir du serveur + web. +

+

+ Pour plus de renseignements des groupes de tests, voyez le + documentation sur le groupement des tests. +

+ +

Utiliser les objets fantaisie

+

+ Avançons un peu plus dans le futur. +

+

+ Supposons que notre class logging soit testée et terminée. + Supposons aussi que nous testons une autre classe qui ait + besoin d'écrire des messages de log, disons + SessionPool. Nous voulons tester une méthode + qui ressemblera probablement à quelque chose comme... +


+class SessionPool {
+    ...
+    function logIn($username) {
+        ...
+        $this->_log->message('User $username logged in.');
+        ...
+    }
+    ...
+}
+
+
+ Avec le concept de "réutilisation de code" comme fil + conducteur, nous utilisons notre class Log. Un + scénario de test classique ressemblera peut-être à... +
+<?php
+require_once('simpletest/autorun.php');
+require_once('../classes/log.php');
+require_once('../classes/session_pool.php');
+
+class TestOfSessionLogging extends UnitTestCase {
+    
+    function setUp() {
+        @unlink('/temp/test.log');
+    }
+    
+    function tearDown() {
+        @unlink('/temp/test.log');
+    }
+    
+    function testLoggingInIsLogged() {
+        $log = new Log('/temp/test.log');
+        $session_pool = &new SessionPool($log);
+        $session_pool->logIn('fred');
+        $messages = file('/temp/test.log');
+        $this->assertEqual($messages[0], "User fred logged in.\n");
+    }
+}
+?>
+
+ Nous expliquerons les méthodes setUp() + et tearDown() plus tard. +

+

+ Le design de ce scénario de test n'est pas complètement + mauvais, mais on peut l'améliorer. Nous passons du temps à + tripoter les fichiers de log qui ne font pas partie de + notre test. + Pire, nous avons créé des liens de proximité + entre la classe Log et ce test. Que se + passerait-il si nous n'utilisions plus de fichiers, mais la + bibliothèque syslog à la place ? + + Cela veut dire que notre test TestOfSessionLogging + enverra un échec alors même qu'il ne teste pas Logging. +

+

+ Il est aussi fragile sur des petites retouches. Avez-vous + remarqué le retour chariot supplémentaire à la fin du + message ? A-t-il été ajouté par le loggueur ? Et si il + ajoutait aussi un timestamp ou d'autres données ? +

+

+ L'unique partie à tester réellement est l'envoi d'un + message précis au loggueur. + Nous pouvons réduire le couplage en + créant une fausse classe de logging : elle ne fait + qu'enregistrer le message pour le test, mais ne produit + aucun résultat. Sauf qu'elle doit ressembler exactement à + l'original. +

+

+ Si l'objet fantaisie n'écrit pas dans un fichier alors nous + nous épargnons la suppression du fichier avant et après le + test. Nous pourrions même nous épargner quelques lignes de + code supplémentaires si l'objet fantaisie pouvait exécuter + l'assertion. +

+

+ Trop beau pour être vrai ? Pas vraiement on peut créer un tel + objet très facilement... +
+<?php
+require_once('simpletest/autorun.php');
+require_once('../classes/log.php');
+require_once('../classes/session_pool.php');
+
+Mock::generate('Log');
+
+class TestOfSessionLogging extends UnitTestCase {
+    
+    function testLoggingInIsLogged() {
+        $log = &new MockLog();
+        $log->expectOnce('message', array('User fred logged in.'));
+        $session_pool = &new SessionPool($log);
+        $session_pool->logIn('fred');
+    }
+}
+?>
+
+ L'appel Mock::generate() a généré + une nouvelle classe appelé MockLog. + Cela ressemble à un clone identique, sauf que nous pouvons + y adjoindre du code de test. + C'est ce que fait expectOnce(). + Cela dit que si message() m'est appelé, + il a intérêt à l'être avec le paramètre + "User fred logged in.". +

+

+ L'appel tally() est nécessaire pour annoncer à + l'objet fantaisie qu'il n'y aura plus d'appels ultérieurs. + Sans ça l'objet fantaisie pourrait attendre pendant une + éternité l'appel de la méthode sans jamais prévenir le + scénario de test. Les autres tests sont déclenchés + automatiquement quand l'appel à message() est + invoqué sur l'objet MockLog par le code + SessionPool::logIn(). + L'appel mock va déclencher une comparaison des + paramètres et ensuite envoyer le message "pass" ou "fail" + au test pour l'affichage. Des jokers peuvent être inclus + pour ne pas avoir à tester tous les paramètres d'un appel + alors que vous ne souhaitez qu'en tester un. +

+

+ Les objets fantaisie dans la suite SimpleTest peuvent avoir + un ensemble de valeurs de sortie arbitraires, des séquences + de sorties, des valeurs de sortie sélectionnées à partir + des arguments d'entrée, des séquences de paramètres + attendus et des limites sur le nombre de fois qu'une + méthode peut être invoquée. +

+

+ Pour que ce test fonctionne la librairie avec les objets + fantaisie doit être incluse dans la suite de tests, par + exemple dans all_tests.php. +

+

+ Pour plus de renseignements sur les objets fantaisie, voyez le + documentation sur les objets fantaisie. +

+ +

Tester une page web

+

+ Une des exigences des sites web, c'est qu'ils produisent + des pages web. Si vous construisez un projet de A à Z et + que vous voulez intégrer des tests au fur et à mesure alors + vous voulez un outil qui puisse effectuer une navigation + automatique et en examiner le résultat. C'est le boulot + d'un testeur web. +

+

+ Effectuer un test web via SimpleTest reste assez primitif : + il n'y a pas de javascript par exemple. + La plupart des autres opérations d'un navigateur sont simulées. +

+

+ Pour vous donner une idée, voici un exemple assez trivial : + aller chercher une page web, + à partir de là naviguer vers la page "about" + et finalement tester un contenu déterminé par le client. +

+<?php
+require_once('simpletest/autorun.php');
+require_once('simpletest/web_tester.php');
+
+class TestOfAbout extends WebTestCase {
+    function testOurAboutPageGivesFreeReignToOurEgo() {
+        $this->get('http://test-server/index.php');
+        $this->click('About');
+        $this->assertTitle('About why we are so great');
+        $this->assertText('We are really great');
+    }
+}
+?>
+
+ Avec ce code comme test de recette, vous pouvez vous + assurer que le contenu corresponde toujours aux + spécifications à la fois des développeurs et des autres + parties prenantes au projet. +

+

+ Vous pouvez aussi naviguer à travers des formulaires... +

+<?php
+require_once('simpletest/autorun.php');
+require_once('simpletest/web_tester.php');
+
+class TestOfRankings extends WebTestCase {
+    function testWeAreTopOfGoogle() {
+        $this->get('http://google.com/');
+        $this->setField('q', 'simpletest');
+        $this->click("I'm Feeling Lucky");
+        $this->assertTitle('SimpleTest - Unit Testing for PHP');
+    }
+}
+?>
+
+ ...même si cela pourrait constituer une violation + des documents juridiques de Google(tm). +

+

+ Pour plus de renseignements sur comment tester une page web, voyez la + documentation sur tester des scripts web. +

+

+ SourceForge.net Logo +

+ +
+ References and related information... + + + + + -- cgit v1.2.3