Hi,
Process of setup PHPUnit testing in Zend Framework-2:
NOTE: Before starting to describe the process of PHPUnit i assuming that readers are aware of Zend Framework-2.
Step 1: PHPUnit Installation with the help of "Pear"
# pear config-set auto_discover 1
# pear install pear.phpunit.de/PHPUnit
Step 2: Create "test" directory inside your module.
Step 3: create phpunit.xml, TestConfig.php and Bootstrap.php file inside the "test" directory.
phpunit.xml File
TestConfig.php
Bootstrap.php
Step 4: Create directory for module testing inside the "test" directory. Name should be same as the module name.
EX: if your module name is "Report" then your testing module-name would be "ReportTest"
Step 5: Create Controller directory whose name would be "Controller" inside the Test module i.e. "ReportTest"
Step 6: Create controller class file inside your controller dir, named as your main module controller file-name.
ex: your module controller name as "IndexController" then test-module controller file name should be "IndexControllerTest".
IndexControllerTest.php
Now your directory structure would look like as:
Step 7: Run the phpunit inside of the "test" directory. then you will see some output if your test run successfully like as :
#phpunit
PHPUnit 4.1.3 by Sebastian Bergmann.
..
Time: 00:00
OK (2 tests)
Step 8: Some time you will get error, then there would be some code return that has some significant role like as:
. Printed when the test succeeds.
F Printed when an assertion fails while running the test method.
E Printed when an error occurs while running the test method.
S Printed when the test has been skipped.
I Printed when the test is marked as being incomplete or not yet implemented.
Process of setup PHPUnit testing in Zend Framework-2:
NOTE: Before starting to describe the process of PHPUnit i assuming that readers are aware of Zend Framework-2.
Step 1: PHPUnit Installation with the help of "Pear"
# pear config-set auto_discover 1
# pear install pear.phpunit.de/PHPUnit
Step 2: Create "test" directory inside your module.
Step 3: create phpunit.xml, TestConfig.php and Bootstrap.php file inside the "test" directory.
phpunit.xml File
<?xml version="1.0" encoding="UTF-8"?> <phpunit bootstrap="Bootstrap.php"> <php> <!--server name="SERVER_PORT" value="80"/ --> </php> <testsuites> <testsuite name="Demo PHPUnit"> <directory>./ApplicationTest</directory> </testsuite> </testsuites> </phpunit>
TestConfig.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <?php return array( 'modules' => array( // Other modules needed 'Application', ), 'module_listener_options' => array( 'config_glob_paths' => array( '../../../config/autoload/{,*.}{global,local}.php', ), 'module_paths' => array( 'module', 'vendor', ), ), ); |
Bootstrap.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | <?php namespace ApplicationTest; // our namespace use Zend\Loader\AutoloaderFactory; use Zend\Mvc\Service\ServiceManagerConfig; use Zend\ServiceManager\ServiceManager; use Zend\Stdlib\ArrayUtils; use RuntimeException; use Zend\Session\Container; error_reporting(E_ALL | E_STRICT); chdir(__DIR__); class Bootstrap { protected static $serviceManager; protected static $config; protected static $bootstrap; public static function init() { // Load the user-defined test configuration file, if it exists; otherwise, load if (is_readable(__DIR__ . '/TestConfig.php')) { $testConfig = include __DIR__ . '/TestConfig.php'; } else { $testConfig = include __DIR__ . '/TestConfig.php.dist'; } $zf2ModulePaths = array(); if (isset($testConfig['module_listener_options']['module_paths'])) { $modulePaths = $testConfig['module_listener_options']['module_paths']; foreach ($modulePaths as $modulePath) { if (($path = static::findParentPath($modulePath)) ) { $zf2ModulePaths[] = $path; } } } $zf2ModulePaths = implode(PATH_SEPARATOR, $zf2ModulePaths) . PATH_SEPARATOR; $zf2ModulePaths .= getenv('ZF2_MODULES_TEST_PATHS') ?: (defined('ZF2_MODULES_TEST_PATHS') ? ZF2_MODULES_TEST_PATHS : ''); static::initAutoloader(); // use ModuleManager to load this module and it's dependencies $baseConfig = array( 'module_listener_options' => array( 'module_paths' => explode(PATH_SEPARATOR, $zf2ModulePaths), ), ); $config = ArrayUtils::merge($baseConfig, $testConfig); $serviceManager = new ServiceManager(new ServiceManagerConfig()); $serviceManager->setService('ApplicationConfig', $config); $serviceManager->get('ModuleManager')->loadModules(); static::$serviceManager = $serviceManager; static::$config = $config; } public static function getServiceManager() { return static::$serviceManager; } public static function getConfig() { return static::$config; } protected static function initAutoloader() { $vendorPath = static::findParentPath('vendor'); if (is_readable($vendorPath . '/autoload.php')) { $loader = include $vendorPath . '/autoload.php'; } else { $zf2Path = getenv('ZF2_PATH') ?: (defined('ZF2_PATH') ? ZF2_PATH : (is_dir($vendorPath . '/ZF2/library') ? $vendorPath . '/ZF2/library' : false)); if (!$zf2Path) { throw new RuntimeException('Unable to load ZF2. Run `php composer.phar install` or define a ZF2_PATH environment variable.'); } include $zf2Path . '/Zend/Loader/AutoloaderFactory.php'; } AutoloaderFactory::factory(array( 'Zend\Loader\StandardAutoloader' => array( 'autoregister_zf' => true, 'namespaces' => array( __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(); |
Step 4: Create directory for module testing inside the "test" directory. Name should be same as the module name.
EX: if your module name is "Report" then your testing module-name would be "ReportTest"
Step 5: Create Controller directory whose name would be "Controller" inside the Test module i.e. "ReportTest"
Step 6: Create controller class file inside your controller dir, named as your main module controller file-name.
ex: your module controller name as "IndexController" then test-module controller file name should be "IndexControllerTest".
IndexControllerTest.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | <?php namespace ApplicationTest\Controller; use ApplicationTest\Bootstrap; use Zend\Mvc\Router\Http\TreeRouteStack as HttpRouter; use Application\Controller\IndexController; use Zend\Http\Request; use Zend\Http\Response; use Zend\Mvc\MvcEvent; use Zend\Mvc\Router\RouteMatch; use Zend\Test\PHPUnit\Controller\AbstractControllerTestCase; // use Zend\Test\PHPUnit\Controller\AbstractHttpControllerTestCase; class IndexControllerTest extends AbstractControllerTestCase { protected $controller; protected $request; protected $response; protected $routeMatch; protected $event; protected $userMockObj; protected $serviceManager; public function setUp() { $this->serviceManager = Bootstrap::getServiceManager(); $this->controller = new IndexController(); $this->request = new Request(); $this->routeMatch = new RouteMatch(array('controller' => 'index')); $this->event = new MvcEvent(); $config = $this->serviceManager->get('Config'); $routerConfig = isset($config['router']) ? $config['router'] : array(); $router = HttpRouter::factory($routerConfig); $this->event->setRouter($router); $this->event->setRouteMatch($this->routeMatch); $this->controller->setEvent($this->event); $this->controller->setServiceLocator($this->serviceManager); $this->userMockObj = $this->getMockBuilder('Application\Model\TestModel') ->disableOriginalConstructor() ->getMock(); $this->setApplicationConfig( include __DIR__.'/../../TestConfig.php' ); parent::setUp(); } public function testWorkAction() { $this->serviceManager->setAllowOverride(true); $this->serviceManager->setService('Application\Model\TestModel', $this->userMockObj); $this->routeMatch->setParam('action', 'work'); $response = $this->controller->getResponse(); $result = $this->controller->dispatch($this->request, $response); $this->assertEquals(200, $response->getStatusCode()); // Check a ViewModel has been returned $this->assertInstanceOf('Zend\View\Model\ViewModel', $result); // Test against the test data $variables = $result->getVariables(); $this->assertArrayHasKey('name', $variables); // Very lazy validation of data ;-) $this->assertEquals('OSSCube1', $variables["name"]); $this->dispatch('/index'); $this->assertModuleName('Application'); $this->assertControllerClass('IndexController'); $this->assertMatchedRouteName('xyz'); $this->assertControllerName('Application\Controller\Index'); } public function testMemory() { $this->assertGreaterThanOrEqual(699328, memory_get_usage()); } } ?> |
Now your directory structure would look like as:
Step 7: Run the phpunit inside of the "test" directory. then you will see some output if your test run successfully like as :
#phpunit
PHPUnit 4.1.3 by Sebastian Bergmann.
..
Time: 00:00
OK (2 tests)
Step 8: Some time you will get error, then there would be some code return that has some significant role like as:
. Printed when the test succeeds.
F Printed when an assertion fails while running the test method.
E Printed when an error occurs while running the test method.
S Printed when the test has been skipped.
I Printed when the test is marked as being incomplete or not yet implemented.
Step 9: To get the html report for the code coverage analysis of your code, it's a
feature of the phpunit to get the beautiful html formatted dashboard and reports.
To get this feature you have to install the PHP xDebug module.
# sudo pecl install xdebug
Now, You can create the report by the below command:
# phpunit --coverage-html dir-name
# phpunit --coverage-html dir-name
Here, dir-name is the directory where you will put the report content. It will take bit of time to generate the html report. Once your report generated then just open the index.html file in your browser....