I’ve been programming PHP now for, oh, almost a decade and I’ve been a contributor to PEAR for about four years now. It took me this long to finally get to the point that I think writing unit tests, in some form, is a good idea. I jumped on the OOP bandwagon about 6 years ago and drank the MVC koolaid about 4 years ago. As of a few weeks ago, I’ve jumped on the phpt bandwagon. I’m not going to cover the basics, because they’re well covered in a few different places around the web, but I am going to cover some of the nuances I’ve learned in the last few weeks.First off, you can run phpt
files using the PEAR command line utility. I’ve been creating a tests directory and putting all of my phpt
files in there. I normally name them 000-class-method.phpt
and then increment the sequence number at the front for each test by 5 so I can do a decent job of predicting how tests run. Once you have a few tests you can run your tests in two different manners from the command line:
pear run-tests
pear run-tests 000-class-method.phpt
When you run your tests you’ll get results of which tests passed, which failed, if any of them were skipped and the reason why they were skipped, and files for debugging. If 000-class-method.phpt fails, there are a few files that will be of interest to you:
000-class-method.php
is the actual PHP file ran, which is found in the--FILE--
portion of yourphpt
file.000-class-method.out
is what was actually output by the PHP file ran from the--FILE--
portion of yourphpt
file.000-class-method.exp
is what the test expected the output of000-class-method.php
to be, which is found in the--EXPECT--
portion of yourphpt
file.
You pretty much have everything you need to debug why a test failed. I normally diff the exp and out files and then debug the test (or my code, which is usually the case) using the php file.
Another great thing about phpt
files is that you can use a cgi PHP binary to debug actual GET requests (phpt
supports spoofing $_GET
, $_POST
and $_COOKIE
using the cgi binary). This lets you create tests like the following:
--TEST--
Test a GET request
--GET--
foo=bar&baz=foo
--FILE--
<?php
echo $_GET['bar'] . "\n";
echo $_GET['baz'] . "\n";
?>
--EXPECT--
bar
foo
This test should pass without incident. The only catch is that you need to specify your cgi binary path using the --cgi
argument when you run the tests (e.g. pear run-tests --cgi=/path/to/php-cgi
).
Overall, I’m pretty happy with my newfound testing experiences. My only complaint is that phpt
files don’t support spoofing of $_SESSION
natively. A small complaint to be sure.