Yesterday I set up to write unit tests for a few PHP classes I'm refactoring. Given my usual tendency to set aside serious tasks and concentrate on eye candy, after a few tests I decided to write my own test runner (something I've done at least twice before, never storing away the code for later use).
My test runner builds on a few assumptions:
- the tests live in a web accessible directory
- every php file in the directory with a name starting with test is a test case
- every test file contains one case class extending PHPUnit_TestCase
- every test class has the same name as the file where it resides
- test cases are all the methods of the class whose names start with test
- you run tests and see results with a web browser
The main test runner features are:
- conditional execution of one or more test cases based on an HTML form
- run only/exclude a test with a single click of the mouse
- display aggregate test results by suite, showing counts for successes/failures and a warning indicator if any have been raised
- optionally expand test results to show results/failures for single test cases
- remember each suite visibility status (collapsed/expanded) for subsequent runs
- collect PHP warnings emitted during each test case run and display them under the appropriate test suite
I made a few screenshots, showing a collapsed view of all available suites, the same for a single suite, with a warning indicator, and one suite expanded, showing test cases results and warnings.
The DynamicTestRunner code only needs to include the PEAR version of PHPUnit. Using a templating engine would have made the code more understandable, but at the cost of introducing a dependency.
If you want to preserve the option of being able to run each test file on its own, you can test if it has been called by testRunner with a simple if statement at the end of each test file (substituing of course testEntities with the name of the class declared in the file):
if (!isset($_SERVER['SCRIPT_FILENAME']) || $_SERVER['SCRIPT_FILENAME'] == __FILE__) { $suite = new PHPUnit_TestSuite('testEntities'); $result = PHPUnit::run($suite); echo $result->toString(); }