| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 |
- <!-- EN-Revision: 13910 -->
- <sect2 id="zend.test.phpunit.examples">
- <title>Exemples</title>
- <para>Savoir comment configurer votre infrastructure de tests et comment faire des assertions est seulement la
- moitié du travail ; maintenant il est temps de commencer à regarder quelques scénarios réels de test pour voir
- comment vous pouvez les étendre. </para>
- <example id="zend.test.phpunit.examples.userController">
- <title>Test d'un contrôleur "UserController"</title>
- <para>Considérons une tâche habituelle d'un site Web : l'authentification et l'enregistrement d'utilisateurs.
- Dans notre exemple, nous avons défini un contrôleur "<code>UserController</code>" pour gérer ceci, il requiert
- le conditions suivantes :</para>
- <itemizedlist>
- <listitem>
- <para>Si un utilisateur n'est pas authentifié, il sera toujours redirigé vers la page de login, sans se
- soucier de l'action demandée.</para>
- </listitem>
- <listitem>
- <para>La page avec le formulaire de login présente à la fois le formulaire de login et le formulaire
- d'enregistrement.</para>
- </listitem>
- <listitem>
- <para>Fournir une identification invalide entraîne un retour au formulaire de login.</para>
- </listitem>
- <listitem>
- <para>Une identification valide entraîne une redirection vers la page avec le profil de
- l'utilisateur.</para>
- </listitem>
- <listitem>
- <para>La page de profil peut être personnalisée pour contenir le nom d'utilisateur.</para>
- </listitem>
- <listitem>
- <para>Les utilisateurs déjà authentifiés qui accèdent à la page de login sont redirigés vers leur page
- de profil.</para>
- </listitem>
- <listitem>
- <para>En cas de déconnexion, un utilisateur est redirigé vers la page de login.</para>
- </listitem>
- <listitem>
- <para>Avec des données invalides, l'enregistrement doit entraîner un échec.</para>
- </listitem>
- </itemizedlist>
- <para>Nous pourrions, et devrions définir d'autres tests, mais ceux-ci suffiront pour l'instant.</para>
- <para>Pour notre application, nous définirons un plugin "<code>Initialize</code>", qui fonctionne en
- <code>routeStartup()</code>. Ceci nous permet d'encapsuler notre fichier d'amorçage dans une interface POO, et
- qui nous permet aussi de fournir par une solution simple une fonction de rappel ("callback"). Regardons d'abord
- les bases de cette classe :</para>
- <programlisting role="php"><![CDATA[
- class Bugapp_Plugin_Initialize extends Zend_Controller_Plugin_Abstract
- {
- /**
- * @var Zend_Config
- */
- protected static $_config;
- /**
- * @var string Current environment
- */
- protected $_env;
- /**
- * @var Zend_Controller_Front
- */
- protected $_front;
- /**
- * @var string Path to application root
- */
- protected $_root;
- /**
- * Constructor
- *
- * Initialize environment, root path, and configuration.
- *
- * @param string $env
- * @param string|null $root
- * @return void
- */
- public function __construct($env, $root = null)
- {
- $this->_setEnv($env);
- if (null === $root) {
- $root = realpath(dirname(__FILE__) . '/../../../');
- }
- $this->_root = $root;
- $this->initPhpConfig();
- $this->_front = Zend_Controller_Front::getInstance();
- }
- /**
- * Route startup
- *
- * @return void
- */
- public function routeStartup(Zend_Controller_Request_Abstract $request)
- {
- $this->initDb();
- $this->initHelpers();
- $this->initView();
- $this->initPlugins();
- $this->initRoutes();
- $this->initControllers();
- }
- // definition of methods would follow...
- }
- ]]></programlisting>
- <para>Ceci nous permet de créer un callback d'amorçage comme ce qui suit :</para>
- <programlisting role="php"><![CDATA[
- class UserControllerTest extends Zend_Test_PHPUnit_ControllerTestCase
- {
- public function appBootstrap()
- {
- $controller = $this->getFrontController();
- $controller->registerPlugin(
- new Bugapp_Plugin_Initialize('development')
- );
- }
- public function setUp()
- {
- $this->bootstrap = array($this, 'appBootstrap');
- parent::setUp();
- }
- // ...
- }
- ]]></programlisting>
- <para>Une fois ceci en place, nous pouvons écrire nos tests. Cependant, combien de ces tests nécessiteront qu'un
- utilisateur soit connecté ? La solution la plus simple est d'utiliser la logique de votre application pour faire
- ceci... et d'esquiver un peu par l'utilisation des méthodes <code>resetResponse()</code> et
- <code>resetResponse()</code>, qui vous permettront de distribuer une nouvelle requête.</para>
- <programlisting role="php"><![CDATA[
- class UserControllerTest extends Zend_Test_PHPUnit_ControllerTestCase
- {
- // ...
- public function loginUser($user, $password)
- {
- $this->request->setMethod('POST')
- ->setPost(array(
- 'username' => $user,
- 'password' => $password,
- ));
- $this->dispatch('/user/login');
- $this->assertRedirectTo('/user/view');
- $this->resetRequest()
- ->resetResponse();
- $this->request->setPost(array());
- // ...
- }
- // ...
- }
- ]]></programlisting>
- <para>Écrivons maintenant les tests :</para>
- <programlisting role="php"><![CDATA[
- class UserControllerTest extends Zend_Test_PHPUnit_ControllerTestCase
- {
- // ...
- public function testCallWithoutActionShouldPullFromIndexAction()
- {
- $this->dispatch('/user');
- $this->assertController('user');
- $this->assertAction('index');
- }
- public function testLoginFormShouldContainLoginAndRegistrationForms()
- {
- $this->dispatch('/user');
- $this->assertQueryCount('form', 2);
- }
- public function testInvalidCredentialsShouldResultInRedisplayOfLoginForm()
- {
- $request = $this->getRequest();
- $request->setMethod('POST')
- ->setPost(array(
- 'username' => 'bogus',
- 'password' => 'reallyReallyBogus',
- ));
- $this->dispatch('/user/login');
- $this->assertNotRedirect();
- $this->assertQuery('form');
- }
- public function testValidLoginShouldRedirectToProfilePage()
- {
- $this->loginUser('foobar', 'foobar');
- }
- public function testAuthenticatedUserShouldHaveCustomizedProfilePage()
- {
- $this->loginUser('foobar', 'foobar');
- $this->request->setMethod('GET');
- $this->dispatch('/user/view');
- $this->assertNotRedirect();
- $this->assertQueryContentContains('h2', 'foobar');
- }
- public function testAuthenticatedUsersShouldBeRedirectedToProfilePageWhenVisitingLoginPage()
- {
- $this->loginUser('foobar', 'foobar');
- $this->request->setMethod('GET');
- $this->dispatch('/user');
- $this->assertRedirectTo('/user/view');
- }
- public function testUserShouldRedirectToLoginPageOnLogout()
- {
- $this->loginUser('foobar', 'foobar');
- $this->request->setMethod('GET');
- $this->dispatch('/user/logout');
- $this->assertRedirectTo('/user');
- }
- public function testRegistrationShouldFailWithInvalidData()
- {
- $data = array(
- 'username' => 'This will not work',
- 'email' => 'this is an invalid email',
- 'password' => 'Th1s!s!nv@l1d',
- 'passwordVerification' => 'wrong!',
- );
- $request = $this->getRequest();
- $request->setMethod('POST')
- ->setPost($data);
- $this->dispatch('/user/register');
- $this->assertNotRedirect();
- $this->assertQuery('form .errors');
- }
- }
- ]]></programlisting>
- <para>Notez que ces tests sont laconiques, et, pour la plupart, ne recherchent pas le contenu réel. Au lieu de
- cela, ils recherchent des objets construits dans la réponse - codes et en-têtes de réponse, et noeuds DOM. Ceci
- vous permet de vérifier que la structure est comme prévue - sans entraîner un échec dans vos tests à chaque fois
- qu'un contenu est ajouté au site. </para>
- <para>Notez également que nous utilisons la structure du document dans nos essais. Par exemple, dans le test
- final, nous recherchons un formulaire qui a un noeud avec la classe "errors" ; ceci nous permet de déterminer
- simplement la présence des erreurs de validation de formulaire, et sans nous inquiéter de quelles erreurs
- spécifiques pourraient avoir été levées. </para>
- <para>Cette application <emphasis>peut</emphasis> utiliser une base de données. Si oui, vous aurez besoin
- probablement d'un certain échafaudage pour s'assurer que la base de données est dans une configuration initiale
- et testable au début de chaque essai. PHPUnit fournit déjà une fonctionnalité pour faire ceci ; <ulink
- url="http://www.phpunit.de/pocket_guide/3.3/en/database.html">lisez ceci dans la documentation PHPUnit</ulink>.
- Nous recommandons d'utiliser une base de données séparée pour les tests et pour la production, et recommandons
- en particulier d'employer un fichier SQLite ou une base de données en mémoire, d'autant que les deux options
- s'exécutent très bien, sans nécessité d'un serveur séparé, et peuvent utiliser la plupart de la syntaxe
- SQL</para>
- </example>
- </sect2>
- <!--
- vim:se ts=4 sw=4 et:
- -->
|