Welcome to Abdul Malik Ikhsan's Blog

Zend Framework 2 : Centralize phpunit test

Posted in testing, Tutorial PHP, Zend Framework 2 by samsonasik on November 19, 2013

zf2-zendframework2 Centralize phpunit test is good when we work at integration test to test all modules we have created. What we need is place autoloader at Bootstrap file, and make ‘ServiceManager Grabber’ to grab services over modules.

1. Preparation :
a. Create tests folder at our ZF2 Application.
At this phase, we added Bootstrap.php and phpunit.xml as configuration.
b. Write Bootstrap.php

//we create ServiceManagerGrabber class later...
use ModulesTests\ServiceManagerGrabber; 

error_reporting(E_ALL | E_STRICT);

$cwd = __DIR__;

// Assume we use composer
$loader = require_once  './vendor/autoload.php';
$loader->add("ModulesTests\\", $cwd);

ServiceManagerGrabber::setServiceConfig(require_once './config/application.config.php');

c. Write phpunit.xml
We register module that we add directory of module tests, at this case, named “ModulesTests”.

<?xml version="1.0" encoding="UTF-8"?>


        <testsuite name="sanzf2">
            <directory suffix=".php">./ModulesTests</directory>

d. Based on the phpunit.xml, we then need to create directory named “ModulesTests” to collect test for modules.

e. Create ServiceManager Grabber ( as you can see at “ModulesTests” folder )

//inspired from https://github.com/doctrine/DoctrineModule/blob/master/tests/DoctrineModuleTest/ServiceManagerTestCase.php
// thanks to Marco Pivetta

namespace ModulesTests;

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'] : array();
        $serviceManager = new ServiceManager(new ServiceManagerConfig($smConfig));
        $serviceManager->setService('ApplicationConfig', $configuration);
        return $serviceManager;

This class will grab the our ZF2 application config, load Modules, that means the serviceManager of all modules will be returned.

f. create per-module test case
At this case, I added directory named “SanDbModellingWithZendDbTest” to test my “SanDbModellingWithZendDb” module. It’s up to us to create other name, or collect or not collect module per directory, but for my perspective, it should be on separate folder per-module test.

2. Write a Test
The test can be formatted like the following :

namespace ModulesTests\SanDbModellingWithZendDbTest\Model;

use PHPUnit_Framework_TestCase;
use ModulesTests\ServiceManagerGrabber;

class AlbumTrackMapperTest extends PHPUnit_Framework_TestCase
    protected $serviceManager;
    public function setUp()
        $serviceManagerGrabber   = new ServiceManagerGrabber();
        $this->serviceManager = $serviceManagerGrabber->getServiceManager();
    public function testJoinLeft()
        $count =  count($this->serviceManager->get('AlbumTrackMapper')->findAll());
        ($count > 0 ) ? $this->assertNotEmpty($count) : $this->assertEmpty($count);
  1. Run Test
    We just need to go to tests folder with command line :
$ cd ~/yourzf2app/tests
$ phpunit

And you will get this :

Of course, we can add more folders under “ModulesTests” folder.

Thanks to Marco Pivetta that give me enlightenment to not share one ServiceManager accross different tests.

Done 😉

19 Responses

Subscribe to comments with RSS.

  1. Max Gulturyan said, on November 19, 2013 at 4:30 pm

    1. Every module must contain own tests
    2. General tests mus run all modules tests? like this:




    setService(‘ApplicationConfig’, $config);

    public static function getServiceManager() {
    return static::$serviceManager;

    private static function loadModules(array $modules) {
    foreach ($modules as $moduleName) {
    include SITE_PATH . “/module/$moduleName/Module.php”;



  2. Max Kucher said, on November 19, 2013 at 4:38 pm



  3. Artur Bodera said, on November 19, 2013 at 6:30 pm

    That “ob_start();” is redundant – that’s up to phpunit to handle.

    Module tests should live under module dirs, and then it is trivial to include those test suites in phpunit.xml. This makes more sense in zf2 module-oriented context and would allow for easier module promotion in the future.

    phpunit.xml i.e.:



    • Artur Bodera said, on November 19, 2013 at 6:30 pm

      The above included xml but your wordpress ate that 😛

      • samsonasik said, on November 19, 2013 at 8:58 pm

        Thanks Artur. Yes, of course. the ob_start() is to prevent when header happen accidentally at the test. and for module test, we should provide in module where we provide individually for promotion :P.
        But for whole application, I personally like copy them at one folder :).

  4. Gauthier Delamarre said, on December 18, 2013 at 8:31 pm

    I’m sorry to disagree with both you and Marco, but in my opinion, there should be no Service Manager at all.

    Classes making use of ServiceManager should be provided with a mocked ServiceManager whenever it’s necessary for the current test only… and it should also return mocked services, not actual services.

    If you absolutely need the ServiceManager with the actual application configuration, so probably isn’t your test a unit test, but rather a functional test 😉

  5. Chris said, on January 9, 2014 at 9:36 am

    I like this idea. However, what are you doing for loading Classes?

    PHP Fatal error: Class ‘MyModule\Mapper\User’ not found in /var/www/somesite.com/htdocs/tests/ModulesTests/MyModuleTest/Mapper/UserTest.php on line 15

    and i’m declaring it as: 15) $foo = new \MyModule\Mapper\User();

    • samsonasik said, on January 9, 2014 at 1:38 pm

      nothing, just define getAutoloaderConfig() at your Module class with common code for that function. You should have MyModule\Mapper (represented as folders) namespace under MyModule/scr folder

      • Chris said, on January 9, 2014 at 8:13 pm

        Hurrah! Thanks for the tip. I placed

        public function setUp()
        ‘Zend\Loader\ClassMapAutoloader’ => array(
        __DIR__ . ‘/autoload_classmap.php’,
        ‘Zend\Loader\StandardAutoloader’ => array(
        ‘namespaces’ => array(
        __NAMESPACE__ => __DIR__ . ‘/src/’ . __NAMESPACE__
        $this->mapper = new \MyModule\Mapper\User();

        in the TestModule and this connected. I think that’s what you meant to do. This won’t drag performance down, if I have a lot of test models/mappers will it?

      • samsonasik said, on January 9, 2014 at 9:49 pm

        no, place that at Module Class, see the docs please http://zf2.readthedocs.org/en/latest/user-guide/modules.html and configure Bootstrap.php correctly.

      • Chris said, on January 10, 2014 at 12:16 am

        Done. Much appreciated. This will help a LOT with getting phpunit kicked off with the git pre-commit/pre-receive hooks and kicking off a Jenkins job.

        Do you use the phpunit code coverage tool, how useful is it to you?

      • samsonasik said, on January 10, 2014 at 9:42 am

        yes, I used what @ocramius provide http://ocramius.github.io/blog/automated-code-coverage-check-for-github-pull-requests-with-travis/ it is very usefull when I’m too lazy to check deploy on jenkins.

  6. Rayhan said, on January 19, 2014 at 6:48 am

    Thank you so much. This is exaclty what I was looking for. I’ll try this as soon as can.

  7. Azhar said, on August 22, 2014 at 6:05 pm

    is the where method matches the string into database by using Db\sql like you are using the below code ???

    $select->where(array(‘title’ => ‘abracadabra’));

  8. Joao Marcos said, on June 25, 2020 at 9:22 pm

    Thank you a lot! I’m working on a legacy ZF2 application, and your article really helped me starting to introduce tests in this application. Thanks a million times!!

  9. Sandro said, on February 26, 2021 at 1:40 am

    When using AbstractHttpControllerTestCase I get a ServiceNotFoundException:
    Zend\ServiceManager\Exception\ServiceNotFoundException: Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for ApplicationConfig
    Any idea how to fix this?

    • samsonasik said, on February 26, 2021 at 8:02 am

      You may need to follow the tutorial in documentation for it https://docs.zendframework.com/tutorials/unit-testing/ , better use laminas for new project https://docs.laminas.dev/tutorials/unit-testing/ .

      • Sandro said, on February 26, 2021 at 3:47 pm

        It is a legacy project unfortunately. The tutorial doesn’t explain everything, after spending a few hours trying to get doctrine to work, I then get an empty output from PHPUnit, no errors or whatsoever even though I set it to show errors.
        Your tutorial is the only one that worked, and I like the idea of centralizing tests. I have solved that exception by bootstrapping the application and setting it directly, however I have another error with routes not found.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: