source: trunk/server/www/vendors/simpletest/docs/fr/index.html @ 6

Last change on this file since 6 was 6, checked in by sander, 12 years ago

Added SimpleTest? test framework

File size: 26.3 KB
Line 
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
4<title>
5        Prise en main rapide de SimpleTest pour PHP -
6        Tests unitaire et objets fantaisie pour PHP
7    </title>
8<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
9</head>
10<body>
11<div class="menu_back"><div class="menu">
12<a href="index.html">SimpleTest</a>
13                |
14                <a href="overview.html">Overview</a>
15                |
16                <a href="unit_test_documentation.html">Unit tester</a>
17                |
18                <a href="group_test_documentation.html">Group tests</a>
19                |
20                <a href="mock_objects_documentation.html">Mock objects</a>
21                |
22                <a href="partial_mocks_documentation.html">Partial mocks</a>
23                |
24                <a href="reporter_documentation.html">Reporting</a>
25                |
26                <a href="expectation_documentation.html">Expectations</a>
27                |
28                <a href="web_tester_documentation.html">Web tester</a>
29                |
30                <a href="form_testing_documentation.html">Testing forms</a>
31                |
32                <a href="authentication_documentation.html">Authentication</a>
33                |
34                <a href="browser_documentation.html">Scriptable browser</a>
35</div></div>
36<h1>Prise en main rapide de SimpleTest</h1>
37        This page...
38        <ul>
39<li>
40            <a href="#unit">Utiliser le testeur rapidement</a>
41            avec un exemple.
42        </li>
43<li>
44            <a href="#group">Groupes de tests</a>
45            pour tester en un seul clic.
46        </li>
47<li>
48            <a href="#mock">Utiliser les objets fantaisie</a>
49            pour faciliter les tests et gagner en contrÃŽle.
50        </li>
51<li>
52            <a href="#web">Tester des pages web</a>
53            au niveau de l'HTML.
54        </li>
55</ul>
56<div class="content">
57       
58            <p>
59                Le présent article présuppose que vous soyez familier avec
60                le concept de tests unitaires ainsi que celui de développement
61                web avec le langage PHP. Il s'agit d'un guide pour le nouvel
62                et impatient utilisateur de
63                <a href="https://sourceforge.net/project/showfiles.php?group_id=76550">SimpleTest</a>.
64                Pour une documentation plus complÚte, particuliÚrement si
65                vous découvrez les tests unitaires, consultez la
66                <a href="http://www.lastcraft.com/unit_test_documentation.php">documentation
67                en cours</a>, et pour des exemples de scénarios de test,
68                consultez le
69                <a href="http://www.lastcraft.com/first_test_tutorial.php">tutorial
70                sur les tests unitaires</a>.
71            </p>
72       
73        <p><a class="target" name="unit"><h2>Utiliser le testeur rapidement</h2></a></p>
74            <p>
75                Parmi les outils de test pour logiciel, le testeur unitaire
76                est le plus proche du développeur. Dans un contexte de
77                développement agile, le code de test se place juste à cÃŽté
78                du code source étant donné que tous les deux sont écrits
79                simultanément. Dans ce contexte, SimpleTest aspire à être
80                une solution complÚte de test pour un développeur PHP et
81                s'appelle "Simple" parce qu'elle devrait être simple à
82                utiliser et à étendre. Ce nom n'était pas vraiment un bon
83                choix. Non seulement cette solution inclut toutes les
84                fonctions classiques qu'on est en droit d'attendre de la
85                part des portages de <a href="http://www.junit.org/">JUnit</a> et des <a href="http://sourceforge.net/projects/phpunit/">PHPUnit</a>,
86                mais elle inclut aussi les <a href="http://www.mockobjects.com/">objets fantaisie ou
87                "mock objects"</a>.
88            </p>
89            <p>
90                Ce qui rend cet outil immédiatement utile pour un développeur PHP,
91                c'est son navigateur web interne.
92                Il permet des tests qui parcourent des sites web, remplissent
93                des formulaires et testent le contenu des pages.
94                Etre capable d'écrire ces tests en PHP veut dire qu'il devient
95                facile d'écrire des tests de recette (ou d'intégration).
96                Un exemple serait de confirmer qu'un utilisateur a bien été ajouté
97                dans une base de données aprÚs s'être enregistré sur une site web.
98            </p>
99            <p>
100                La démonstration la plus rapide : l'exemple
101            </p>
102            <p>
103                Supposons que nous sommes en train de tester une simple
104                classe de log dans un fichier : elle s'appelle
105                <span class="new_code">Log</span> dans <em>classes/Log.php</em>. Commençons
106                par créer un script de test, appelé
107                <em>tests/log_test.php</em>. Son contenu est le suivant...
108<pre>
109&lt;?php
110<strong>require_once('simpletest/autorun.php');</strong>
111require_once('../classes/log.php');
112
113class TestOfLogging extends <strong>UnitTestCase</strong> {
114}
115?&gt;
116</pre>
117                Ici le répertoire <em>simpletest</em> est soit dans le
118                dossier courant, soit dans les dossiers pour fichiers
119                inclus. Vous auriez à éditer ces arborescences suivant
120                l'endroit où vous avez installé SimpleTest.
121                Le fichier "autorun.php" fait plus que juste inclure
122                les éléments de SimpleTest : il lance aussi les tests pour nous. 
123            </p>
124            <p>
125                <span class="new_code">TestOfLogging</span> est notre premier scénario de test
126                et il est pour l'instant vide.
127                Chaque scénario de test est une classe qui étend une des classes
128                de base de SimpleTest. Nous pouvons avoir autant de classes de ce type
129                que nous voulons.
130            </p>
131            <p>
132                Avec ces trois lignes d'échafaudage
133                l'inclusion de notre classe <span class="new_code">Log</span>, nous avons une suite
134                de tests. Mais pas encore de test !
135            </p>
136            <p>
137                Pour notre premier test, supposons que la classe <span class="new_code">Log</span>
138                prenne le nom du fichier à écrire au sein du constructeur,
139                et que nous avons un répertoire temporaire dans lequel placer
140                ce fichier.
141<pre>
142&lt;?php
143require_once('simpletest/autorun.php');
144require_once('../classes/log.php');
145
146class TestOfLogging extends UnitTestCase {
147    function <strong>testLogCreatesNewFileOnFirstMessage()</strong> {
148        @unlink('/temp/test.log');
149        $log = new Log('/temp/test.log');
150        <strong>$this-&gt;assertFalse(file_exists('/temp/test.log'));</strong>
151        $log-&gt;message('Should write this to a file');
152        <strong>$this-&gt;assertTrue(file_exists('/temp/test.log'));</strong>
153    }
154}
155?&gt;
156</pre>
157                Au lancement du scénario de test, toutes les méthodes qui
158                commencent avec la chaîne <span class="new_code">test</span> sont
159                identifiées puis exécutées.
160                Si la méthode commence par <span class="new_code">test</span>, c'est un test.
161                Remarquez bien le nom trÚs long de notre exemple :
162                <span class="new_code">testLogCreatesNewFileOnFirstMessage()</span>.
163                C'est bel et bien délibéré : ce style est considéré désirable
164                et il rend la sortie du test plus lisible.
165            </p>
166            <p>
167                D'ordinaire nous avons bien plusieurs méthodes de tests.
168                Mais ce sera pour plus tard.
169            </p>
170            <p>
171                Les assertions dans les
172                méthodes de test envoient des messages vers le framework de
173                test qui affiche immédiatement le résultat. Cette réponse
174                immédiate est importante, non seulement lors d'un crash
175                causé par le code, mais aussi de maniÚre à rapprocher
176                l'affichage de l'erreur au plus prÚs du scénario de test
177                concerné via un appel à <span class="new_code">print</span>code&gt;.
178            </p>
179            <p>
180                Pour voir ces résultats lançons effectivement les tests.
181                Aucun autre code n'est nécessaire, il suffit d'ouvrir
182                la page dans un navigateur.
183            </p>
184            <p>
185                En cas échec, l'affichage ressemble à...
186                <div class="demo">
187                    <h1>TestOfLogging</h1>
188                    <span class="fail">Fail</span>: testcreatingnewfile-&gt;True assertion failed.<br>
189                    <div style="padding: 8px; margin-top: 1em; background-color: red; color: white;">1/1 test cases complete.
190                    <strong>1</strong> passes and <strong>1</strong> fails.</div>
191                </div>
192                ...et si ça passe, on obtient...
193                <div class="demo">
194                    <h1>TestOfLogging</h1>
195                    <div style="padding: 8px; margin-top: 1em; background-color: green; color: white;">1/1 test cases complete.
196                    <strong>2</strong> passes and <strong>0</strong> fails.</div>
197                </div>
198                Et si vous obtenez ça...
199                <div class="demo">
200                    <b>Fatal error</b>:  Failed opening required '../classes/log.php' (include_path='') in <b>/home/marcus/projects/lastcraft/tutorial_tests/Log/tests/log_test.php</b> on line <b>7</b>
201                </div>
202                c'est qu'il vous manque le fichier <em>classes/Log.php</em>
203                qui pourrait ressembler à :
204<pre>
205&lt;?php<strong>
206class Log {
207    function Log($file_path) {
208    }
209
210    function message() {
211    }
212}</strong>
213?&gt;
214</pre>
215                C'est largement plus sympathique d'écrire le code aprÚs le test.
216                Plus que sympatique même - cette technique s'appelle
217                "Développement Piloté par les Tests" ou
218                "Test Driven Development" en anglais.
219            </p>
220            <p>
221                Pour plus de renseignements sur le testeur, voyez la
222                <a href="unit_test_documentation.html">documentation pour les tests de régression</a>.
223            </p>
224       
225        <p><a class="target" name="group"><h2>Construire des groupes de tests</h2></a></p>
226            <p>
227                Il est peu probable que dans une véritable application on
228                ait uniquement besoin de passer un seul scénario de test.
229                Cela veut dire que nous avons besoin de grouper les
230                scénarios dans un script de test qui peut, si nécessaire,
231                lancer tous les tests de l'application.
232            </p>
233            <p>
234                Notre premiÚre étape est de créer un nouveau fichier appelé
235                <em>tests/all_tests.php</em> et d'y inclure le code suivant...
236<pre>
237&lt;?php
238<strong>require_once('simpletest/autorun.php');</strong>
239
240class AllTests extends <strong>TestSuite</strong> {
241    function AllTests() {
242        $this-&gt;TestSuite(<strong>'All tests'</strong>);
243        <strong>$this-&gt;addFile('log_test.php');</strong>
244    }
245}
246?&gt;
247</pre>
248                L'inclusion de "autorun" permettra à notre future suite
249                de tests d'être lancée juste en invoquant ce script.
250            </p>
251            <p>
252                La sous-classe <span class="new_code">TestSuite</span> doit chaîner
253                son constructeur. Cette limitation sera supprimée dans
254                les versions à venir.   
255            </p>
256            <p>
257                The method <span class="new_code">TestSuite::addFile()</span>
258                will include the test case file and read any new classes
259                that are descended from <span class="new_code">SimpleTestCase</span>.
260
261                Cette méthode <span class="new_code">TestSuite::addTestFile()</span> va
262                inclure le fichier de scénarios de test et lire parmi
263                toutes les nouvelles classes créées celles qui sont issues
264                de <span class="new_code">SimpleTestCase</span>.
265                <span class="new_code">UnitTestCase</span> est juste un exemple de classe dérivée
266                depuis <span class="new_code">SimpleTestCase</span> et vous pouvez créer les vÃŽtres.
267                <span class="new_code">TestSuite::addFile()</span> peut aussi inclure d'autres suites.
268            </p>
269            <p>
270                La classe ne sera pas encore instanciée.
271                Quand la suite de tests est lancée, elle construira chaque instance
272                une fois le test atteint, et le détuira juste ensuite.
273                Cela veut dire que le constructeur n'est lancé qu'une fois avant
274                chaque initialisation de ce scénario de test et que le destructeur
275                est lui aussi lancé avant que le test suivant ne commence.
276            </p>
277            <p>
278                Il est commun de grouper des scénarios de test dans des super-classes
279                qui ne sont pas sensées être lancées, mais qui deviennent une classe de base
280                pour d'autres tests.
281                Pour que "autorun" fonctionne proprement les fichiers
282                des scénarios de test ne devraient pas lancer aveuglement
283                d'autres extensions de scénarios de test qui ne lanceraient pas
284                effectivement des tests.
285                Cela pourrait aboutir à un mauvais comptages des scénarios de test
286                pendant la procédure.
287                Pas vraiement un problÚme majeure, mais pour éviter cet inconvénient
288                il suffit de marquer vos classes de base comme <span class="new_code">abstract</span>.
289                SimpleTest ne lance pas les classes abstraites. Et si vous utilisez encore
290                PHP4 alors une directive <span class="new_code">SimpleTestOptions::ignore()</span>
291                dans votre fichier de scénario de test aura le même effet.
292            </p>
293            <p>
294                Par ailleurs, le fichier avec le scénario de test ne devrait pas
295                avoir été inclus ailleurs. Sinon aucun scénario de test
296                ne sera inclus à ce groupe.
297                Ceci pourrait se transformer en un problÚme plus grave :
298                si des fichiers ont déjà été inclus par PHP alors la méthode
299                <span class="new_code">TestSuite::addFile()</span> ne les détectera pas.
300            </p>
301            <p>
302                Pour afficher les résultats, il est seulement nécessaire
303                d'invoquer <em>tests/all_tests.php</em> Ã  partir du serveur
304                web.
305            </p>
306            <p>
307                Pour plus de renseignements des groupes de tests, voyez le
308                <a href="group_test_documentation.html">documentation sur le groupement des tests</a>.
309            </p>
310       
311        <p><a class="target" name="mock"><h2>Utiliser les objets fantaisie</h2></a></p>
312            <p>
313                Avançons un peu plus dans le futur.
314            </p>
315            <p>
316                Supposons que notre class logging soit testée et terminée.
317                Supposons aussi que nous testons une autre classe qui ait
318                besoin d'écrire des messages de log, disons
319                <span class="new_code">SessionPool</span>. Nous voulons tester une méthode
320                qui ressemblera probablement à quelque chose comme...
321<pre><strong>
322class SessionPool {
323    ...
324    function logIn($username) {
325        ...
326        $this-&gt;_log-&gt;message('User $username logged in.');
327        ...
328    }
329    ...
330}
331</strong>
332</pre>
333                Avec le concept de "réutilisation de code" comme fil
334                conducteur, nous utilisons notre class <span class="new_code">Log</span>. Un
335                scénario de test classique ressemblera peut-être à...
336<pre>
337&lt;?php
338require_once('simpletest/autorun.php');
339require_once('../classes/log.php');
340<strong>require_once('../classes/session_pool.php');</strong>
341
342class <strong>TestOfSessionLogging</strong> extends UnitTestCase {
343   
344    function setUp() {
345        <strong>@unlink('/temp/test.log');</strong>
346    }
347   
348    function tearDown() {
349        <strong>@unlink('/temp/test.log');</strong>
350    }
351   
352    function testLoggingInIsLogged() {
353        <strong>$log = new Log('/temp/test.log');
354        $session_pool = &amp;new SessionPool($log);
355        $session_pool-&gt;logIn('fred');</strong>
356        $messages = file('/temp/test.log');
357        $this-&gt;assertEqual($messages[0], "User fred logged in.<strong>\n</strong>");
358    }
359}
360?&gt;
361</pre>
362                Nous expliquerons les méthodes <span class="new_code">setUp()</span>
363                et <span class="new_code">tearDown()</span> plus tard.
364            </p>
365            <p>
366                Le design de ce scénario de test n'est pas complÚtement
367                mauvais, mais on peut l'améliorer. Nous passons du temps à
368                tripoter les fichiers de log qui ne font pas partie de
369                notre test.
370                Pire, nous avons créé des liens de proximité
371                entre la classe <span class="new_code">Log</span> et ce test. Que se
372                passerait-il si nous n'utilisions plus de fichiers, mais la
373                bibliothÚque <em>syslog</em> Ã  la place ?
374               
375                Cela veut dire que notre test <span class="new_code">TestOfSessionLogging</span>
376                enverra un échec alors même qu'il ne teste pas Logging.
377            </p>
378            <p>
379                Il est aussi fragile sur des petites retouches. Avez-vous
380                remarqué le retour chariot supplémentaire à la fin du
381                message ? A-t-il été ajouté par le loggueur ? Et si il
382                ajoutait aussi un timestamp ou d'autres données ?
383            </p>
384            <p>
385                L'unique partie à tester réellement est l'envoi d'un
386                message précis au loggueur.
387                Nous pouvons réduire le couplage en
388                créant une fausse classe de logging : elle ne fait
389                qu'enregistrer le message pour le test, mais ne produit
390                aucun résultat. Sauf qu'elle doit ressembler exactement à
391                l'original.
392            </p>
393            <p>
394                Si l'objet fantaisie n'écrit pas dans un fichier alors nous
395                nous épargnons la suppression du fichier avant et aprÚs le
396                test. Nous pourrions même nous épargner quelques lignes de
397                code supplémentaires si l'objet fantaisie pouvait exécuter
398                l'assertion.
399            <p>
400            </p>
401                Trop beau pour être vrai ? Pas vraiement on peut créer un tel
402                objet trÚs facilement...
403<pre>
404&lt;?php
405require_once('simpletest/autorun.php');
406require_once('../classes/log.php');
407require_once('../classes/session_pool.php');
408
409<strong>Mock::generate('Log');</strong>
410
411class TestOfSessionLogging extends UnitTestCase {
412   
413    function testLoggingInIsLogged() {<strong>
414        $log = &amp;new MockLog();
415        $log-&gt;expectOnce('message', array('User fred logged in.'));</strong>
416        $session_pool = &amp;new SessionPool(<strong>$log</strong>);
417        $session_pool-&gt;logIn('fred');
418    }
419}
420?&gt;
421</pre>
422                L'appel <span class="new_code">Mock::generate()</span> a généré
423                une nouvelle classe appelé <span class="new_code">MockLog</span>.
424                Cela ressemble à un clone identique, sauf que nous pouvons
425                y adjoindre du code de test.
426                C'est ce que fait <span class="new_code">expectOnce()</span>.
427                Cela dit que si <span class="new_code">message()</span> m'est appelé,
428                il a intérêt à l'être avec le paramÚtre
429                "User fred logged in.".
430            </p>
431            <p>
432                L'appel <span class="new_code">tally()</span> est nécessaire pour annoncer à
433                l'objet fantaisie qu'il n'y aura plus d'appels ultérieurs.
434                Sans ça l'objet fantaisie pourrait attendre pendant une
435                éternité l'appel de la méthode sans jamais prévenir le
436                scénario de test. Les autres tests sont déclenchés
437                automatiquement quand l'appel à <span class="new_code">message()</span> est
438                invoqué sur l'objet <span class="new_code">MockLog</span> par le code
439                <span class="new_code">SessionPool::logIn()</span>.
440                L'appel <span class="new_code">mock</span> va déclencher une comparaison des
441                paramÚtres et ensuite envoyer le message "pass" ou "fail"
442                au test pour l'affichage. Des jokers peuvent être inclus
443                pour ne pas avoir à tester tous les paramÚtres d'un appel
444                alors que vous ne souhaitez qu'en tester un.
445            </p>
446            <p>
447                Les objets fantaisie dans la suite SimpleTest peuvent avoir
448                un ensemble de valeurs de sortie arbitraires, des séquences
449                de sorties, des valeurs de sortie sélectionnées à partir
450                des arguments d'entrée, des séquences de paramÚtres
451                attendus et des limites sur le nombre de fois qu'une
452                méthode peut être invoquée.
453            </p>
454            <p>
455                Pour que ce test fonctionne la librairie avec les objets
456                fantaisie doit être incluse dans la suite de tests, par
457                exemple dans <em>all_tests.php</em>.
458            </p>
459            <p>
460                Pour plus de renseignements sur les objets fantaisie, voyez le
461                <a href="mock_objects_documentation.html">documentation sur les objets fantaisie</a>.
462            </p>
463       
464        <p><a class="target" name="web"><h2>Tester une page web</h2></a></p>
465            <p>
466                Une des exigences des sites web, c'est qu'ils produisent
467                des pages web. Si vous construisez un projet de A à Z et
468                que vous voulez intégrer des tests au fur et à mesure alors
469                vous voulez un outil qui puisse effectuer une navigation
470                automatique et en examiner le résultat. C'est le boulot
471                d'un testeur web.
472            </p>
473            <p>
474                Effectuer un test web via SimpleTest reste assez primitif :
475                il n'y a pas de javascript par exemple.
476                La plupart des autres opérations d'un navigateur sont simulées.
477            </p>
478            <p>
479                Pour vous donner une idée, voici un exemple assez trivial :
480                aller chercher une page web,
481                à partir de là naviguer vers la page "about"
482                et finalement tester un contenu déterminé par le client.
483<pre>
484&lt;?php
485require_once('simpletest/autorun.php');
486<strong>require_once('simpletest/web_tester.php');</strong>
487
488class TestOfAbout extends <strong>WebTestCase</strong> {
489    function testOurAboutPageGivesFreeReignToOurEgo() {
490        <strong>$this-&gt;get('http://test-server/index.php');
491        $this-&gt;click('About');
492        $this-&gt;assertTitle('About why we are so great');
493        $this-&gt;assertText('We are really great');</strong>
494    }
495}
496?&gt;
497</pre>
498                Avec ce code comme test de recette, vous pouvez vous
499                assurer que le contenu corresponde toujours aux
500                spécifications à la fois des développeurs et des autres
501                parties prenantes au projet.
502            </p>
503            <p>
504                Vous pouvez aussi naviguer à travers des formulaires...
505<pre>
506&lt;?php
507require_once('simpletest/autorun.php');
508require_once('simpletest/web_tester.php');
509
510class TestOfRankings extends WebTestCase {
511    function testWeAreTopOfGoogle() {
512        $this-&gt;get('http://google.com/');
513        $this-&gt;setField('q', 'simpletest');
514        $this-&gt;click("I'm Feeling Lucky");
515        $this-&gt;assertTitle('SimpleTest - Unit Testing for PHP');
516    }
517}
518?&gt;
519</pre>
520                ...même si cela pourrait constituer une violation
521                des documents juridiques de Google(tm).
522            </p>
523            <p>
524                Pour plus de renseignements sur comment tester une page web, voyez la
525                <a href="web_tester_documentation.html">documentation sur tester des scripts web</a>.
526            </p>
527            <p>
528                <a href="http://sourceforge.net/projects/simpletest/"><img src="http://sourceforge.net/sflogo.php?group_id=76550&amp;type=5" width="210" height="62" border="0" alt="SourceForge.net Logo"></a>
529            </p>
530       
531    </div>
532        References and related information...
533        <ul>
534<li>
535            <a href="https://sourceforge.net/project/showfiles.php?group_id=76550&amp;release_id=153280">Télécharger PHP Simple Test</a>
536            depuis <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
537        </li>
538<li>
539            L'<a href="http://simpletest.org/api/">API de SimpleTest pour développeur</a>
540            donne tous les détails sur les classes et assertions existantes.
541        </li>
542</ul>
543<div class="menu_back"><div class="menu">
544<a href="index.html">SimpleTest</a>
545                |
546                <a href="overview.html">Overview</a>
547                |
548                <a href="unit_test_documentation.html">Unit tester</a>
549                |
550                <a href="group_test_documentation.html">Group tests</a>
551                |
552                <a href="mock_objects_documentation.html">Mock objects</a>
553                |
554                <a href="partial_mocks_documentation.html">Partial mocks</a>
555                |
556                <a href="reporter_documentation.html">Reporting</a>
557                |
558                <a href="expectation_documentation.html">Expectations</a>
559                |
560                <a href="web_tester_documentation.html">Web tester</a>
561                |
562                <a href="form_testing_documentation.html">Testing forms</a>
563                |
564                <a href="authentication_documentation.html">Authentication</a>
565                |
566                <a href="browser_documentation.html">Scriptable browser</a>
567</div></div>
568<div class="copyright">
569            Copyright<br>Marcus Baker 2006
570        </div>
571</body>
572</html>
Note: See TracBrowser for help on using the repository browser.