Now you can write tests for CodeIgniter 3.0 apps that contains exit() with ci-phpunit-test
If you have apps that contains exit()
or die()
, normally you can't test them with PHPUnit.
Because an exit()
in your app will abort the whole test suite.
But if you use CI PHPUnit Test v0.5.0, you can test your CodeIgniter apps like that without any modifications.
(2016/02/28 Added) If you are not familiar with Testing, I recommend our Ebook. CodeIgniter Testing Guide. It is Beginners' Guide to Automated Testing in PHP.
Requirements
- CodeIgniter 3.0
- PHP 5.4 or later
- PHPUnit (4.7 is recommended)
- ci-phpunit-test v0.5.0 (or later)
Setup
Installing CI PHPUnit Test is very easy.
Step 0
Install CodeIgniter 3.0.0. Download CodeIgniter 3.0.0 from http://www.codeigniter.com/download and unzip it.
Step 1
Install CI PHPUnit Test. Download latest version from https://github.com/kenjis/ci-phpunit-test/releases and unzip it. Copy application/tests
folder into application
folder.
CodeIgniter-3.0.0/
└── application/
└── tests/
Step 2
Install PHPUnit 4.7. See https://phpunit.de/manual/4.7/en/installation.html.
For example, download https://phar.phpunit.de/phpunit.phar, and copy it to CodeIgniter project application/tests
folder.
CodeIgniter-3.0.0/
└── application/
└── tests/
└── phpunit.phar
Now you're ready to run phpuint tests.
$ cd CodeIgniter-3.0.0/application/tests/
$ php phpunit.phar
PHPUnit 4.7.7 by Sebastian Bergmann and contributors.
...
Time: 896 ms, Memory: 9.25Mb
OK (3 tests, 3 assertions)
Generating code coverage report in Clover XML format ... done
Generating code coverage report in HTML format ... done
Okay.
Application Code containing exit()
If you have a controller like this:
application/controllers/Test.php
<?php
class Test extends CI_Controller
{
public function index()
{
$this->output
->set_status_header(200)
->set_content_type('application/json', 'utf-8')
->set_output(json_encode(['foo' => 'bar']))
->_display();
exit();
}
}
You can write a test case with CI PHPUnit Test like below:
application/tests/controllers/Test_test.php
<?php
class Test_test extends TestCase
{
public function test_index()
{
$output = $this->request('GET', 'test/index');
$this->assertContains('{"foo":"bar"}', $output);
}
}
But when phpunit runs Test
controller, the whole test suite will be aborted by the exit()
in the controller like below:
$ php phpunit.phar
PHPUnit 4.7.7 by Sebastian Bergmann and contributors.
{"foo":"bar"}$
There is no test results. So you can't test the controller normally.
Converting exit() to Exception
But now CI PHPUnit Test has a new functionality to convert exit()
to exception.
To enable it, you just change TestCase::$enable_patcher
to true
.
(2015/08/12 Added) The way to enable this functionality has changed on CI PHPUnit Test v0.6.0. See https://github.com/kenjis/ci-phpunit-test/blob/master/docs/HowToWriteTests.md#monkey-patching.
--- a/application/tests/TestCase.php
+++ b/application/tests/TestCase.php
@@ -2,5 +2,5 @@
class TestCase extends CIPHPUnitTestCase
{
- public static $enable_patcher = false;
+ public static $enable_patcher = true;
}
Let's run phpunit again.
$ php phpunit.phar
PHPUnit 4.7.7 by Sebastian Bergmann and contributors.
E...
Time: 1.23 seconds, Memory: 10.50Mb
There was 1 error:
1) Test_test::test_index
CIPHPUnitTestExitException: exit() called in Test::index()
/Users/kenji/CodeIgniter-3.0.0/application/controllers/Test.php:12
/Users/kenji/CodeIgniter-3.0.0/application/tests/_ci_phpunit_test/CIPHPUnitTestRequest.php:281
/Users/kenji/CodeIgniter-3.0.0/application/tests/_ci_phpunit_test/CIPHPUnitTestRequest.php:243
/Users/kenji/CodeIgniter-3.0.0/application/tests/_ci_phpunit_test/CIPHPUnitTestRequest.php:87
/Users/kenji/CodeIgniter-3.0.0/application/tests/_ci_phpunit_test/CIPHPUnitTestCase.php:60
/Users/kenji/CodeIgniter-3.0.0/application/tests/controllers/Test_test.php:7
/Users/kenji/CodeIgniter-3.0.0/application/tests/phpunit.phar:537
FAILURES!
Tests: 4, Assertions: 3, Errors: 1.
Generating code coverage report in Clover XML format ... done
Generating code coverage report in HTML format ... done
Now you can see an error message below:
1) Test_test::test_index
CIPHPUnitTestExitException: exit() called in Test::index()
Yes, exit()
was converted to CIPHPUnitTestExitException
.
Cool, isn't it?
So you can test it to catch the exception.
application/tests/controllers/Test_test.php
<?php
class Test_test extends TestCase
{
public function test_index()
{
try {
$output = $this->request('GET', 'test/index');
} catch (CIPHPUnitTestExitException $e) {
$output = ob_get_clean();
}
$this->assertContains('{"foo":"bar"}', $output);
}
}
Let's run phpunit again.
$ php phpunit.phar
PHPUnit 4.7.7 by Sebastian Bergmann and contributors.
....
Time: 1.34 seconds, Memory: 10.50Mb
OK (4 tests, 4 assertions)
Generating code coverage report in Clover XML format ... done
Generating code coverage report in HTML format ... done
Okay. All green.
Summary
- Installing CI PHPUnit Test is very easy. You don't have to modify CodeIgniter files at all.
- You can write tests for application code that contains
exit()
ordie()
with CI PHPUnit Test.
If you are interested in CI PHPUnit Test, see the official site:
Related
Date: 2015/07/27