Configuring PHPUnit and Codeigniter on PHPStorm
The main motivation behind this setup is to get into Test Driven Development.
There are debates about the downside of TDD over other development methodologies. That main downside being that it is time consuming. At the time of writing this blog, I admit that TDD is a well known concept, unfortunately, from my experiences it has not been very practical.
http://stackoverflow.com/questions/64333/disadvantages-of-test-driven-development#67184
http://www.agiledata.org/essays/tdd.html
http://net.tutsplus.com/tutorials/php/lets-tdd-a-simple-app-in-php/
I assumed the following setup on your development box.
Attribution: http://www.jamesfairhurst.co.uk/posts/view/codeigniter_phpunit_and_netbeans
Bootstrapping your PHPUnit.
Launch your PHPstorm IDE and open your Codeigniter project. If you do not have a Codeigniter project. You can download or clone Codeigniter from their Githhub Repo.
git clone https://github.com/EllisLab/CodeIgniter.git
Create a /tests directory in the root Codeigniter directory. Tests should exist in the same path as your application, assets, and system. Test files will need to be created in this directory.
Create bootstrap.php and phpunit.xml and place it under the /tests directory.
Copy this code and paste this code into bootstrap.php https://gist.github.com/thachp/8263055
Copy this xml configuration codes and paste it into your phpunit.xml file. https://gist.github.com/thachp/8263086
Open system/core/Utf8.php file and goto line 41, the $CFG variable is marked as global and this is causing issues with PHPUnit. Replace that line by loading the class via CodeIgniter like so:
$CFG =& load_class('Config', 'core');
Add a config in your hooks file under application/config/hooks.php
// application/config/hooks.php $hook['display_override'] = array( 'class' => 'DisplayHook', 'function' => 'captureOutput', 'filename' => 'DisplayHook.php', 'filepath' => 'hooks' );
Create a DisplayHook.php file under application/hooks.
// application/hooks/DisplayHook.php class DisplayHook { public function captureOutput() { $this->CI =& get_instance(); $output = $this->CI->output->get_output(); if (ENVIRONMENT != 'testing') { echo $output; } } }
Create a model to run tests.
// application/models/post.php class Post extends CI_Model { public function getAll() { return array( array('title'=>'post 1','content'=>'...'), array('title'=>'post 2','content'=>'...'), array('title'=>'post 3','content'=>'...'), array('title'=>'post 4','content'=>'...'), array('title'=>'post 5','content'=>'...'), ); } }
Create a TestFile that will run Tests on the model that we just created.
// tests/PostTest.php class PostTest extends PHPUnit_Framework_TestCase { private $CI; public function setUp() { $this->CI = &get_instance(); } public function testGetAllPosts() { $this->CI->load->model('post'); $posts = $this->CI->post->getAll(); $this->assertEquals(5, count($posts)); } }
Launch your Terminal and change your working directory to your Codeigniter project. Run this command. You should see that your test passed.
> phpunit PostTest.php ... Configuration read from PATH\tests\phpunit.xml . Time: 0 seconds, Memory: 5.25Mb OK (1 test, 1 assertion)
Set your PHP Interpreter. Select your local PHP setup.
> Click File > Settings > click PHP
In my case, I created localPHP under configuration directives. I selected my local PHP installation as my interpreter.
/Applications/MAMP/bin/php/php5.4.4/bin
Set your PHPunit Test Runner
> Click PHPUnit > Check Default configuration file. > Point the path to your phpunit.xml file under /tests. > Check Default bootstrap file. > Point the path to your bootstrap.php file under /tests.
Set your Debug Configuration. This will enable to press SHIFT + F10 every time you need to run your tests.
> Click Run > Edit Configuration > Click + > Select PHPUnit > Set Name to RunTests > Under Test Scope > Select Directory > Set the Directory to your /Test path.
Open your PostTest.php under /tests. Press Shift + F10 or Click Run > RunTests. You should see your test results in the PHPstorm Test Panel.
Configuration read from PATH\tests\phpunit.xml . Time: 0 seconds, Memory: 5.25Mb OK (1 test, 1 assertion)
A reader from the Netherlands has encountered few problems with the setup that I did not describe in this post. Please review his suggested modifications.
I ran into a few problems after following the article to the letter. The first was get_instance(); not being defined (had to do with the default PHPUnit config file not configured in PhpStorm). If you don’t pas a PHPUnit config file in PhpStorm it will add -no-configuration to the command line. And in that case it will not load the default phpunit.xml so the bootstrap file will not be loaded. All i needed to do is add the file manually in the PHPUnit tab of PHPStorm.
After that i kept getting 404 error pages. My solution to this was to add a folder in the application/config named ’testing’ (same as the environment). Copy my routes.php and only have these to lines in it:
$route['default_controller’] = "site"; $route['(:any)’] = "site”;
Where „site" is obviously a existing controller. This way the 404 page won’t trigger and won’t disturb the PHPUnit flow (it wil also only be used when the environment is set to testing). You can also copy the config.php to this directory and enable the hooks there. So it wont mess with your production or development environment.
Another minor change i made was copy the Utf8.php to the application/core folder rename it to [subclass_prefix found in config.php]_Utf8.php and change this line in the file: 'class [subclass_prefix found in config.php]_Utf8 extends CI_Utf8’