PHPUnit

Kohana Unit Testing – Finally

I’ve written about using PHPUnit in Kohana in the past. However, there is now an official Unit Testing module for Kohana v3 (uses PHPUnit). From the previous hacks, I changed it now to be compliant with the official unit testing module.

There is an instruction on how to setup the unit testing module from the module itself. However, I changed some of the setup a bit and based it to my previous style when using Zend Framework and PHPUnit in general. I like my tests be individual and let the PHPUnit scans the directory instead of using group tests as recommended by the module.

Here are the simple steps, based on the official module mixed with my own style and Zend Frameworkish:

  • Enable unittest module
  • Modify the sending of response
  • Create test cases directory
  • Create phpunit.xml
  • Create tests

Enable unittest module

Edit application/bootstrap.php and enable the unittest module.

	/**
	 * Enable modules. Modules are referenced by a relative or absolute path.
	 */
	Kohana::modules(array(
		// 'auth'       => MODPATH.'auth',       // Basic authentication
		// 'cache'      => MODPATH.'cache',      // Caching with multiple backends
		// 'codebench'  => MODPATH.'codebench',  // Benchmarking tool
		'database'   => MODPATH.'database',   // Database access
		// 'image'      => MODPATH.'image',      // Image manipulation
		// 'orm'        => MODPATH.'orm',        // Object Relationship Mapping
		// 'oauth'      => MODPATH.'oauth',      // OAuth authentication
		// 'pagination' => MODPATH.'pagination', // Paging of results
		'unittest'   => MODPATH.'unittest',   // Unit testing
		'userguide'  => MODPATH.'userguide',  // User guide and API documentation
	));

Modify the sending of response

On application/bootstrap.php, modify the sending of response so that it will not send output when running unit tests. It should look like this:

	if ( ! defined('SUPPRESS_REQUEST'))
	{
		echo Request::instance()
			->execute()
			->send_headers()
			->response;
	}

Create test cases directory

Create the test cases directory which will contain all your test cases. Kohana recommends to put all your tests for application on application/tests. For modules, put it on the module directory. Of course you can put it anywhere you like.

Create tests dir

Create phpunit.xml

My tests are located at application/tests, therefore my phpunit.xml is located at application/tests/phpunit.xml. This is the content:

	<phpunit colors="true" bootstrap="../../index.php">
		<testsuites>
			<testsuite name="Kohana Tests">
				<directory>./</directory>
			</testsuite>
		</testsuites>
	</phpunit>

It is important the the bootstrap points to your index.php file. I am used to allow PHPUnit handles the scanning of all test cases on a directory. That way, I can write tests and don’t bother creating test suites and test groups, whatever.

Create tests

I created a sample test called SampleTest.php. To facilitate PHPUnit auto scanning the directory, you must suffix all your files with ‘Test’ and all class names with ‘Test’. For example, I created application/tests/classes/SampleTest.php and the content looks like this:

	<?php defined('SYSPATH') or die('No direct access allowed!');

	class SampleTest extends Kohana_UnitTest_TestCase
	{
		public function testAdd()
		{
			$post = array();

			$username = Arr::get($post, 'username');

			$this->assertEquals($username, null);
		}
	}

Now that we have one and only test, let’s run it first in the command line. Change directory to the tests directory, then run phpunit.

cd application/tests
phpunit

Run tests

As I explore the unittest module, I found out that it has a web interface. You can access it at base_url/unittest in the browser. For example the base url is at http://localhost/kohana, then you can access the web interface at http://localhost/kohana/unittest

Web runner first view
Web runner select test
Web runner result

9 thoughts on “Kohana Unit Testing – Finally”

  1. Thanks for the tutorial. I’m trying to make use of it, but struggling a bit. I know this article was written before version 3.1, so Request::initial() needs to be changed to Request::current(), but when I put that block in my bootstrap, I get “Call to a member function execute() on a non-object — which makes sense, because bootstrap is executing before index.php, so I don’t have a request at that point, right? But it’s also unclear to me where the SUPPRESS_REQUEST constant is supposed to be getting set in the first place. Any new thoughts on this?

  2. If you receive the error: Class “Kohana_UnitTest_TestCase” not found (usually burried in a bunch of HTML from the command line)

    try changing: Kohana_UnitTest_TestCase to Kohana_Unittest_TestCase (notice the lowercase “t” in Unittest).

    I specifically had this issue with Kohana 3.3.0 on Linux, which may be due to a case-sensitive filesystem.

    Note also for 3.3, you don’t need the “suppress” code, but you DO need to enable “minion” in the bootstrap.php modules, else you’ll receive: “Please enable the Minion module for CLI support”

Leave a reply

Your email address will not be published. Required fields are marked *