Zend Framework

SimpleTest with Zend Framework – Unit Testing

Actually, Zend Framework has its own unit testing tool using PHPUnit. It is called Zend_Test_PHPUnit*. However, my first encounter with Unit Testing in PHP (actual testing) is with SimpleTest and I easily get acquinted with SimpleTest and I’m very comfortable with it. So I will be using it, until I find a good reason to use PHPUnit.

First, using the standard Zend Framework directory structure, we only need to download SimpleTest library and put it on our project. In my case, I put it inside the public directory beside index.php.

{Project_Dir}
    application
    library
        Zend
        Dc
    resource
        docs
    public
        css
        js
        simpletest {the simpletest lib}
        test {my tests....}

Since ZF needs the bootstrapping thingy, I copied the bootstrap and created a customized one under the test directory.

{tests/bootstrap.php}

<?php

	/**
	 * Part 1 of initialization: Global Constants for Paths
	 * 
	 */
	define('PUBLIC_WEB_PATH', '/');
	define('INDEX_PATH', str_replace('\\', '/', realpath(dirname(__FILE__) . '/../')));
	define('APPLICATION_PATH', str_replace('\\', '/', realpath(INDEX_PATH . '/../application')));
	define('LIBRARY_PATH', str_replace('\\', '/', realpath(INDEX_PATH . '/../library')));
	set_include_path(
			LIBRARY_PATH
			. PATH_SEPARATOR
			. get_include_path()
		);
	
	require_once 'Zend/Loader.php';
	
	Zend_Loader::registerAutoload();
	
	/**
	 * General Bootstrap
	 */
	 
	defined('APPLICATION_PATH')
	    or define('APPLICATION_PATH', dirname(__FILE__));
	    

	defined('APPLICATION_ENVIRONMENT')
	    or define('APPLICATION_ENVIRONMENT', 'development');

	$frontController = Zend_Controller_Front::getInstance();
	

	/**
	 * Point controllers directory to your app controller directory
	 */
	$frontController->setControllerDirectory(APPLICATION_PATH . '/controllers');
	

	/**
	 * Set environment flag indicator
	 */
	$frontController->setParam('env', APPLICATION_ENVIRONMENT);
	
	
	/**
	 * Setup the layout
	 */
	Zend_Layout::startMvc(APPLICATION_PATH . '/layouts/scripts');
	

	/**
	 * Setup layout view
	 */
	$view = Zend_Layout::getMvcInstance()->getView();
	$view->doctype('XHTML1_STRICT');
	

	/*
	 * Setup configurations
	 */
	
	$configuration = new Zend_Config_Ini(
	    APPLICATION_PATH . '/config/project_config.ini', 
	    APPLICATION_ENVIRONMENT
	);
	
	$messages = new Zend_Config_Ini(
	    APPLICATION_PATH . '/config/project_messages.ini', 
	    APPLICATION_ENVIRONMENT
	);
				
	$dbAdapter = Zend_Db::factory($configuration->database);
	
	/**
	 * Setup dbAdapter to our tables
	 */
	Zend_Db_Table::setDefaultAdapter($dbAdapter);
	
	/**
	 * Create cache for Db metadata
	 */
	$frontendOptions = array( 
	                    'lifetime'                  => 25200, 
	                    'automatic_serialization'   => true 
	                    ); 
	$backendOptions  = array( 
	                     'cache_dir'                => APPLICATION_PATH . '/tmp' 
	                    ); 
	$dbCache = Zend_Cache::factory( 
	                    'Core', 
	                    'File', 
	                    $frontendOptions, 
	                    $backendOptions 
	                    ); 
	/**
	 * Cache table metadata
	 */ 
	Zend_Db_Table_Abstract::setDefaultMetadataCache($dbCache);
	
	/**
	 * General caching
	 */ 
	$frontendOptions = array( 
	                    'lifetime'                  => 3600, 
	                    'automatic_serialization'   => true 
	                    ); 
	$backendOptions  = array( 
	                     'cache_dir'                => APPLICATION_PATH . '/tmp' 
	                    ); 
	$cache = Zend_Cache::factory( 
	                    'Core', 
	                    'File', 
	                    $frontendOptions, 
	                    $backendOptions 
	                    );  
	
	/**
	 * Plugin Loader caching
	 */
	$classFileIncCache = APPLICATION_PATH .  '/data/pluginLoaderCache.php'; 
	if (file_exists($classFileIncCache))
	{ 
	    include_once $classFileIncCache; 
	} 
	Zend_Loader_PluginLoader::setIncludeFileCache($classFileIncCache); 
	
	/**
	 * Save objects to registry
	 */
	$registry = Zend_Registry::getInstance();
	$registry->set('configuration', $configuration);
	$registry->set('dbAdapter', $dbAdapter);
	$registry->set('messages', $messages);
	$registry->set('cache', $cache);
	
	header ('Content-type: text/html; charset=utf-8');
	$dbAdapter->query('SET NAMES utf8');
	
	Zend_Locale::setDefault('en_US');
	Zend_Session::start();
	
	/**
	 * Setup the Custom Helpers
	 */
	Zend_Controller_Action_HelperBroker::addPrefix('Dc_Helper');
	
	/**
	 * Cleanup
	 */
	unset($frontController, $view, $configuration, $dbAdapter, $registry);
	unset($backendOptions, $cache, $frontendOptions, $messages, $dbCache);

Then everytime I need to test for example, I will just create another file under tests folder like this:

{tests/test_holiday.php}

<?php

require_once 'bootstrap.php';
require_once INDEX_PATH . '/simpletest/autorun.php';
require_once APPLICATION_PATH . '/models/Holidays.php';

Mock::generate('Model_Holidays');

class TestHoliday extends UnitTestCase
{
	function testCreate()
	{
		$holiday = new Model_Holidays;
		$this->assertIsA($holiday, 'Model_Holidays');
		$this->assertTrue($holiday->getHolidaysByDate('2007-11-1', '2007-11-30'));
	}
	
	function testGetHolidaysByYear()
	{
		$holiday = new Model_Holidays;
		$this->assertIsA($holiday, 'Model_Holidays');
		
		$ret = $holiday->getHolidaysByYear(2007);
		$this->assertIsA($ret, 'array');
	}
	
	function testAddMockHoliday()
	{
		$holMock = new MockModel_Holidays;
		$holMock->expectOnce(
						'add',
						array(
							array(
								'Holiday' 	=> '2009-01-01',
								'Name' 		=> 'New Year'
								)
							)
						);
						
		$holMock->setReturnValue('add', true);
		
		$ret = $holMock->add(
					array(
						'Holiday' 	=> '2009-01-01',
						'Name' 		=> 'New Year'
						)
					);
					
		$this->assertTrue($ret);
	}
	
	function testAddHoliday()
	{
		$hol = new Model_Holidays;
		
		$data = array(
					'Holiday'	=> '2009-01-01',
					'Name'		=> 'New Year'
					);
					
		//$ret = $hol->add($data);
		//$this->assertTrue($ret);
	}
	
	function testGetHoliday()
	{
		$hol = new Model_Holidays;
		
		$ret = $hol->getHoliday('2007-11-01');
		$this->assertTrue($ret);
	}
}//end class

To preview the test: http://my-server:8002/tests/test_holiday.php
(using custom port)

All I need to do is to include the bootstrap file then do normally as if I’m on ZF while testing.

So far, I’m playing only with Models.

One big problem that I’ve encountered is that most of the probably buggy portion of my codes could be in the
controller and not in models. I’m still having difficulties testing controllers right now.

But in general, I enjoyed testing.
Thanks to the TDD master for the slides. 🙂

4 thoughts on “SimpleTest with Zend Framework – Unit Testing”

  1. Deprecated since Zend Framework 2. I need the same exemple Zend Framework 2. Can you do the same thing with ZF2 please ?

    Thx !

  2. Better use the officially supported unit test framework. I think ZF2 uses PHPUnit so just use it, it’s better that way.

  3. Yes, I know it. But I need SimpleTest for several integration testing and web testing.

Leave a reply

Your email address will not be published. Required fields are marked *