Zend_Test-PHPUnit-Db-Quickstart.xml 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- EN-Revision: 24249 -->
  3. <!-- Reviewed: no -->
  4. <sect2 id="zend.test.phpunit.db.quickstart">
  5. <title>Quickstart</title>
  6. <sect3 id="zend.test.phpunit.db.quickstart.testcase">
  7. <title>Configurer un cas de tests Database</title>
  8. <para>
  9. Nous allons à présent écrire des tests pour la base de données Bug de la
  10. documentation sur <classname>Zend_Db_Table</classname>. D'abord, nous testons
  11. qu'insérer un nouveau bug est bien sauvegardé en base. Nous devons créer un cas
  12. de tests sous forme de classe étendant
  13. <classname>Zend_Test_PHPUnit_DatabaseTestCase</classname>. Cette classe étend elle-
  14. même PHPUnit Database Extension, qui étend alors
  15. <classname>PHPUnit_Framework_TestCase</classname>. Un cas de test pour base de données
  16. contient deux méthodes abstraites à définir, une concernant la connexion à la base et
  17. l'autre concernant les données à utiliser comme source pour les tests.
  18. </para>
  19. <note>
  20. <para>
  21. Il est recommandé de se familiariser à l'extension PHPUnit Database afin de suivre
  22. nos exemples sereinnement. Bien que nous expliquions tous les concepts dans cette
  23. documentation, il peut être intéressant de lire la documentation de PHPUnit avant
  24. de suivre nos exemples.
  25. </para>
  26. </note>
  27. <programlisting language="php"><![CDATA[
  28. class BugsTest extends Zend_Test_PHPUnit_DatabaseTestCase
  29. {
  30. private $_connectionMock;
  31. /**
  32. * Retourne la connexion de test
  33. *
  34. * @return PHPUnit_Extensions_Database_DB_IDatabaseConnection
  35. */
  36. protected function getConnection()
  37. {
  38. if($this->_connectionMock == null) {
  39. $connection = Zend_Db::factory(...);
  40. $this->_connectionMock = $this->createZendDbConnection(
  41. $connection, 'zfunittests'
  42. );
  43. Zend_Db_Table_Abstract::setDefaultAdapter($connection);
  44. }
  45. return $this->_connectionMock;
  46. }
  47. /**
  48. * @return PHPUnit_Extensions_Database_DataSet_IDataSet
  49. */
  50. protected function getDataSet()
  51. {
  52. return $this->createFlatXmlDataSet(
  53. dirname(__FILE__) . '/_files/bugsSeed.xml'
  54. );
  55. }
  56. }
  57. ]]></programlisting>
  58. <para>
  59. Ici, nous créons la connexion à la base et nous y injectons des données fictives de test.
  60. Les éléments suivants sont importants à noter :
  61. </para>
  62. <itemizedlist>
  63. <listitem>
  64. <para>
  65. Vous ne pouvez retourner directement un objet <classname>Zend_Db_Adapter_Abstract</classname>
  66. depuis <methodname>getConnection()</methodname>, mais un objet spécifique à PHPUnit
  67. qui est généré grâce à la méthode <methodname>createZendDbConnection()</methodname>.
  68. </para>
  69. </listitem>
  70. <listitem>
  71. <para>
  72. Le schéma de la base (tables et bases de données) n'est pas recrée
  73. entre chaque test. Les bases de données et les tables doivent être créees
  74. à la main avant de lancer les tests.
  75. </para>
  76. </listitem>
  77. <listitem>
  78. <para>
  79. Les tests vident la base durant <methodname>setUp()</methodname> et y
  80. insèrent les données en provenance de <methodname>getDataSet()</methodname>.
  81. </para>
  82. </listitem>
  83. <listitem>
  84. <para>
  85. Les jeux de données (DataSets) doivent implémenter
  86. <classname>PHPUnit_Extensions_Database_DataSet_IDataSet</classname>.
  87. Il en existe quelques uns, basés sur <acronym>XML</acronym> ou YAML et
  88. ils sont inclus dans PHPUnit et permettent de décrire les données fictives pour
  89. les tests. Vous devriez vous reporter à la documentation de PHPUnit pour
  90. des informations complémentaires ou plus à jour concernant les DataSets.
  91. </para>
  92. </listitem>
  93. </itemizedlist>
  94. </sect3>
  95. <sect3 id="zend.test.phpunit.db.quickstart.dataset">
  96. <title>Spécifier un jeu de données (DataSet)</title>
  97. <para>
  98. Dans l'exemple précédent, nous avons préciser un fichier de jeu de données. Nous allons
  99. maintenant le créer, au format <acronym>XML</acronym> :
  100. </para>
  101. <programlisting language="xml"><![CDATA[
  102. <?xml version="1.0" encoding="UTF-8" ?>
  103. <dataset>
  104. <zfbugs bug_id="1" bug_description="system needs electricity to run"
  105. bug_status="NEW" created_on="2007-04-01 00:00:00"
  106. updated_on="2007-04-01 00:00:00" reported_by="goofy"
  107. assigned_to="mmouse" verified_by="dduck" />
  108. <zfbugs bug_id="2" bug_description="Implement Do What I Mean function"
  109. bug_status="VERIFIED" created_on="2007-04-02 00:00:00"
  110. updated_on="2007-04-02 00:00:00" reported_by="goofy"
  111. assigned_to="mmouse" verified_by="dduck" />
  112. <zfbugs bug_id="3" bug_description="Where are my keys?" bug_status="FIXED"
  113. created_on="2007-04-03 00:00:00" updated_on="2007-04-03 00:00:00"
  114. reported_by="dduck" assigned_to="mmouse" verified_by="dduck" />
  115. <zfbugs bug_id="4" bug_description="Bug no product" bug_status="INCOMPLETE"
  116. created_on="2007-04-04 00:00:00" updated_on="2007-04-04 00:00:00"
  117. reported_by="mmouse" assigned_to="goofy" verified_by="dduck" />
  118. </dataset>
  119. ]]></programlisting>
  120. <para>
  121. Nous allons travailler sur ces quatre entrées dans la table "zfbugs" après.
  122. Le script MySQL suivant est nécessaire pour l'exemple:
  123. </para>
  124. <programlisting language="sql"><![CDATA[
  125. CREATE TABLE IF NOT EXISTS `zfbugs` (
  126. `bug_id` int(11) NOT NULL auto_increment,
  127. `bug_description` varchar(100) default NULL,
  128. `bug_status` varchar(20) default NULL,
  129. `created_on` datetime default NULL,
  130. `updated_on` datetime default NULL,
  131. `reported_by` varchar(100) default NULL,
  132. `assigned_to` varchar(100) default NULL,
  133. `verified_by` varchar(100) default NULL,
  134. PRIMARY KEY (`bug_id`)
  135. ) ENGINE=InnoDB AUTO_INCREMENT=1 ;
  136. ]]></programlisting>
  137. </sect3>
  138. <sect3 id="zend.test.phpunit.db.quickstart.initial-tests">
  139. <title>Quelques tests initiaux</title>
  140. <para>
  141. Maintenant que nous avons écrits les deux méthodes obligatoires pour
  142. <classname>Zend_Test_PHPUnit_DatabaseTestCase</classname> et que nous avons
  143. préciser avec quoi remplir la base et ses tables, nous pouvons commencer à écrire
  144. des tests afin d'effectuer des assertions. Voyons un test pour l'insertion d'un
  145. nouveau bug
  146. </para>
  147. <programlisting language="php"><![CDATA[
  148. class BugsTest extends Zend_Test_PHPUnit_DatabaseTestCase
  149. {
  150. public function testBugInsertedIntoDatabase()
  151. {
  152. $bugsTable = new Bugs();
  153. $data = array(
  154. 'created_on' => '2007-03-22 00:00:00',
  155. 'updated_on' => '2007-03-22 00:00:00',
  156. 'bug_description' => 'Something wrong',
  157. 'bug_status' => 'NEW',
  158. 'reported_by' => 'garfield',
  159. 'verified_by' => 'garfield',
  160. 'assigned_to' => 'mmouse',
  161. );
  162. $bugsTable->insert($data);
  163. $ds = new Zend_Test_PHPUnit_Db_DataSet_QueryDataSet(
  164. $this->getConnection()
  165. );
  166. $ds->addTable('zfbugs', 'SELECT * FROM zfbugs');
  167. $this->assertDataSetsEqual(
  168. $this->createFlatXmlDataSet(dirname(__FILE__)
  169. . "/_files/bugsInsertIntoAssertion.xml"),
  170. $ds
  171. );
  172. }
  173. }
  174. ]]></programlisting>
  175. <para>
  176. Au dessus de la ligne <methodname>$bugsTable->insert($data);</methodname>, tout devrait vous
  177. être familier. La ligne d'après contient le nom de la méthode d'assertion. Nous souhaitons vérifier
  178. qu'après l'insertion d'un bug, la base a été correctement mise à jour avec les données. Ainsi,
  179. nous utilisons un objet de requête de jeu de données, instance de
  180. <classname>Zend_Test_PHPUnit_Db_DataSet_QueryDataSet</classname> et nous lui fournissons notre
  181. connexion à la base de données. Puis nous indiquons à notre objet de requête qu'il contient une table
  182. "zfbugs" contenant les données d'une requête <acronym>SQL</acronym> statement. Cet état actuel
  183. est alors comparé à un état contenu dans un fichier <acronym>XML</acronym>
  184. "bugsInsertIntoAssertions.xml". Ce fichier <acronym>XML</acronym> est le même que celui des données
  185. d'origine, à l'exception qu'il contient lui les données supplémentaires attendues:
  186. </para>
  187. <programlisting language="xml"><![CDATA[
  188. <?xml version="1.0" encoding="UTF-8" ?>
  189. <dataset>
  190. <!-- Les 4 enregistrement précédents, puis: -->
  191. <zfbugs bug_id="5" bug_description="Something wrong" bug_status="NEW"
  192. created_on="2007-03-22 00:00:00" updated_on="2007-03-22 00:00:00"
  193. reported_by="garfield" assigned_to="mmouse" verified_by="garfield" />
  194. </dataset>
  195. ]]></programlisting>
  196. <para>
  197. Il existe d'autres manière de vérifier que l'état actuel de la base est équivalent à
  198. un état attendu. La table "Bugs" de l'exemple connait déja sont état interne, utilisons
  199. ceci à notre avantage. L'exemple suivant teste que la suppression de données dans la table
  200. est possible:
  201. </para>
  202. <programlisting language="php"><![CDATA[
  203. class BugsTest extends Zend_Test_PHPUnit_DatabaseTestCase
  204. {
  205. public function testBugDelete()
  206. {
  207. $bugsTable = new Bugs();
  208. $bugsTable->delete(
  209. $bugsTable->getAdapter()->quoteInto("bug_id = ?", 4)
  210. );
  211. $ds = new Zend_Test_PHPUnit_Db_DataSet_DbTableDataSet();
  212. $ds->addTable($bugsTable);
  213. $this->assertDataSetsEqual(
  214. $this->createFlatXmlDataSet(dirname(__FILE__)
  215. . "/_files/bugsDeleteAssertion.xml"),
  216. $ds
  217. );
  218. }
  219. }
  220. ]]></programlisting>
  221. <para>
  222. Ici nous créons un objet représentant un jeu de données pour une table, instance de
  223. <classname>Zend_Test_PHPUnit_Db_DataSet_DbTableDataSet</classname>. Il prend en paramètre
  224. un objet <classname>Zend_Db_Table_Abstract</classname> et l'ajoute au jeu de données
  225. avec le nom de la table, dans notre exemple : "zfbugs". Vous pourriez ajouter plus de données
  226. dans le jeu de données en utilisant <methodname>addTable()</methodname> plusieurs fois.
  227. </para>
  228. <para>
  229. Ici nous ne possédons qu'une seule table et nous la comparons à un état défini dans
  230. "bugsDeleteAssertion.xml" qui est en fait le jeu de données original moins la données
  231. supprimée : celle ayant l'id 4.
  232. </para>
  233. <para>
  234. Voyons maintenant comment vérifier que deux tables soient identiques (et non deux jeux
  235. de données correspondants à de telles tables). Ajoutons un test à notre scénario qui va
  236. vérifier la mise à jour de données.
  237. </para>
  238. <programlisting language="php"><![CDATA[
  239. class BugsTest extends Zend_Test_PHPUnit_DatabaseTestCase
  240. {
  241. public function testBugUpdate()
  242. {
  243. $bugsTable = new Bugs();
  244. $data = array(
  245. 'updated_on' => '2007-05-23',
  246. 'bug_status' => 'FIXED'
  247. );
  248. $where = $bugsTable->getAdapter()->quoteInto('bug_id = ?', 1);
  249. $bugsTable->update($data, $where);
  250. $rowset = $bugsTable->fetchAll();
  251. $ds = new Zend_Test_PHPUnit_Db_DataSet_DbRowset($rowset);
  252. $assertion = $this->createFlatXmlDataSet(
  253. dirname(__FILE__) . '/_files/bugsUpdateAssertion.xml'
  254. );
  255. $expectedRowsets = $assertion->getTable('zfbugs');
  256. $this->assertTablesEqual(
  257. $expectedRowsets, $ds
  258. );
  259. }
  260. }
  261. ]]></programlisting>
  262. <para>
  263. Ici, nous récupérons l'état de la table depuis un objet
  264. <classname>Zend_Db_Table_Rowset_Abstract</classname> au moyen de
  265. <methodname>Zend_Test_PHPUnit_Db_DataSet_DbRowset($rowset)</methodname> qui crée
  266. une représentation de l'état interne des données du rowset. Nous comparons
  267. enfin cet état grâce à l'assertion
  268. <methodname>$this->assertTablesEqual()</methodname>
  269. </para>
  270. </sect3>
  271. </sect2>