A solid unit test suite is essential for ongoing development in large projects, especially those with many people involved. Going back and manually testing every individual component of an application after every change is impractical. Your unit tests will help alleviate that by automatically testing your application’s components and alerting you when something is not working the same way it was when you wrote your tests.
The Zend Framework 2 API uses PHPUnit, and so does this tutorial application. A detailed explanation of unit testing is beyond the scope of this tutorial, so we will only provide sample tests for the components in the pages that follow. This tutorial assumes that you already have PHPUnit installed.
Setting up the Tests Directory
Start by creating a directory called test in zf2-tutorial\module\Application
with the following subdirectories:
zf2-tutorial/
/module
/Application
/test
/ApplicationTest
/Model
The structure of the test directory matches exactly with that of the module’s source files, and it will allow you to keep your tests well-organized and easy to find.
Bootstrapping Your Tests
Next, create a file called phpunit.xml
under zf2-tutorial/module/Application/test
:
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="Bootstrap.php">
<testsuites>
<testsuite name="zf2tutorial">
<directory>./ApplicationTest</directory>
</testsuite>
</testsuites>
</phpunit>
A file called ServiceManagerGrabber.php
, put it under zf-tutorial/module/Application/test
:
namespace ApplicationTest;
use Zend\ServiceManager\ServiceManager;
use Zend\Mvc\Service\ServiceManagerConfig;
class ServiceManagerGrabber
{
protected static $serviceConfig = null;
public static function setServiceConfig($config)
{
static::$serviceConfig = $config;
}
public function getServiceManager()
{
$configuration =
static::$serviceConfig ?:
require_once "../../../config/application.config.php";
$smConfig = isset($configuration["service_manager"])
? $configuration["service_manager"]
: [];
$serviceManager = new ServiceManager(
new ServiceManagerConfig($smConfig)
);
$serviceManager - gt;
setService("ApplicationConfig", $configuration);
$serviceManager - gt;
get("ModuleManager") - gt;
loadModules();
return $serviceManager;
}
}
A file called Bootstrap.php
, also under zf-tutorial/module/Application/test
namespace ApplicationTest;
use Zend\Loader\AutoloaderFactory;
use Zend\Mvc\Service\ServiceManagerConfig;
use Zend\ServiceManager\ServiceManager;
use RuntimeException;
error_reporting(E_ALL | E_STRICT);
chdir(__DIR__);
/**
* Test bootstrap, for setting up autoloading
*/
class Bootstrap
{
protected static $serviceManager;
public static function init()
{
$zf2ModulePaths = [dirname(dirname(__DIR__))];
if ($path = static::findParentPath("vendor")) {
$zf2ModulePaths[] = $path;
}
if (($path = static::findParentPath("module")) !== $zf2ModulePaths[0]) {
$zf2ModulePaths[] = $path;
}
static::initAutoloader();
// use ModuleManager to load this module and it's dependencies
$config = [
"module_listener_options" => [
"module_paths" => $zf2ModulePaths,
],
"modules" => ["Application"],
];
$serviceManager = new ServiceManager(new ServiceManagerConfig());
$serviceManager->setService("ApplicationConfig", $config);
$serviceManager->get("ModuleManager")->loadModules();
static::$serviceManager = $serviceManager;
ServiceManagerGrabber::setServiceConfig(
require_once "../../../config/application.config.php"
);
}
public static function chroot()
{
$rootPath = dirname(static::findParentPath("module"));
chdir($rootPath);
}
public static function getServiceManager()
{
return static::$serviceManager;
}
protected static function initAutoloader()
{
$vendorPath = static::findParentPath("vendor");
$zf2Path = getenv("ZF2_PATH");
if (!$zf2Path) {
if (defined("ZF2_PATH")) {
$zf2Path = ZF2_PATH;
} elseif (is_dir($vendorPath . "/ZF2/library")) {
$zf2Path = $vendorPath . "/ZF2/library";
} elseif (
is_dir($vendorPath . "/zendframework/zendframework/library")
) {
$zf2Path = $vendorPath . "/zendframework/zendframework/library";
}
}
if (!$zf2Path) {
throw new RuntimeException(
"Unable to load ZF2. Run `php composer.phar install` or" .
" define a ZF2_PATH environment variable."
);
}
if (file_exists($vendorPath . "/autoload.php")) {
include $vendorPath . "/autoload.php";
}
include $zf2Path . "/Zend/Loader/AutoloaderFactory.php";
AutoloaderFactory::factory([
"Zend\Loader\StandardAutoloader" => [
"autoregister_zf" => true,
"namespaces" => [
__NAMESPACE__ => __DIR__ . "/" . __NAMESPACE__,
],
],
]);
}
protected static function findParentPath($path)
{
$dir = __DIR__;
$previousDir = ".";
while (!is_dir($dir . "/" . $path)) {
$dir = dirname($dir);
if ($previousDir === $dir) {
return false;
}
$previousDir = $dir;
}
return $dir . "/" . $path;
}
}
Bootstrap::init();
Bootstrap::chroot();
Create Your Unit Testing Cases
Next, create UserTableTest.php
under zf-tutorial/module/Application/test/ApplicationTest/Model
with the following contents:
namespace Application\Model;
use PHPUnit_Framework_TestCase;
use Zend\Db\ResultSet\ResultSet;
use Application\Model\User;
use Application\Model\UserTable;
use ApplicationTest\ServiceManagerGrabber;
class UserTableTest extends PHPUnit_Framework_TestCase {
protected $serviceManager;
protected $userTable;
public function setUp() {
$serviceManagerGrabber = new ServiceManagerGrabber();
$this->serviceManager = $serviceManagerGrabber->getServiceManager();
$this->userTable = $this->serviceManager->get('Application\Model\UserTable');
}
public function testGetUserUsingUidExists() {
$expectedUser = new User();
$expectedUser->exchangeArray(array(
'uid' => 1001,
'username' => 'zjhzxhz',
'email' => '[email protected]',
));
$actualUser = $this->userTable->getUserUsingUid(1001);
$this->assertEquals($expectedUser, $actualUser);
}
}
Testing
hzxie@XieHaozhe-PC:~/Development/PHP/CourseOcean/module/CourseOcean/tests$ phpunit
PHPUnit 4.5.0 by Sebastian Bergmann and contributors.
Configuration read from /home/hzxie/Development/PHP/CourseOcean/module/CourseOcean/tests/phpunit.xml
....
Time: 52 ms, Memory: 7.25Mb
OK (4 tests, 16 assertions)
The Disqus comment system is loading ...
If the message does not appear, please check your Disqus configuration.