April 21, 2012

Debugging PHP CLI scripts and phpunit unit tests in Eclipse with XDebug

Nowadays I've spent some time at stackoverflow.com, mostly because I wanted to give back something in exchange for the many solutions found there in the last few years. Browsing the questions found an interesting one asking if it was possible to debug unit tests.
Maybe another post will be about how to install phpunit with PEAR, but let's assume you already have it installed. As of writing this post, the actual Eclipse version is Indigo 3.7.2 with PDT 3.0.0.
You will need XDebug, if you use debian or ubuntu, the package is called php5-xdebug.
Without going into the details - because a couple other guys have already done that, just google 'eclipse xdebug' - I'd like to point out some important things. First, make sure you have everything installed and set up, you can follow instructions described in this document.

So, here come the important bits:

- You must have a phpunit.php in your project to debug unit tests. In ubuntu, you can copy /usr/bin/phpunit to your-project/some-dir/phpunit.php

- Add the PEAR directory as a PHP user library to Eclipse (Preferences / PHP / PHP Libraries), and add this library to the include path of your projects (Project Properties / PHP Include Path / Libraries).

- Eclipse - and PDT - runs PHP executable with a custom php.ini file, and the -n command line switch, so you have to create a full php.ini containing all the .ini files from the conf.d directory. The best way to realize this is to notice that your extensions are not loaded when running scripts within Eclipse, or you see that the debugger does not stop on breakpoints, because the xdebug extension is not loaded either.
Create a directory somewhere and concatenate all the .ini files together. You can do it running a command like this:
cat /etc/php5/cli/php.ini /etc/php5/cli/conf.d/* > /usr/local/etc/php5/php.ini
Set up the PHP executable in Eclipse (Preferences / PHP / PHP Executables), and specify this php.ini file location. After this, exit Eclipse and start it up with the -clean option.

- Make sure that your bootstrap.php file is set up to be run from anywhere, even from another working directory. Avoid including files like require_once('../classes/someclass.php'); use absolute paths instead, or start from the bootstrap.php file's directory to build absolute paths.

- Open a unit test file in Eclipse, and click Debug Configurations from the Run menu. Create a PHP CLI Application configuration. Select the PHP runtime you've just set up, and specify your phpunit.php file's as the 'PHP File', use relative path from your workspace directory, or just use Browse. Also, it may come handy to set the 'Break at first line' to on.
Go to PHP Script Arguments tab, and set command line options for phpunit you want to use (A 2 cent tip: don't use '--colors' in Eclipse) and the unit test's file name you want to debug. Usually the arguments would include
--configuration '/path/to/your/phpunit.xml'
--bootstrap '/path/to/your/bootstrap.php'
You can use the variables defined to avoid setting full paths here:
--configuration "${workspace_loc}/my-project/test/phpunit.xml" "${resource_loc}"
The '${resource_loc}' is a full path to the file you're currently debugging.

When you're done, just click Apply then Debug, and start debugging.