index.html 26 KB

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