571 lines
23 KiB
HTML
571 lines
23 KiB
HTML
<html>
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
<title>Documentation SimpleTest : tester des scripts web</title>
|
|
<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
|
|
</head>
|
|
<body>
|
|
<div class="menu_back"><div class="menu">
|
|
<a href="index.html">SimpleTest</a>
|
|
|
|
|
<a href="overview.html">Overview</a>
|
|
|
|
|
<a href="unit_test_documentation.html">Unit tester</a>
|
|
|
|
|
<a href="group_test_documentation.html">Group tests</a>
|
|
|
|
|
<a href="mock_objects_documentation.html">Mock objects</a>
|
|
|
|
|
<a href="partial_mocks_documentation.html">Partial mocks</a>
|
|
|
|
|
<a href="reporter_documentation.html">Reporting</a>
|
|
|
|
|
<a href="expectation_documentation.html">Expectations</a>
|
|
|
|
|
<a href="web_tester_documentation.html">Web tester</a>
|
|
|
|
|
<a href="form_testing_documentation.html">Testing forms</a>
|
|
|
|
|
<a href="authentication_documentation.html">Authentication</a>
|
|
|
|
|
<a href="browser_documentation.html">Scriptable browser</a>
|
|
</div></div>
|
|
<h1>Documentation sur le testeur web</h1>
|
|
This page...
|
|
<ul>
|
|
<li>
|
|
Réussir à <a href="#telecharger">télécharger une page web</a>
|
|
</li>
|
|
<li>
|
|
Tester le <a href="#contenu">contenu de la page</a>
|
|
</li>
|
|
<li>
|
|
<a href="#navigation">Naviguer sur un site web</a> pendant le test
|
|
</li>
|
|
<li>
|
|
Méthodes pour <a href="#requete">modifier une requête</a> et pour déboguer
|
|
</li>
|
|
</ul>
|
|
<div class="content">
|
|
<h2>
|
|
<a class="target" name="telecharger"></a>Télécharger une page</h2>
|
|
<p>
|
|
Tester des classes c'est très bien.
|
|
Reste que PHP est avant tout un langage
|
|
pour créer des fonctionnalités à l'intérieur de pages web.
|
|
Comment pouvons tester la partie de devant
|
|
-- celle de l'interface -- dans nos applications en PHP ?
|
|
Etant donné qu'une page web n'est constituée que de texte,
|
|
nous devrions pouvoir les examiner exactement
|
|
comme n'importe quelle autre donnée de test.
|
|
</p>
|
|
<p>
|
|
Cela nous amène à une situation délicate.
|
|
Si nous testons dans un niveau trop bas,
|
|
vérifier des balises avec un motif ad hoc par exemple,
|
|
nos tests seront trop fragiles. Le moindre changement
|
|
dans la présentation pourrait casser un grand nombre de test.
|
|
Si nos tests sont situés trop haut, en utilisant
|
|
une version fantaisie du moteur de template pour
|
|
donner un cas précis, alors nous perdons complètement
|
|
la capacité à automatiser certaines classes de test.
|
|
Par exemple, l'interaction entre des formulaires
|
|
et la navigation devra être testé manuellement.
|
|
Ces types de test sont extrêmement fastidieux
|
|
et plutôt sensibles aux erreurs.
|
|
</p>
|
|
<p>
|
|
SimpleTest comprend une forme spéciale de scénario
|
|
de test pour tester les actions d'une page web.
|
|
<span class="new_code">WebTestCase</span> inclut des facilités pour la navigation,
|
|
des vérifications sur le contenu
|
|
et les cookies ainsi que la gestion des formulaires.
|
|
Utiliser ces scénarios de test ressemble
|
|
fortement à <span class="new_code">UnitTestCase</span>...
|
|
<pre>
|
|
<strong>class TestOfLastcraft extends WebTestCase {
|
|
}</strong>
|
|
</pre>
|
|
Ici nous sommes sur le point de tester
|
|
le site de <a href="http://www.lastcraft.com/">Last Craft</a>.
|
|
Si ce scénario de test est situé dans un fichier appelé
|
|
<em>lastcraft_test.php</em> alors il peut être chargé
|
|
dans un script de lancement tout comme des tests unitaires...
|
|
<pre>
|
|
<?php
|
|
require_once('simpletest/autorun.php');<strong>
|
|
require_once('simpletest/web_tester.php');</strong>
|
|
SimpleTest::prefer(new TextReporter());
|
|
|
|
class WebTests extends TestSuite {
|
|
function WebTests() {
|
|
$this->TestSuite('Web site tests');<strong>
|
|
$this->addFile('lastcraft_test.php');</strong>
|
|
}
|
|
}
|
|
?>
|
|
</pre>
|
|
J'utilise ici le rapporteur en mode texte
|
|
pour mieux distinguer le contenu au format HTML
|
|
du résultat du test proprement dit.
|
|
</p>
|
|
<p>
|
|
Rien n'est encore testé. Nous pouvons télécharger
|
|
la page d'accueil en utilisant la méthode <span class="new_code">get()</span>...
|
|
<pre>
|
|
class TestOfLastcraft extends WebTestCase {
|
|
<strong>
|
|
function testHomepage() {
|
|
$this->assertTrue($this->get('http://www.lastcraft.com/'));
|
|
}</strong>
|
|
}
|
|
</pre>
|
|
La méthode <span class="new_code">get()</span> renverra "true"
|
|
uniquement si le contenu de la page a bien été téléchargé.
|
|
C'est un moyen simple, mais efficace pour vérifier
|
|
qu'une page web a bien été délivré par le serveur web.
|
|
Cependant le contenu peut révéler être une erreur 404
|
|
et dans ce cas notre méthode <span class="new_code">get()</span> renverrait encore un succès.
|
|
</p>
|
|
<p>
|
|
En supposant que le serveur web pour le site Last Craft
|
|
soit opérationnel (malheureusement ce n'est pas toujours le cas),
|
|
nous devrions voir...
|
|
<pre class="shell">
|
|
Web site tests
|
|
OK
|
|
Test cases run: 1/1, Failures: 0, Exceptions: 0
|
|
</pre>
|
|
Nous avons vérifié qu'une page, de n'importe quel type,
|
|
a bien été renvoyée. Nous ne savons pas encore
|
|
s'il s'agit de celle que nous souhaitions.
|
|
</p>
|
|
|
|
<h2>
|
|
<a class="target" name="contenu"></a>Tester le contenu d'une page</h2>
|
|
<p>
|
|
Pour obtenir la confirmation que la page téléchargée
|
|
est bien celle que nous attendions,
|
|
nous devons vérifier son contenu.
|
|
<pre>
|
|
class TestOfLastcraft extends WebTestCase {
|
|
|
|
function testHomepage() {<strong>
|
|
$this->get('http://www.lastcraft.com/');
|
|
$this->assertWantedPattern('/why the last craft/i');</strong>
|
|
}
|
|
}
|
|
</pre>
|
|
La page obtenue par le dernier téléchargement est
|
|
placée dans un buffer au sein même du scénario de test.
|
|
Il n'est donc pas nécessaire de s'y référer directement.
|
|
La correspondance du motif est toujours effectuée
|
|
par rapport à ce buffer.
|
|
</p>
|
|
<p>
|
|
Voici une liste possible d'assertions sur le contenu...
|
|
<table><tbody>
|
|
<tr>
|
|
<td><span class="new_code">assertWantedPattern($pattern)</span></td>
|
|
<td>Vérifier une correspondance sur le contenu via une expression rationnelle Perl</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">assertNoUnwantedPattern($pattern)</span></td>
|
|
<td>Une expression rationnelle Perl pour vérifier une absence</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">assertTitle($title)</span></td>
|
|
<td>Passe si le titre de la page correspond exactement</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">assertLink($label)</span></td>
|
|
<td>Passe si un lien avec ce texte est présent</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">assertNoLink($label)</span></td>
|
|
<td>Passe si aucun lien avec ce texte est présent</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">assertLinkById($id)</span></td>
|
|
<td>Passe si un lien avec cet attribut d'identification est présent</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">assertField($name, $value)</span></td>
|
|
<td>Passe si une balise input avec ce nom contient cette valeur</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">assertFieldById($id, $value)</span></td>
|
|
<td>Passe si une balise input avec cet identifiant contient cette valeur</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">assertResponse($codes)</span></td>
|
|
<td>Passe si la réponse HTTP trouve une correspondance dans la liste</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">assertMime($types)</span></td>
|
|
<td>Passe si le type MIME se retrouve dans cette liste</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">assertAuthentication($protocol)</span></td>
|
|
<td>Passe si l'authentification provoquée est de ce type de protocole</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">assertNoAuthentication()</span></td>
|
|
<td>Passe s'il n'y pas d'authentification provoquée en cours</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">assertRealm($name)</span></td>
|
|
<td>Passe si le domaine provoqué correspond</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">assertHeader($header, $content)</span></td>
|
|
<td>Passe si une entête téléchargée correspond à cette valeur</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">assertNoUnwantedHeader($header)</span></td>
|
|
<td>Passe si une entête n'a pas été téléchargé</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">assertHeaderPattern($header, $pattern)</span></td>
|
|
<td>Passe si une entête téléchargée correspond à cette expression rationnelle Perl</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">assertCookie($name, $value)</span></td>
|
|
<td>Passe s'il existe un cookie correspondant</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">assertNoCookie($name)</span></td>
|
|
<td>Passe s'il n'y a pas de cookie avec un tel nom</td>
|
|
</tr>
|
|
</tbody></table>
|
|
Comme d'habitude avec les assertions de SimpleTest,
|
|
elles renvoient toutes "false" en cas d'échec
|
|
et "true" si c'est un succès.
|
|
Elles renvoient aussi un message de test optionnel :
|
|
vous pouvez l'ajouter dans votre propre message en utilisant "%s".
|
|
</p>
|
|
<p>
|
|
A présent nous pourrions effectué le test sur le titre uniquement...
|
|
<pre>
|
|
<strong>$this->assertTitle('The Last Craft?');</strong>
|
|
</pre>
|
|
En plus d'une simple vérification sur le contenu HTML,
|
|
nous pouvons aussi vérifier que le type MIME est bien d'un type acceptable...
|
|
<pre>
|
|
<strong>$this->assertMime(array('text/plain', 'text/html'));</strong>
|
|
</pre>
|
|
Plus intéressant encore est la vérification sur
|
|
le code de la réponse HTTP. Pareillement au type MIME,
|
|
nous pouvons nous assurer que le code renvoyé se trouve
|
|
bien dans un liste de valeurs possibles...
|
|
<pre>
|
|
class TestOfLastcraft extends WebTestCase {
|
|
|
|
function testHomepage() {
|
|
$this->get('http://simpletest.sourceforge.net/');<strong>
|
|
$this->assertResponse(200);</strong>
|
|
}
|
|
}
|
|
</pre>
|
|
Ici nous vérifions que le téléchargement s'est
|
|
bien terminé en ne permettant qu'une réponse HTTP 200.
|
|
Ce test passera, mais ce n'est pas la meilleure façon de procéder.
|
|
Il n'existe aucune page sur <em>http://simpletest.sourceforge.net/</em>,
|
|
à la place le serveur renverra une redirection vers
|
|
<em>http://www.lastcraft.com/simple_test.php</em>.
|
|
<span class="new_code">WebTestCase</span> suit automatiquement trois
|
|
de ces redirections. Les tests sont quelque peu plus
|
|
robustes de la sorte. Surtout qu'on est souvent plus intéressé
|
|
par l'interaction entre les pages que de leur simple livraison.
|
|
Si les redirections se révèlent être digne d'intérêt,
|
|
il reste possible de les supprimer...
|
|
<pre>
|
|
class TestOfLastcraft extends WebTestCase {
|
|
|
|
function testHomepage() {<strong>
|
|
$this->setMaximumRedirects(0);</strong>
|
|
$this->get('http://simpletest.sourceforge.net/');
|
|
$this->assertResponse(200);
|
|
}
|
|
}
|
|
</pre>
|
|
Alors l'assertion échoue comme prévue...
|
|
<pre class="shell">
|
|
Web site tests
|
|
1) Expecting response in [200] got [302]
|
|
in testhomepage
|
|
in testoflastcraft
|
|
in lastcraft_test.php
|
|
FAILURES!!!
|
|
Test cases run: 1/1, Failures: 1, Exceptions: 0
|
|
</pre>
|
|
Nous pouvons modifier le test pour accepter les redirections...
|
|
<pre>
|
|
class TestOfLastcraft extends WebTestCase {
|
|
|
|
function testHomepage() {
|
|
$this->setMaximumRedirects(0);
|
|
$this->get('http://simpletest.sourceforge.net/');
|
|
$this->assertResponse(<strong>array(301, 302, 303, 307)</strong>);
|
|
}
|
|
}
|
|
</pre>
|
|
Maitenant ça passe.
|
|
</p>
|
|
|
|
<h2>
|
|
<a class="target" name="navigation"></a>Navigeur dans un site web</h2>
|
|
<p>
|
|
Les utilisateurs ne naviguent pas souvent en tapant les URLs,
|
|
mais surtout en cliquant sur des liens et des boutons.
|
|
Ici nous confirmons que les informations sur le contact
|
|
peuvent être atteintes depuis la page d'accueil...
|
|
<pre>
|
|
class TestOfLastcraft extends WebTestCase {
|
|
...
|
|
function testContact() {
|
|
$this->get('http://www.lastcraft.com/');<strong>
|
|
$this->clickLink('About');
|
|
$this->assertTitle('About Last Craft');</strong>
|
|
}
|
|
}
|
|
</pre>
|
|
Le paramètre est le texte du lien.
|
|
</p>
|
|
<p>
|
|
Il l'objectif est un bouton plutôt qu'une balise ancre,
|
|
alors <span class="new_code">clickSubmit()</span> doit être utilisé avec
|
|
le titre du bouton...
|
|
<pre>
|
|
<strong>$this->clickSubmit('Go!');</strong>
|
|
</pre>
|
|
</p>
|
|
<p>
|
|
La liste des méthodes de navigation est...
|
|
<table><tbody>
|
|
<tr>
|
|
<td><span class="new_code">get($url, $parameters)</span></td>
|
|
<td>Envoie une requête GET avec ces paramètres</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">post($url, $parameters)</span></td>
|
|
<td>Envoie une requête POST avec ces paramètres</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">head($url, $parameters)</span></td>
|
|
<td>Envoie une requête HEAD sans remplacer le contenu de la page</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">retry()</span></td>
|
|
<td>Relance la dernière requête</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">back()</span></td>
|
|
<td>Identique au bouton "Précédent" du navigateur</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">forward()</span></td>
|
|
<td>Identique au bouton "Suivant" du navigateur</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">authenticate($name, $password)</span></td>
|
|
<td>Re-essaye avec une tentative d'authentification</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">getFrameFocus()</span></td>
|
|
<td>Le nom de la fenêtre en cours d'utilisation</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">setFrameFocusByIndex($choice)</span></td>
|
|
<td>Change le focus d'une fenêtre en commençant par 1</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">setFrameFocus($name)</span></td>
|
|
<td>Change le focus d'une fenêtre en utilisant son nom</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">clearFrameFocus()</span></td>
|
|
<td>Revient à un traitement de toutes les fenêtres comme une seule</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">clickSubmit($label)</span></td>
|
|
<td>Clique sur le premier bouton avec cette étiquette</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">clickSubmitByName($name)</span></td>
|
|
<td>Clique sur le bouton avec cet attribut de nom</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">clickSubmitById($id)</span></td>
|
|
<td>Clique sur le bouton avec cet attribut d'identification</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">clickImage($label, $x, $y)</span></td>
|
|
<td>Clique sur une balise input de type image par son titre (title="*") our son texte alternatif (alt="*")</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">clickImageByName($name, $x, $y)</span></td>
|
|
<td>Clique sur une balise input de type image par son attribut (name="*")</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">clickImageById($id, $x, $y)</span></td>
|
|
<td>Clique sur une balise input de type image par son identifiant (id="*")</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">submitFormById($id)</span></td>
|
|
<td>Soumet un formulaire sans valeur de soumission</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">clickLink($label, $index)</span></td>
|
|
<td>Clique sur une ancre avec ce texte d'étiquette visible</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">clickLinkById($id)</span></td>
|
|
<td>Clique sur une ancre avec cet attribut d'identification</td>
|
|
</tr>
|
|
</tbody></table>
|
|
</p>
|
|
<p>
|
|
Les paramètres dans les méthodes <span class="new_code">get()</span>,
|
|
<span class="new_code">post()</span> et <span class="new_code">head()</span> sont optionnels.
|
|
Le téléchargement via HTTP HEAD ne modifie pas
|
|
le contexte du navigateur, il se limite au chargement des cookies.
|
|
Cela peut être utilise lorsqu'une image ou une feuille de style
|
|
initie un cookie pour bloquer un robot trop entreprenant.
|
|
</p>
|
|
<p>
|
|
Les commandes <span class="new_code">retry()</span>, <span class="new_code">back()</span>
|
|
et <span class="new_code">forward()</span> fonctionnent exactement comme
|
|
dans un navigateur. Elles utilisent l'historique pour
|
|
relancer les pages. Une technique bien pratique pour
|
|
vérifier les effets d'un bouton retour sur vos formulaires.
|
|
</p>
|
|
<p>
|
|
Les méthodes sur les fenêtres méritent une petite explication.
|
|
Par défaut, une page avec des fenêtres est traitée comme toutes
|
|
les autres. Le contenu sera vérifié à travers l'ensemble de
|
|
la "frameset", par conséquent un lien fonctionnera,
|
|
peu importe la fenêtre qui contient la balise ancre.
|
|
Vous pouvez outrepassé ce comportement en exigeant
|
|
le focus sur une unique fenêtre. Si vous réalisez cela,
|
|
toutes les recherches et toutes les actions se limiteront
|
|
à cette unique fenêtre, y compris les demandes d'authentification.
|
|
Si un lien ou un bouton n'est pas dans la fenêtre en focus alors
|
|
il ne peut pas être cliqué.
|
|
</p>
|
|
<p>
|
|
Tester la navigation sur des pages fixes ne vous alerte que
|
|
quand vous avez cassé un script entier.
|
|
Pour des pages fortement dynamiques,
|
|
un forum de discussion par exemple,
|
|
ça peut être crucial pour vérifier l'état de l'application.
|
|
Pour la plupart des applications cependant,
|
|
la logique vraiment délicate se situe dans la gestion
|
|
des formulaires et des sessions.
|
|
Heureusement SimpleTest aussi inclut
|
|
<a href="form_testing_documentation.html">
|
|
des outils pour tester des formulaires web</a>.
|
|
</p>
|
|
|
|
<h2>
|
|
<a class="target" name="requete"></a>Modifier la requête</h2>
|
|
<p>
|
|
Bien que SimpleTest n'ait pas comme objectif
|
|
de contrôler des erreurs réseau, il contient quand même
|
|
des méthodes pour modifier et déboguer les requêtes qu'il lance.
|
|
Voici une autre liste de méthode...
|
|
<table><tbody>
|
|
<tr>
|
|
<td><span class="new_code">getTransportError()</span></td>
|
|
<td>La dernière erreur de socket</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">getUrl()</span></td>
|
|
<td>La localisation courante</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">showRequest()</span></td>
|
|
<td>Déverse la requête sortante</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">showHeaders()</span></td>
|
|
<td>Déverse les entêtes d'entrée</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">showSource()</span></td>
|
|
<td>Déverse le contenu brut de la page HTML</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">ignoreFrames()</span></td>
|
|
<td>Ne recharge pas les framesets</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">setCookie($name, $value)</span></td>
|
|
<td>Initie un cookie à partir de maintenant</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">addHeader($header)</span></td>
|
|
<td>Ajoute toujours cette entête à la requête</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">setMaximumRedirects($max)</span></td>
|
|
<td>S'arrête après autant de redirections</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">setConnectionTimeout($timeout)</span></td>
|
|
<td>Termine la connexion après autant de temps entre les bytes</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="new_code">useProxy($proxy, $name, $password)</span></td>
|
|
<td>Effectue les requêtes à travers ce proxy d'URL</td>
|
|
</tr>
|
|
</tbody></table>
|
|
</p>
|
|
|
|
</div>
|
|
References and related information...
|
|
<ul>
|
|
<li>
|
|
La page du projet SimpleTest sur
|
|
<a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
|
|
</li>
|
|
<li>
|
|
La page de téléchargement de SimpleTest sur
|
|
<a href="http://www.lastcraft.com/simple_test.php">LastCraft</a>.
|
|
</li>
|
|
<li>
|
|
<a href="http://simpletest.org/api/">L'API du développeur pour SimpleTest</a>
|
|
donne tous les détails sur les classes et les assertions disponibles.
|
|
</li>
|
|
</ul>
|
|
<div class="menu_back"><div class="menu">
|
|
<a href="index.html">SimpleTest</a>
|
|
|
|
|
<a href="overview.html">Overview</a>
|
|
|
|
|
<a href="unit_test_documentation.html">Unit tester</a>
|
|
|
|
|
<a href="group_test_documentation.html">Group tests</a>
|
|
|
|
|
<a href="mock_objects_documentation.html">Mock objects</a>
|
|
|
|
|
<a href="partial_mocks_documentation.html">Partial mocks</a>
|
|
|
|
|
<a href="reporter_documentation.html">Reporting</a>
|
|
|
|
|
<a href="expectation_documentation.html">Expectations</a>
|
|
|
|
|
<a href="web_tester_documentation.html">Web tester</a>
|
|
|
|
|
<a href="form_testing_documentation.html">Testing forms</a>
|
|
|
|
|
<a href="authentication_documentation.html">Authentication</a>
|
|
|
|
|
<a href="browser_documentation.html">Scriptable browser</a>
|
|
</div></div>
|
|
<div class="copyright">
|
|
Copyright<br>Marcus Baker 2006
|
|
</div>
|
|
</body>
|
|
</html>
|