[MANUAL] English:
[zend.git] / documentation / manual / en / module_specs / Zend_Test-PHPUnit-Db-Testing.xml
blob23db609ce2621734eacaca53467889f184e3597d
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- Reviewed: no -->
3 <sect2 id="zend.test.phpunit.db.testing">
4     <title>Usage, API and Extensions Points</title>
6     <para>
7         The Quickstart already gave a good introduction on how database testing can be done using
8         PHPUnit and the Zend Framework. This section gives an overview over the
9         <acronym>API</acronym> that the <classname>Zend_Test_PHPUnit_Db</classname> component comes
10         with and how it works internally.
11     </para>
13     <note>
14         <title>Some Remarks on Database Testing</title>
16         <para>
17             Just as the Controller TestCase is testing an application at an integration level, the
18             Database TestCase is an integration testing method. Its using several different
19             application layers for testing purposes and therefore should be consumed with caution.
20         </para>
22         <para>
23             It should be noted that testing domain and business logic with integration tests such
24             as Zend Framework's Controller and Database TestCases is a bad practice. The purpose of
25             an Integration test is to check that several parts of an application work smoothly when
26             wired together. These integration tests do not replace the need for a set of unit tests
27             that test the domain and business logic at a much smaller level, the isolated class.
28         </para>
29     </note>
31     <sect3 id="zend.test.phpunit.db.testing.testcase">
32         <title>The Zend_Test_PHPUnit_DatabaseTestCase class</title>
34         <para>
35             The <classname>Zend_Test_PHPUnit_DatabaseTestCase</classname> class derives from the
36             <classname>PHPUnit_Extensions_Database_TestCase</classname> which allows to setup tests
37             with a fresh database fixture on each run easily. The Zend implementation offers some
38             additional convenience features over the PHPUnit Database extension when it comes to
39             using <classname>Zend_Db</classname> resources inside your tests. The workflow of a
40             database test-case can be described as follows.
41         </para>
43         <orderedlist>
44             <listitem>
45                 <para>
46                     For each test PHPUnit creates a new instance of the TestCase and calls the
47                     <methodname>setUp()</methodname> method.
48                 </para>
49             </listitem>
51             <listitem>
52                 <para>
53                     The Database TestCase creates an instance of a Database Tester which handles the
54                     setting up and tearing down of the database.
55                 </para>
56             </listitem>
58             <listitem>
59                 <para>
60                     The database tester collects the information on the database connection and
61                     initial dataset from <methodname>getConnection()</methodname> and
62                     <methodname>getDataSet()</methodname> which are both abstract methods and have
63                     to be implemented by any Database Testcase.
64                 </para>
65             </listitem>
67             <listitem>
68                 <para>
69                     By default the database tester truncates the tables specified in the given
70                     dataset, and then inserts the data given as initial fixture.
71                 </para>
72             </listitem>
74             <listitem>
75                 <para>
76                     When the database tester has finished setting up the database, PHPUnit runs the
77                     test.
78                 </para>
79             </listitem>
81             <listitem>
82                 <para>
83                     After running the test, <methodname>tearDown()</methodname> is called. Because
84                     the database is wiped in <methodname>setUp()</methodname> before inserting the
85                     required initial fixture, no actions are executed by the database tester at this
86                     stage.
87                 </para>
88             </listitem>
89         </orderedlist>
91         <note>
92             <para>
93                 The Database TestCase expects the database schema and tables to be setup correctly
94                 to run the tests. There is no mechanism to create and tear down database tables.
95             </para>
96         </note>
98         <para>
99             The <classname>Zend_Test_PHPUnit_DatabaseTestCase</classname> class has some convenience
100             functions that can help writing tests that interact with the database and the database
101             testing extension.
102         </para>
104         <para>
105             The next table lists only the new methods compared to the
106             <classname>PHPUnit_Extensions_Database_TestCase</classname>, whose <ulink
107                 url="http://www.phpunit.de/manual/current/en/database.html">API is documented in
108             the PHPUnit Documentation</ulink>.
109         </para>
111         <table id="zend.test.phpunit.db.testing.testcase.api-methods">
112             <title>Zend_Test_PHPUnit_DatabaseTestCase API Methods</title>
114             <tgroup cols="2">
115                 <thead>
116                     <row>
117                         <entry>Method</entry>
118                         <entry>Description</entry>
119                     </row>
120                 </thead>
122                 <tbody>
123                     <row>
124                         <entry>
125                             <methodname>createZendDbConnection(Zend_Db_Adapter_Abstract $connection,
126                                 $schema)</methodname>
127                         </entry>
129                         <entry>
130                             Create a PHPUnit Database Extension compatible Connection instance from
131                             a <classname>Zend_Db_Adapter_Abstract</classname> instance. This method
132                             should be used in for testcase setup when implementing the abstract
133                             <methodname>getConnection()</methodname> method of the database
134                             testcase.
135                         </entry>
136                     </row>
138                     <row>
139                         <entry><methodname>getAdapter()</methodname></entry>
141                         <entry>
142                             Convenience method to access the underlying
143                             <classname>Zend_Db_Adapter_Abstract</classname> instance which is nested
144                             inside the PHPUnit database connection created with
145                             <methodname>getConnection()</methodname>.
146                         </entry>
147                     </row>
149                     <row>
150                         <entry>
151                             <methodname>createDbRowset(Zend_Db_Table_Rowset_Abstract $rowset,
152                                 $tableName = null)</methodname>
153                         </entry>
155                         <entry>
156                             Create a DataTable Object that is filled with the data from a given
157                             <classname>Zend_Db_Table_Rowset_Abstract</classname> instance. The table
158                             the rowset is connected to is chosen when <varname>$tableName</varname>
159                             is <constant>NULL</constant>.
160                         </entry>
161                     </row>
163                     <row>
164                         <entry>
165                             <methodname>createDbTable(Zend_Db_Table_Abstract $table, $where = null,
166                                 $order = null, $count = null, $offset = null)</methodname>
167                         </entry>
169                         <entry>
170                             Create a DataTable object that represents the data contained in a
171                             <classname>Zend_Db_Table_Abstract</classname> instance. For retrieving
172                             the data <methodname>fetchAll()</methodname> is used, where the optional
173                             parameters can be used to restrict the data table to a certain subset.
174                         </entry>
175                     </row>
177                     <row>
178                         <entry>
179                             <methodname>createDbTableDataSet(array $tables=array())</methodname>
180                         </entry>
182                         <entry>
183                             Create a DataSet containing the given <varname>$tables</varname>, an
184                             array of <classname>Zend_Db_Table_Abstract</classname> instances.
185                         </entry>
186                     </row>
187                 </tbody>
188             </tgroup>
189         </table>
190     </sect3>
192     <sect3 id="zend.test.phpunit.db.testing.controllerintegration">
193         <title>Integrating Database Testing with the ControllerTestCase</title>
195         <para>
196             Because <acronym>PHP</acronym> does not support multiple inheritance it is not possible
197             to use the Controller and Database testcases in conjunction. However you can use the
198             <classname>Zend_Test_PHPUnit_Db_SimpleTester</classname> database tester in your
199             controller test-case to setup a database enviroment fixture for each new controller
200             test. The Database TestCase in general is only a set of convenience functions which can
201             also be accessed and used without the test case.
202         </para>
204         <example id="zend.test.phpunit.db.testing.controllerintegration.example">
205             <title>Database integration example</title>
207             <para>
208                 This example extends the User Controller Test from the
209                 <classname>Zend_Test_PHPUnit_ControllerTestCase</classname> documentation to include
210                 a database setup.
211             </para>
213             <programlisting language="php"><![CDATA[
214 class UserControllerTest extends Zend_Test_PHPUnit_ControllerTestCase
216     public function setUp()
217     {
218         $this->setupDatabase();
219         $this->bootstrap = array($this, 'appBootstrap');
220         parent::setUp();
221     }
223     public function setupDatabase()
224     {
225         $db = Zend_Db::factory(...);
226         $connection = new Zend_Test_PHPUnit_Db_Connection($db,
227                                                       'database_schema_name');
228         $databaseTester = new Zend_Test_PHPUnit_Db_SimpleTester($connection);
230         $databaseFixture =
231                     new PHPUnit_Extensions_Database_DataSet_FlatXmlDataSet(
232                         dirname(__FILE__) . '/_files/initialUserFixture.xml'
233                     );
235         $databaseTester->setupDatabase($databaseFixture);
236     }
238 ]]></programlisting>
240             <para>
241                 Now the Flat <acronym>XML</acronym> dataset "initialUserFixture.xml" is used to set
242                 the database into an initial state before each test, exactly as the DatabaseTestCase
243                 works internally.
244             </para>
245         </example>
246     </sect3>
247 </sect2>