Skip to end of metadata
Go to start of metadata

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[

Zend Framework: Zend_Test_PHPUnit_Database Component Proposal

Proposed Component Name Zend_Test_PHPUnit_Database
Developer Notes
Proposers Benjamin Eberlei
Zend Liaison Matthew Weier O'Phinney
Revision 1.0 - 5 February 2009: Initial Draft. (wiki revision: 10)

Table of Contents

1. Overview

The PHPUnit Database Extension is very PDO centric and may hinder people
using Zend_Db to effectivly write Database related tests. This proposal
is for a subcomponent in the Zend_Test namespace that implementes the
necessary interfaces of the PHPUnit_Extensions_Database to make this tool
work with Zend_Db_Adapter_Abstract connections.

It would also allow for a very simple integration of a Zend_Db_Table implementation
as a dataset which would make testing against Zend_Db_Table and corresponding
Zend_Db_TableRowset instances a bit more convenient.

Additionally the profiler does much work on counting queries and stuff, which could
also be integrated as additional assertions.

2. References

3. Component Requirements, Constraints, and Acceptance Criteria

  • This component MUST allow using Zend_Db_Adapter_Abstract in conjunction with PHPUnits database extension.
  • This component MUST allow using Zend_Db_Table implementations as DataSets to test against.
  • This component MUST add new constraints for use with the Zend_Db_Profiler

4. Dependencies on Other Framework Components

  • Zend_Db_Adapter_Abstract
  • Zend_Db_Table
  • PHPUnit

5. Theory of Operation

Operation with this component would be exactly the same as in the current PHPUnit Database Extension.

You seed the database with a default dataset and perform operations the database as you would in normal production enviroment. At any stage you can assert weater two datasets are equal, which proves test-success.

Step by step:

1. At each testrun, PHPUnit clears the database and refills it with the Seed Data you are giving to it.
2. You perform database operations.
3. You assert that the content of two datasets are the same, where a dataset is an abstract definition of rows in a table.

Datasets come from very different sources: Flat XML format, a more complex XML format, in the next version YAML, from other database tables and from CSV-Files.

PHPUnits Database Extension puts those into a common format and allows them to be comparable so that you can check for example weater the contents of a database table equal the contents in a given XML file after you performed some operations in the test-case.

6. Milestones / Tasks

  • Milestone 1: Proposal, Community Review and Acceptance
  • Milestone 2: Unit-Testing and Development
  • Milestone 3: Documentation and Testing

7. Class Index

  • Zend_Test_PHPUnit_DatabaseTestCase
  • Zend_Test_PHPUnit_Database_Connection
  • Zend_Test_PHPUnit_Database_DataSet_ZendDbTable
  • Zend_Test_PHPUnit_Database_DataSet_RowSet
  • Zend_Test_PHPUnit_Database_Metadata_Generic
  • Zend_Test_PHPUnit_Database_Operation_*

8. Use Cases

9. Class Skeletons



Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Feb 05, 2009

    <p>Can you talk about where (in the current project structure) database fixtures (and other testing data) would go?</p>

    <p>Does this mean that the schema needs to be defined somewhere so that a full build up and breakdown can be used? If this is the case, where does the schema go in the project structure?</p>

    <p>I think we need to start discussing how we are gonna manage the tearing up and breaking down of a projects sql ddl and dml files.</p>

    1. Feb 05, 2009

      <p>PHPUnit Database extension takes the Schema as a given. It has to be able to accept the seed-data as input. Therefore you it has to be installed on the database beforehand.</p>

    2. Feb 06, 2009

      <ac:macro ac:name="unmigrated-wiki-markup"><ac:plain-text-body><![CDATA[i agree, currently i use the following which takes an sql file. The table is dropped if it exists, which i don't like and should change.


      protected function _loadDbSchema()
      $schemaFile = Zend_Registry::get('testDbSchemaPath');
      $schema = file_get_contents($schemaFile);
      $statements = explode(';', $schema);

      $db = $this->_db;
      $conn = $db->getConnection();

      $filter = new Zend_Filter_StringTrim();

      foreach ($statements as $statement)

      Unknown macro: { $statement = $filter->filter($statement); $conn->exec($statement); }



      -- Table structure for table `name`

      DROP TABLE IF EXISTS `name`;
      `id` int(11) NOT NULL auto_increment,
      `name` varchar(255) collate utf8_unicode_ci NOT NULL,
      `date_created` date default NULL,
      PRIMARY KEY (`id`)
      ) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

      I place my test db schema file in the application config folder and register it in my testHelper to "testDbSchemaPath" and simply call it when needed:
      $schemaFile = Zend_Registry::get('testDbSchemaPath');

      I think this is better because it doesn't matter where it is.
      That said there could be a default, maybe a _files/schema folder below the actual Class?


      $path = realpath(dirname(_FILE_) . '/../')) . '/_files/schema;

      $sql = $path . '/db-schema.sql
      $xml = $path . '/db-schema.xml


  2. Feb 26, 2009

    <p>Ben, there was some talk at one point about pushing the DBUnit provider and assertions into classes that could be consumed from within a generic PHPUnit_Framework_TestCase. Can you verify if this has been done? if so, would this proposal target such an approach?</p>

    <p>The reason I ask is that, for the larger goal of functional testing, it would be handy to have the ability to grab a DB provider, do your seeding, and then do assertions against the DB following an operation. Right now, the way your proposal stands, you would not be able to do that as the DBUnit integration uses its own specialized test case.</p>

    1. Feb 26, 2009

      <p>the testcase is jsut for convenience, it only consists of methods that proxy to classes to make it easier to work with. Its perfectly possible to do seeding from any testcase base class, if you know how to do it.</p>

      <p>this is a good point, which needs documentation and i will make sure to write a bigger example part on the cases where you cannot work with the DatabaseTestCase class.</p>

  3. Mar 27, 2009

    <ac:macro ac:name="note"><ac:parameter ac:name="title">Zend Acceptance</ac:parameter><ac:rich-text-body>
    <p>This proposal is accepted for immediate development in the standard incubator, with one minor change:</p>
    <li>Zend_Test_PHPUnit_Database_ namespace to be renamed to Zend_Test_PHPUnit_Db (for consistency with the Zend_Db namespace)</li>