I am trying to learn Unit Testing using Zend Framework. I have set up a test application called LyZend in Github. Supposedly, the application should be able to display artists, albums, and tracks.
The tests are found in: http://github.com/wenbert/lyzend/tree/master/tests/ I have follwed Matthew Weier O’phinney’s method of setting up the tests.
lyzend / tests / TestHelper.php
<?php require_once 'TestConfig.php'; /* * Start output buffering */ ob_start(); /* * Set error reporting to the level to which Zend Framework code must comply. */ error_reporting( E_ALL | E_STRICT ); /* * Set default timezone */ date_default_timezone_set('GMT'); /* * Determine the root, library, tests, and models directories */ $root = realpath(dirname(__FILE__) . '/../'); $library = $root . '/library'; $tests = $root . '/tests'; $models = $root . '/application/models'; $controllers = $root . '/application/controllers'; /* * Prepend the library/, tests/, and models/ directories to the * include_path. This allows the tests to run out of the box. */ $path = array( $models, $library, $tests, get_include_path() ); set_include_path(implode(PATH_SEPARATOR, $path)); /** * Register autoloader */ require_once 'Zend/Loader/Autoloader.php'; //Zend_Loader::registerAutoload(); Zend_Loader_Autoloader::getInstance(); /* * Add library/ and models/ directory to the PHPUnit code coverage * whitelist. This has the effect that only production code source files appear * in the code coverage report and that all production code source files, even * those that are not covered by a test yet, are processed. */ if (defined('TESTS_GENERATE_REPORT') && TESTS_GENERATE_REPORT === true && version_compare(PHPUnit_Runner_Version::id(), '3.1.6', '>=')) { PHPUnit_Util_Filter::addDirectoryToWhitelist($library); PHPUnit_Util_Filter::addDirectoryToWhitelist($models); PHPUnit_Util_Filter::addDirectoryToWhitelist($controllers); } /** * Setup default DB adapter */ /* $db = Zend_Db::factory('pdo_sqlite', array( 'dbname' => $root . '/data/db/bugs.db', )); Zend_Db_Table_Abstract::setDefaultAdapter($db); */ /* * Unset global variables that are no longer needed. */ unset($root, $library, $models, $controllers, $tests, $path); |
You might noticed that I included a TestConfig.php file above. Here is the file:
<?php // Define path to application directory defined('APPLICATION_PATH') || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application')); // Define application environment defined('APPLICATION_ENV') || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'testing')); // Ensure library/ is on include_path set_include_path(implode(PATH_SEPARATOR, array( realpath(APPLICATION_PATH . '/../library'), get_include_path(), ))); |
Here is a sample test for my Artist Model.
lyzend / tests / application / models / ArtistTest.php
<?php // Call Model_ArtistTest::main() if this source file is executed directly. if (!defined("PHPUnit_MAIN_METHOD")) { define("PHPUnit_MAIN_METHOD", "Model_ArtistTest::main"); } require_once dirname(__FILE__) . '/../../TestHelper.php'; /** Model_Artist */ require_once 'Artist.php'; require_once 'ArtistMapper.php'; require_once 'DbTable/Artist.php'; /** * Test class for Model_Artist. * * @group Models */ class Model_ArtistTest extends Zend_Test_PHPUnit_ControllerTestCase { /** * Runs the test methods of this class. * * @return void */ public static function main() { $suite = new PHPUnit_Framework_TestSuite("Model_ArtistTest"); $result = PHPUnit_TextUI_TestRunner::run($suite); } /** * Sets up the fixture, for example, open a network connection. * This method is called before a test is executed. * * @return void */ public function setUp() { $this->bootstrap = new Zend_Application( APPLICATION_ENV, APPLICATION_PATH . DIRECTORY_SEPARATOR . 'configs' . DIRECTORY_SEPARATOR . 'application.ini' ); parent::setUp(); } /** * Tears down the fixture, for example, close a network connection. * This method is called after a test is executed. * * @return void */ public function tearDown() { } public function testCanTest() { //this is a sample test } } |
The XML file is like this:
<phpunit> <testsuite name="Ly Test Suite"> <directory>./</directory> </testsuite> <php> <!-- <ini name="include_path" value="../library"/> --> </php> <filter> <whitelist> <directory suffix=".php">../library/</directory> <directory suffix=".php">../application/</directory> <exclude> <directory suffix=".phtml">../application/</directory> <file>../application/Bootstrap.php</file> <file>../application/controllers/ErrorController.php</file> </exclude> </whitelist> </filter> <logging> <log type="coverage-html" target="./log/report" charset="UTF-8" yui="true" highlight="true" lowUpperBound="50" highLowerBound="80"/> <log type="testdox-html" target="./log/testdox.html" /> </logging> </phpunit> |
Running the test would be something like this:
phpunit --configuration phpunit.xml
Matthew did not provide sample test for Mappers. So I created one something like this:
$mapper = new Ly_Model_ArtistMapper(); $this->assertTrue($mapper instanceof Ly_Model_ArtistMapper); |
My process was like:
- Setup Unit Testing in Zend Framework
- Create tests (let’s say for Artist Model).
- Make code in my model to pass the tests.
- Repeat step 2 and then go to next model if satisfied.
FYI: I am not so sure about my Model. I am not sure if I am breaking any rules when I created them. It would be cool if you could check them out (http://github.com/wenbert/lyzend/tree/master/application/models/) and discuss my mistakes below.
Thanks!
Note that only [integration] tests which involves end-to-end request and controllers (typing an url, asserting that the html response is good) need to use Zend_Test. For testing of your models, mappers, services and so on you just need phpunit with the –bootstrap option.
Thanks for the insight! There is a lot of helpful information within those links.Thanks for sharing..
Website Designing
Thanks, this is very much helpful. Very informative.
Thanks, this pick’s up where Matthew’s leaves off. Very helpful.
Hi.I am trying to create an app using zend framework but i can not seem to find out why my code will not move directories.
can anyone please tell me because with this code :
”
<?php
defined('APPLICATION_ENVIRONMENT')
|| define('APPLICATION_ENVIRONMENT', (getenv('APPLICATION_ENVIRONMENT') ? getenv('APPLICATION_ENVIRONMENT') : 'development'));
define('APP_ROOT', realpath(dirname(dirname(__FILE__))));
set_include_path(implode(PATH_SEPARATOR, array(
dirname(__FILE__) . '../library',
get_include_path(),
)));
print_r(get_include_path());
try
{
require '../application/Bootstrap.php';
}
catch(Exception $exception)
{
echo " an excpetion has occured during bootstrap”;
echo getcwd();
if (defined(APPLICATION_ENVIRONMENT) && APPLICATION_ENVIRONMENT !=’development’)
{
echo “” . $exception->getMessage() . “”
.”" . $exception->getLine() . “”
.”" . $exception->getFile() . “”
.”Stack Trace;”
.”
“;
}
echo “”;
exit(1);
}
//Zend_Controller_Front::getInstance()->dispatch();
?>
”
i get this error in the browser:
/Users/Neri/Sites/360/public../library:.:
Warning: require(../application/Bootstrap.php) [function.require]: failed to open stream: No such file or directory in /Users/Neri/Sites/360/public/index.php on line 22
Fatal error: require() [function.require]: Failed opening required ‘../application/Bootstrap.php’ (include_path=’/Users/Neri/Sites/360/public../library:.:’) in /Users/Neri/Sites/360/public/index.php on line 22″
why why??????