Back to Home

Development through testing with Zend Framework and PHPUnit

php · zend framework · tdd · PHPUnit

Development through testing with Zend Framework and PHPUnit

Original author: Srirangan
  • Transfer
After spending the last few days studying the documentation on the Zend Framework, I was pleasantly surprised by the new functionality that was added to the latest version of this web application framework.
My first thought was to realize the speed with which PHP technology is growing.
The ease of sharing Zend Framework and PHPUnit is, in my opinion, one of the most significant achievements.


I’ve already done enough work with PHPUnit to understand how powerful, customizable and easy to
use it is (it belongs to the xUnit family of test frameworks), however, the most remarkable thing is that the Zend Framework is completely ready to work with PHPUnit (in my opinion, this willingness will allow you to choose Zend Framework for any PHP project, but this is a topic for another post ...).

Here's what we know about PHPUnit: you can not only modularly test your PHP classes, but also create dependencies between tests, use dataProviders to increase the sample size of input test parameters, and test exceptions and errors .

In addition, PHPUnit allows you to do the following: organize tests , provide database testingperform double testing to cover the source code, and, moreover, can be used for quick documentation .
In conclusion, I note that PHPUnit works very well in conjunction with Selenium, Apache Ant, Apache Maven, Phing, Atlassian Bamboo, CruiseControl and other environments.

I can only refer to the documentation on PHPUnit and you can return to the main topic of the article.

According to the directory structure of the Zend Framework project, it is clearly seen that the authors of the Zend Framework have always paid great attention to the development through testing methodology. In the official documentation, reference materials, literature, the place of the catalog for tests in the overall structure of the project is emphasized. You can talk about "Zend PHP development path"( "Zend way of PHP development" ).
In a more detailed study, in the Zend_Test package we will find the Zend_Test_PHPUnit and Zend_Test_PHPUnit_Db classes that are inherited from PHPUnit.

Zend_Test_PHPUnit provides classes that can be used to test the framework’s MVC classes.
In the most typical case, the class for testing the controller will be the descendant of Zend_Test_PHPUnit_ControllerTestCase.
The following is an example class for testing a controller.

class UserControllerTest extends Zend_Test_PHPUnit_ControllerTestCase
{
    public function setUp()
    {
        $this->bootstrap = array($this, 'appBootstrap');
        parent::setUp();
    }

    public function appBootstrap()
    {
        $this->frontController
             ->registerPlugin( new Bugapp_Plugin_Initialize('development'));
    }

    public function testCallWithoutActionShouldPullFromIndexAction()
    {
        $this->dispatch('/user');
        $this->assertController( 'user');
        $this->assertAction('index');
    }

    public function testIndexActionShouldContainLoginForm()
    {
        $this->dispatch( '/user');
        $this->assertAction('index');
        $this->assertQueryCount('form#loginForm', 1);
    }

    public function testValidLoginShouldGoToProfilePage()
    {
        $this->request->setMethod('POST')
             ->setPost(array(
                 'username' => 'foobar',
                 'password' => 'foobar'
             ));
        $this->dispatch('/user/login');
        $this->assertRedirectTo('/user/view');

        $this->resetRequest()
             ->resetResponse();

        $this->request->setMethod('GET')
             ->setPost(array());
        $this->dispatch('/user/view');
        $this->assertRoute('default');
        $this->assertModule('default');
        $this->assertController('user');
        $this->assertAction('view');
        $this->assertNotRedirect();
        $this->assertQuery('dl');
        $this->assertQueryContentContains('h2', 'User: foobar');
    }
}

* This source code was highlighted with Source Code Highlighter.

Zend_Test_PHPUnit_Db inherits the PHPUnit database extension with Zend Framework specific code, which makes it much
easier to write tests for the database.
The following is the test:

class BugsTest extends Zend_Test_PHPUnit_DatabaseTestCase
{
    private $_connectionMock;

    /**
     * Возвращает тестовое соединение с базой данных.
     *
     * @return PHPUnit_Extensions_Database_DB_IDatabaseConnection
     */
    protected function getConnection()
    {
         if($this->_connectionMock == null) {
            $connection = Zend_Db::factory(...);
            $this->_connectionMock = $this->createZendDbConnection(
                $connection, 'zfunittests'
            );
            Zend_Db_Table_Abstract::setDefaultAdapter($connection);
        }
         return $this->_connectionMock;
    }

    /**
     * @return PHPUnit_Extensions_Database_DataSet_IDataSet
     */
    protected function getDataSet()
    {
        return $this->createFlatXmlDataSet(
            dirname(__FILE__) . '/_files/bugsSeed.xml'
        );
    }
}

* This source code was highlighted with Source Code Highlighter.

When your application is almost finished, it will be appropriate to conduct functional testing.
Together with the Zend Framework with PHPUnit support, the Selenium IDE can be used.
There are tests that mimic end-user behavior and are designed to test usability, security, and performance.

The regular Selenium test inherits from PHPUnit_Extensions_SeleniumTestCase and looks something like this:

require_once 'PHPUnit/Extensions/SeleniumTestCase.php';
class seleniumExampleTest extends PHPUnit_Extensions_SeleniumTestCase
{
 protected function setUp()
 {
     $this->setBrowser('*firefox');
     $this->setBrowserUrl('http://www.google.com.au/');
 }
 function testMyTestCase()
 {
     $this->open('http://www.google.com.au/');
     $this->type('q', 'zend framework');
     $this->click('btnG');
     $this->waitForPageToLoad('30000');
     try {
         $this->assertTrue($this->isTextPresent('framework.zend.com/'));
     } catch (PHPUnit_Framework_AssertionFailedError $e) {
         array_push($this->verificationErrors, $e->toString());
     }
 }
}

* This source code was highlighted with Source Code Highlighter.

This article is not affected by a small proportion of all the testing capabilities.
The purpose of this article is to show that the Zend framework is very closely integrated into its environment and that
this integration helps a group of PHP users to use
the development through testing (TDD) technology in practice .
Use these features to improve the quality of your products.

Read Next