Running the tests, the easy way with autorun
You started with unit testing not so long ago and this is what you came up with... A file test_of_all_modules.php containing :
<?php require_once('simpletest/unit_tester.php'); require_once('simpletest/reporter.php'); $group = new TestSuite(); $group->addFile('test_of_module_ship.php'); $group->addFile('test_of_module_pay.php'); $group->run(new HtmlReporter()); ?>
But now you have a new way of shipping your socks overseas. Easily you just need to add a new file test_of_module_ship_overseas.php to your test runner... Quickly enough, you end up with a lot of file :
<?php require_once('simpletest/unit_tester.php'); require_once('simpletest/reporter.php'); $group = new TestSuite(); $group->addFile('test_of_module_ship.php'); $group->addFile('test_of_module_ship_overseas.php'); $group->addFile('test_of_module_ship_france.php'); $group->addFile('test_of_module_ship_uk.php'); $group->addFile('test_of_module_ship_us.php'); ... $group->addFile('test_of_module_pay.php'); $group->run(new HtmlReporter()); ?>
As you list grows, running the test suite becomes too time- consuming : the tests are actually slowing you down while writing code.
Introducing 'autorun'
What we're looking for now is a way to run one test at a time and still be able to run every one of them easily... What if we could just write - in a console for example :
<?php require_once('simpletest/autorun.php'); class TestUsingParcelForce extends UnitTestCase { function testParcelForceIsFine() { $this->assertTrue(true); } } class TestUsingMyOwnAirplane extends UnitTestCase { function testUsingMyOwnAirplaneOnlyWorksForSmallGifts() { $this->assertFalse(false); } } ?>
Setting the prefered runner
PHP is mainly for web stuff : I'm guessing your first test platform is a web browser, Firefox, Opera or Safari usually. And SimpleTest comes with a nice HTML interface : it's the one we want to use when running one file. We can tell our test_of_module_ship_us.php to use it by default :
<?php require_once('simpletest/autorun.php'); SimpleTest :: prefer(new HtmlReporter()); class TestUsingParcelForce extends UnitTestCase { function testParcelForceIsFine() { $this->assertTrue(true); } } class TestUsingMyOwnAirplane extends UnitTestCase { function testUsingMyOwnAirplaneOnlyWorksForSmallGifts() { $this->assertFalse(false); } } ?>
We get a nice green bar :
TestSuite
Autorun for test suites
So we've managed to get the time spent running the test under control during the coding period. We now want to make sure all the tests still pass, all the time. Or at least after every commit to the SVN (or CVS) trunk.
Such process is called continuous integration : Martin Fowler writes really well about this practice where members of a team integrate their work frequently [...]. Each integration is verified by an automated buid (including test) to detect integration errors as quickly as possible. So I can just give you the link : Continuous Integration.
Now our post-commit hook in SVN (or Phing task if you prefer) doesn't need the HTML reporter. We need something useful at the command line : TextReporter to the rescue. Our test_of_all_modules.php becomes :
<?php require_once('simpletest/autorun.php'); SimpleTest :: prefer(new TextReporter()); class AllTests extends TestSuite { function AllTests() { parent::TestSuite(); $this->addFile('test_of_module_ship.php'); $this->addFile('test_of_module_ship_overseas.php'); $this->addFile('test_of_module_ship_france.php'); $this->addFile('test_of_module_ship_uk.php'); $this->addFile('test_of_module_ship_us.php'); ... $this->addFile('test_of_module_pay.php'); } } ?>
The results show up nicely in the console :
grouptest
OK
Test cases run: 10/10, Passes: 37, Failures: 0, Exceptions: 0