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

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

Added SimpleTest? test framework

File size: 16.5 KB
Line 
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
4<title>Documentation SimpleTest : étendre le testeur unitaire avec des classes d'attentes supplémentaires</title>
5<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
6</head>
7<body>
8<div class="menu_back"><div class="menu">
9<a href="index.html">SimpleTest</a>
10                |
11                <a href="overview.html">Overview</a>
12                |
13                <a href="unit_test_documentation.html">Unit tester</a>
14                |
15                <a href="group_test_documentation.html">Group tests</a>
16                |
17                <a href="mock_objects_documentation.html">Mock objects</a>
18                |
19                <a href="partial_mocks_documentation.html">Partial mocks</a>
20                |
21                <a href="reporter_documentation.html">Reporting</a>
22                |
23                <a href="expectation_documentation.html">Expectations</a>
24                |
25                <a href="web_tester_documentation.html">Web tester</a>
26                |
27                <a href="form_testing_documentation.html">Testing forms</a>
28                |
29                <a href="authentication_documentation.html">Authentication</a>
30                |
31                <a href="browser_documentation.html">Scriptable browser</a>
32</div></div>
33<h1>Documentation sur les attentes</h1>
34        This page...
35        <ul>
36<li>
37            Utiliser les attentes <a href="#fantaisie">pour des tests
38            plus précis avec des objets fantaisie</a>
39        </li>
40<li>
41            <a href="#comportement">Changer le comportement d'un objet fantaisie</a>
42            avec des attentes
43        </li>
44<li>
45            <a href="#etendre">Créer des attentes</a>
46        </li>
47<li>
48            Par dessous SimpleTest <a href="#unitaire">utilise des classes d'attente</a>
49        </li>
50</ul>
51<div class="content">
52        <p><a class="target" name="fantaisie"><h2>Plus de contrÃŽle sur les objets fantaisie</h2></a></p>
53            <p>
54                Le comportement par défaut des
55                <a href="mock_objects_documentation.html">objets fantaisie</a> dans
56                <a href="http://sourceforge.net/projects/simpletest/">SimpleTest</a>
57                est soit une correspondance identique sur l'argument,
58                soit l'acceptation de n'importe quel argument.
59                Pour la plupart des tests, c'est suffisant.
60                Cependant il est parfois nécessaire de ramollir un scénario de test.
61            </p>
62            <p>
63                Un des endroits où un test peut être trop serré
64                est la reconnaissance textuelle. Prenons l'exemple
65                d'un composant qui produirait un message d'erreur
66                utile lorsque quelque chose plante. Il serait utile de tester
67                que l'erreur correcte est renvoyée,
68                mais le texte proprement dit risque d'être plutÃŽt long.
69                Si vous testez le texte dans son ensemble alors
70                à chaque modification de ce même message
71                -- même un point ou une virgule -- vous aurez
72                à revenir sur la suite de test pour la modifier.
73            </p>
74            <p>
75                Voici un cas concret, nous avons un service d'actualités
76                qui a échoué dans sa tentative de connexion à sa source distante.
77<pre>
78<strong>class NewsService {
79    ...
80    function publish(&amp;$writer) {
81        if (! $this-&gt;isConnected()) {
82            $writer-&gt;write('Cannot connect to news service "' .
83                    $this-&gt;_name . '" at this time. ' .
84                    'Please try again later.');
85        }
86        ...
87    }
88}</strong>
89</pre>
90                Là il envoie son contenu vers un classe <span class="new_code">Writer</span>.
91                Nous pourrions tester ce comportement avec un <span class="new_code">MockWriter</span>...
92<pre>
93class TestOfNewsService extends UnitTestCase {
94    ...
95    function testConnectionFailure() {<strong>
96        $writer = &amp;new MockWriter($this);
97        $writer-&gt;expectOnce('write', array(
98                'Cannot connect to news service ' .
99                '"BBC News" at this time. ' .
100                'Please try again later.'));
101       
102        $service = &amp;new NewsService('BBC News');
103        $service-&gt;publish($writer);
104       
105        $writer-&gt;tally();</strong>
106    }
107}
108</pre>
109                C'est un bon exemple d'un test fragile.
110                Si nous décidons d'ajouter des instructions complémentaires,
111                par exemple proposer une source d'actualités alternative,
112                nous casserons nos tests par la même occasion sans pourtant
113                avoir modifié une seule fonctionnalité.
114            </p>
115            <p>
116                Pour contourner ce problÚme, nous voudrions utiliser
117                un test avec une expression rationnelle plutÃŽt
118                qu'une correspondance exacte. Nous pouvons y parvenir avec...
119<pre>
120class TestOfNewsService extends UnitTestCase {
121    ...
122    function testConnectionFailure() {
123        $writer = &amp;new MockWriter($this);<strong>
124        $writer-&gt;expectOnce(
125                'write',
126                array(new WantedPatternExpectation('/cannot connect/i')));</strong>
127       
128        $service = &amp;new NewsService('BBC News');
129        $service-&gt;publish($writer);
130       
131        $writer-&gt;tally();
132    }
133}
134</pre>
135                PlutÃŽt que de transmettre le paramÚtre attendu au <span class="new_code">MockWriter</span>,
136                nous envoyons une classe d'attente appelée <span class="new_code">WantedPatternExpectation</span>.
137                L'objet fantaisie est suffisamment élégant pour reconnaître
138                qu'il s'agit d'un truc spécial et pour le traiter différemment.
139                PlutÃŽt que de comparer l'argument entrant à cet objet,
140                il utilise l'objet attente lui-même pour exécuter le test.
141            </p>
142            <p>
143                <span class="new_code">WantedPatternExpectation</span> utilise
144                l'expression rationnelle pour la comparaison avec son constructeur.
145                A chaque fois qu'une comparaison est fait à travers
146                <span class="new_code">MockWriter</span> par rapport à cette classe attente,
147                elle fera un <span class="new_code">preg_match()</span> avec ce motif.
148                Dans notre scénario de test ci-dessus, aussi longtemps
149                que la chaîne "cannot connect" apparaît dans le texte,
150                la fantaisie transmettra un succÚs au testeur unitaire.
151                Peu importe le reste du texte.
152            </p>
153            <p>
154                Les classes attente possibles sont...
155                <table><tbody>
156                    <tr>
157<td><span class="new_code">EqualExpectation</span></td>
158<td>Une égalité, plutÎt que la plus forte comparaison à l'identique</td>
159</tr>
160                    <tr>
161<td><span class="new_code">NotEqualExpectation</span></td>
162<td>Une comparaison sur la non-égalité</td>
163</tr>
164                    <tr>
165<td><span class="new_code">IndenticalExpectation</span></td>
166<td>La vérification par défaut de l'objet fantaisie qui doit correspondre exactement</td>
167</tr>
168                    <tr>
169<td><span class="new_code">NotIndenticalExpectation</span></td>
170<td>Inverse la logique de l'objet fantaisie</td>
171</tr>
172                    <tr>
173<td><span class="new_code">WantedPatternExpectation</span></td>
174<td>Utilise une expression rationnelle Perl pour comparer une chaîne</td>
175</tr>
176                    <tr>
177<td><span class="new_code">NoUnwantedPatternExpectation</span></td>
178<td>Passe seulement si l'expression rationnelle Perl échoue</td>
179</tr>
180                    <tr>
181<td><span class="new_code">IsAExpectation</span></td>
182<td>Vérifie le type ou le nom de la classe uniquement</td>
183</tr>
184                    <tr>
185<td><span class="new_code">NotAExpectation</span></td>
186<td>L'opposé de <span class="new_code">IsAExpectation</span>
187</td>
188</tr>
189                    <tr>
190<td><span class="new_code">MethodExistsExpectation</span></td>
191<td>Vérifie si la méthode est disponible sur un objet</td>
192</tr>
193                </tbody></table>
194                La plupart utilisent la valeur attendue dans le constructeur.
195                Les exceptions sont les vérifications sur motif,
196                qui utilisent une expression rationnelle, ainsi que
197                <span class="new_code">IsAExpectation</span> et <span class="new_code">NotAExpectation</span>,
198                qui prennent un type ou un nom de classe comme chaîne.
199            </p>
200       
201        <p><a class="target" name="comportement"><h2>Utiliser les attentes pour contrÃŽler les bouchons serveur</h2></a></p>
202            <p>
203                Les classes attente peuvent servir à autre chose
204                que l'envoi d'assertions depuis les objets fantaisie,
205                afin de choisir le comportement d'un
206                <a href="mock_objects_documentation.html">objet fantaisie</a>
207                ou celui d'un <a href="server_stubs_documentation.html">bouchon serveur</a>.
208                A chaque fois qu'une liste d'arguments est donnée,
209                une liste d'objets d'attente peut être insérée à la place.
210            </p>
211            <p>
212                Mettons que nous voulons qu'un bouchon serveur
213                d'autorisation simule une connexion réussie seulement
214                si il reçoit un objet de session valide.
215                Nous pouvons y arriver avec ce qui suit...
216<pre>
217Stub::generate('Authorisation');
218<strong>
219$authorisation = new StubAuthorisation();
220$authorisation-&gt;setReturnValue(
221        'isAllowed',
222        true,
223        array(new IsAExpectation('Session', 'Must be a session')));
224$authorisation-&gt;setReturnValue('isAllowed', false);</strong>
225</pre>
226                Le comportement par défaut du bouchon serveur
227                est défini pour renvoyer <span class="new_code">false</span>
228                quand <span class="new_code">isAllowed</span> est appelé.
229                Lorsque nous appelons cette méthode avec un unique paramÚtre
230                qui est un objet <span class="new_code">Session</span>, il renverra <span class="new_code">true</span>.
231                Nous avons aussi ajouté un deuxiÚme paramÚtre comme message.
232                Il sera affiché dans le message d'erreur de l'objet fantaisie
233                si l'attente est la cause de l'échec.
234            </p>
235            <p>
236                Ce niveau de sophistication est rarement utile :
237                il n'est inclut que pour être complet.
238            </p>
239       
240        <p><a class="target" name="etendre"><h2>Créer vos propres attentes</h2></a></p>
241            <p>
242                Les classes d'attentes ont une structure trÚs simple.
243                Tellement simple qu'il devient trÚs simple de créer
244                vos propres version de logique pour des tests utilisés couramment.
245            </p>
246            <p>
247                Par exemple voici la création d'une classe pour tester
248                la validité d'adresses IP. Pour fonctionner correctement
249                avec les bouchons serveurs et les objets fantaisie,
250                cette nouvelle classe d'attente devrait étendre
251                <span class="new_code">SimpleExpectation</span>...
252<pre>
253<strong>class ValidIp extends SimpleExpectation {
254   
255    function test($ip) {
256        return (ip2long($ip) != -1);
257    }
258   
259    function testMessage($ip) {
260        return "Address [$ip] should be a valid IP address";
261    }
262}</strong>
263</pre> 
264               Il n'y a véritablement que deux méthodes à mettre en place.
265               La méthode <span class="new_code">test()</span> devrait renvoyer un <span class="new_code">true</span>
266               si l'attente doit passer, et une erreur <span class="new_code">false</span>
267               dans le cas contraire. La méthode <span class="new_code">testMessage()</span>
268               ne devrait renvoyer que du texte utile à la compréhension du test en lui-même.
269            </p>
270            <p>
271                Cette classe peut désormais être employée à la place
272                des classes d'attente précédentes.
273            </p>
274       
275        <p><a class="target" name="unitaire"><h2>Sous le capot du testeur unitaire</h2></a></p>
276            <p>
277                Le <a href="http://sourceforge.net/projects/simpletest/">framework
278                de test unitaire SimpleTest</a> utilise aussi dans son coeur
279                des classes d'attente pour
280                la <a href="unit_test_documentation.html">classe UnitTestCase</a>.
281                Nous pouvons aussi tirer parti de ces mécanismes pour réutiliser
282                nos propres classes attente à l'intérieur même des suites de test.
283            </p>
284            <p>
285                La méthode la plus directe est d'utiliser la méthode
286                <span class="new_code">SimpleTest::assertExpectation()</span> pour effectuer le test...
287<pre>
288<strong>class TestOfNetworking extends UnitTestCase {
289    ...
290    function testGetValidIp() {
291        $server = &amp;new Server();
292        $this-&gt;assertExpectation(
293                new ValidIp(),
294                $server-&gt;getIp(),
295                'Server IP address-&gt;%s');
296    }
297}</strong>
298</pre>
299                C'est plutÃŽt sale par rapport à notre syntaxe habituelle
300                du type <span class="new_code">assert...()</span>.
301            </p>
302            <p>
303                Pour un cas aussi simple, nous créons d'ordinaire une méthode
304                d'assertion distincte en utilisant la classe d'attente.
305                Supposons un instant que notre attente soit un peu plus
306                compliquée et que par conséquent nous souhaitions la réutiliser,
307                nous obtenons...
308<pre>
309class TestOfNetworking extends UnitTestCase {
310    ...<strong>
311    function assertValidIp($ip, $message = '%s') {
312        $this-&gt;assertExpectation(new ValidIp(), $ip, $message);
313    }</strong>
314   
315    function testGetValidIp() {
316        $server = &amp;new Server();<strong>
317        $this-&gt;assertValidIp(
318                $server-&gt;getIp(),
319                'Server IP address-&gt;%s');</strong>
320    }
321}
322</pre>
323                Il est peu probable que nous ayons besoin
324                de ce niveau de contrÃŽle sur la machinerie de test.
325                Il est assez rare que le besoin d'une attente dépasse
326                le stade de la reconnaissance d'un motif.
327                De plus, les classes d'attente complexes peuvent rendre
328                les tests difficiles à lire et à déboguer.
329                Ces mécanismes sont véritablement là pour les auteurs
330                de systÚme qui étendront le framework de test
331                pour leurs propres outils de test.
332            </p>
333       
334    </div>
335        References and related information...
336        <ul>
337<li>
338            La page du projet SimpleTest sur
339            <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
340        </li>
341<li>
342            La page de téléchargement de SimpleTest sur
343            <a href="http://www.lastcraft.com/simple_test.php">LastCraft</a>.
344        </li>
345<li>
346            Les attentes imitent les contraintes dans
347            <a href="http://www.jmock.org/">JMock</a>.
348        </li>
349<li>
350            <a href="http://simpletest.org/api/">L'API complÚte pour SimpleTest</a>
351            réalisé avec PHPDoc.
352        </li>
353</ul>
354<div class="menu_back"><div class="menu">
355<a href="index.html">SimpleTest</a>
356                |
357                <a href="overview.html">Overview</a>
358                |
359                <a href="unit_test_documentation.html">Unit tester</a>
360                |
361                <a href="group_test_documentation.html">Group tests</a>
362                |
363                <a href="mock_objects_documentation.html">Mock objects</a>
364                |
365                <a href="partial_mocks_documentation.html">Partial mocks</a>
366                |
367                <a href="reporter_documentation.html">Reporting</a>
368                |
369                <a href="expectation_documentation.html">Expectations</a>
370                |
371                <a href="web_tester_documentation.html">Web tester</a>
372                |
373                <a href="form_testing_documentation.html">Testing forms</a>
374                |
375                <a href="authentication_documentation.html">Authentication</a>
376                |
377                <a href="browser_documentation.html">Scriptable browser</a>
378</div></div>
379<div class="copyright">
380            Copyright<br>Marcus Baker 2006
381        </div>
382</body>
383</html>
Note: See TracBrowser for help on using the repository browser.