+ To run test cases as part of a group the test cases should really + be placed in files without the runner code... +
+<?php + require_once('../classes/io.php'); + + class FileTester extends UnitTestCase { + ... + } + + class SocketTester extends UnitTestCase { + ... + } +?> ++ As many cases as needed can appear in a single file. + They should include any code they need, such as the library + being tested, but none of the simple test libraries. + +
+ If you have extended any test cases, you can include them + as well. +
+<?php + require_once('../classes/io.php'); + + class MyFileTestCase extends UnitTestCase { + ... + } + SimpleTestOptions::ignore('MyFileTestCase'); + + class FileTester extends MyFileTestCase { + ... + } + + class SocketTester extends UnitTestCase { + ... + } +?> ++ The FileTester class does + not contain any actual tests, but is a base class for other + test cases. + For this reason we use the + SimpleTestOptions::ignore() directive + to tell the upcoming group test to ignore it. + This directive can appear anywhere in the file and works + when a whole file of test cases is loaded (see below). + We will call this sample file_test.php. + +
+ Next we create a group test file, called say group_test.php. + You will think of a better name I am sure. + We will add the test file using a safe method... +
+<?php + require_once('simpletest/unit_tester.php'); + require_once('simpletest/reporter.php'); + require_once('file_test.php'); + + $test = &new GroupTest('All file tests'); + $test->addTestCase(new FileTestCase()); + $test->run(new HtmlReporter()); +?> ++ This instantiates the test case before the test suite is + run. + This could get a little expensive with a large number of test + cases, so another method is provided that will only + instantiate the class when it is needed... +
+<?php + require_once('simpletest/unit_tester.php'); + require_once('simpletest/reporter.php'); + require_once('file_test.php'); + + $test = &new GroupTest('All file tests'); + $test->addTestClass('FileTestCase'); + $test->run(new HtmlReporter()); +?> ++ The problem with this method is that for every test case + that we add we will have + to require_once() the test code + file and manually instantiate each and every test case. + We can save a lot of typing with... +
+<?php + require_once('simpletest/unit_tester.php'); + require_once('simpletest/reporter.php'); + + $test = &new GroupTest('All file tests'); + $test->addTestFile('file_test.php'); + $test->run(new HtmlReporter()); +?> ++ What happens here is that the GroupTest + class has done the require_once() + for us. + It then checks to see if any new test case classes + have been created by the new file and automatically adds + them to the group test. + Now all we have to do is add each new file. + +
+ There are two things that could go wrong and which require care... +
-
+
- + The file could already have been parsed by PHP and so no + new classes will have been added. You should make + sure that the test cases are only included in this file + and no others. + +
- + New test case extension classes that get included will be + placed in the group test and run also. + You will need to add a SimpleTestOptions::ignore() + directive for these classes or make sure that they are included + before the GroupTest::addTestFile() + line. + +
+ The above method places all of the test cases into one large group. + For larger projects though this may not be flexible enough; you + may want to group the tests in all sorts of ways. +
++ To get a more flexible group test we can subclass + GroupTest and then instantiate it as needed... +
+<?php + require_once('simpletest/unit_tester.php'); + require_once('simpletest/reporter.php'); + + class FileGroupTest extends GroupTest { + function FileGroupTest() { + $this->GroupTest('All file tests'); + $this->addTestFile('file_test.php'); + } + } +?> ++ This effectively names the test in the constructor and then + adds our test cases and a single group below. + Of course we can add more than one group at this point. + We can now invoke the tests from a separate runner file... +
+<?php + require_once('file_group_test.php'); + + $test = &new FileGroupTest(); + $test->run(new HtmlReporter()); +?> ++ ...or we can group them into even larger group tests... +
+<?php + require_once('file_group_test.php'); + + $test = &new BigGroupTest('Big group'); + $test->addTestCase(new FileGroupTest()); + $test->addTestCase(...); + $test->run(new HtmlReporter()); +?> ++ If we still wish to run the original group test and we + don't want all of these little runner files, we can + put the test runner code around guard bars when we create + each group. +
+<?php + class FileGroupTest extends GroupTest { + function FileGroupTest() { + $this->GroupTest('All file tests'); + $test->addTestFile('file_test.php'); + } + } + + if (! defined('RUNNER')) { + define('RUNNER', true); + $test = &new FileGroupTest(); + $test->run(new HtmlReporter()); + } +?> ++ This approach requires the guard to be set when including + the group test file, but this is still less hassle than + lots of separate runner files. + You include the same guard on the top level tests to make sure + that run() will run once only + from the top level script that has been invoked. +
+<?php + define('RUNNER', true); + require_once('file_group_test.php'); + + $test = &new BigGroupTest('Big group'); + $test->addTestCase(new FileGroupTest()); + $test->addTestCase(...); + $test->run(new HtmlReporter()); +?> ++ As with the normal test cases, a GroupTest can + be loaded with the GroupTest::addTestFile() method. +
+<?php + define('RUNNER', true); + + $test = &new BigGroupTest('Big group'); + $test->addTestFile('file_group_test.php'); + $test->addTestFile(...); + $test->run(new HtmlReporter()); +?> ++ + +
+
+Integrating legacy test cases
+
+
+ If you already have unit tests for your code or are extending external + classes that have tests, it is unlikely that all of the test cases + are in SimpleTest format. + Fortunately it is possible to incorporate test cases from other + unit testers directly into SimpleTest group tests. +
++ Say we have the following + PhpUnit + test case in the file config_test.php... +
+class ConfigFileTest extends TestCase { + function ConfigFileTest() { + $this->TestCase('Config file test'); + } + + function testContents() { + $config = new ConfigFile('test.conf'); + $this->assertRegexp('/me/', $config->getValue('username')); + } +} ++ The group test can recognise this as long as we include + the appropriate adapter class before we add the test + file... +
+<?php + require_once('simpletest/unit_tester.php'); + require_once('simpletest/reporter.php'); + require_once('simpletest/adapters/phpunit_test_case.php'); + + $test = &new GroupTest('All file tests'); + $test->addTestFile('config_test.php'); + $test->run(new HtmlReporter()); +?> ++ There are only two adapters, the other is for the + PEAR + 1.0 unit tester... +
+<?php + require_once('simpletest/unit_tester.php'); + require_once('simpletest/reporter.php'); + require_once('simpletest/adapters/pear_test_case.php'); + + $test = &new GroupTest('All file tests'); + $test->addTestFile('some_pear_test_cases.php'); + $test->run(new HtmlReporter()); +?> ++ The PEAR test cases can be freely mixed with SimpleTest + ones even in the same test file, + but you cannot use SimpleTest assertions in the legacy + test case versions. + This is done as a check that you are not accidently making + your test cases completely dependent on SimpleTest. + You may want to do a PEAR release of your library for example + which would mean shipping it with valid PEAR::PhpUnit test + cases. + + +