Welcome to Abdul Malik Ikhsan's Blog

Unit and Functional testing Zend Framework 3 Controller with Kahlan 3.0

Posted in testing, Tutorial PHP, Zend Framework 2 by samsonasik on October 24, 2016

This post will cover unit and functional testing ZF3 Controller with Kahlan 3.0. For example, you have a ZF3 Skeleton application with an IndexController like the following:

namespace Application\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;

class IndexController extends AbstractActionController
    public function indexAction()
        return new ViewModel();

As usual, we need to require kahlan/kahlan:^3.0 via composer command:

composer require --dev kahlan/kahlan:^3.0 --sort-packages

You can then write the spec. Let’s write our spec inside module/Application/spec like the following structure:

├── config
├── spec
│   ├── Controller
│   │   ├── IndexControllerDispatchSpec.php
│   │   └── IndexControllerSpec.php
├── src
│   ├── Controller
│   │   ├── IndexController.php

if we are only have the 1 module, named Application module, we can define the spec and src path via kahlan-config.php like the following:

// ./kahlan.config.php
$commandLine = $this->commandLine();
$commandLine->option('spec', 'default', 'module/Application/spec');
$commandLine->option('src', 'default', 'module/Application/src');

Or for multi-modules, we can run parallel command that specify --spec and --src in command like the following:

vendor/bin/kahlan --spec=module/Application/spec --src=module/Application/src

in each iteration. If you’re using ant, you can write a build.xml for tasks definition:

<?xml version="1.0" encoding="UTF-8"?>
<project name="My Website" default="build">
    <!-- executable files directory definition -->
    <property name="toolsdir" value="${basedir}/vendor/bin/"/>
    <!-- module directory definition --> 
    <property name="moduledir" value="${basedir}/module/"/>

    <target name="build"

    <target name="kahlan"
            description="Run kahlan">
            <!-- Application -->    
            <exec executable="${toolsdir}kahlan" failonerror="true" taskname="kahlan">
            <!-- Application -->
            <!-- other modules run test definition go here --> 


Unit testing

Let’s write the unit testing inside spec/Controller/IndexControllerSpec.php:

namespace ApplicationSpec\Controller;

use Application\Controller\IndexController;
use Zend\View\Model\ViewModel;

describe('IndexController', function () {
    given('controller', function () {
        return new IndexController();
    describe('->indexAction()', function() {
        it('instance of ViewModel', function() {
            $actual = $this->controller->indexAction();

That’s enough for IndexController::indexAction() unit test, nothing complex logic we need to accomodate as it only return the ViewModel instance, so we just need to check if return values is instance of ViewModel.

Functional Testing

Now, we need to make sure if the dispatch response of IndexController::indexAction() by open ‘/’ url that shown by user is the expected result, that show a welcome page, let’s do with spec/Controller/IndexControllerDispatchSpec.php:

namespace ApplicationSpec\Controller;

use Zend\Console\Console;
use Zend\Mvc\Application;

describe('IndexController Dispatch', function () {
    // setup the Application
    beforeAll(function () {
        $appConfig = include __DIR__ . '/../../../../config/application.config.php';
        $this->application = Application::init($appConfig);

        $events = $this->application->getEventManager();

    // dispatch '/' page tests
    describe('/', function() {
        it('contains welcome page', function() {
            $request     = $this->application->getRequest();
            // run app with '/' url
            $app =  $this->application->run();
            // expect actual response is contain
            // a welcome page
            )->toContain('<h1>Welcome to <span class="zf-green">Zend Framework</span></h1>');

That’s it 😉

2 Responses

Subscribe to comments with RSS.

  1. Stephan said, on February 13, 2018 at 12:48 pm

    Again great article.

    Is there any advantage using Kahlan other than using plain old PHPUnit?

    Also can you explain how to bootstrap ZF3 for phpunit testing?

    • samsonasik said, on February 13, 2018 at 6:17 pm

      You can check kahlan feature at the documentation https://kahlan.github.io/docs/ .

      Bootstrapping for testing is depent on whether it will use unit or functional test, if you use functional test, It will looks like this post on `beforeAll()` function if you use phpunit with define the bootstrap file to phpunit.xml

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 )

Google+ photo

You are commenting using your Google+ 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: