387 lines
15 KiB
HTML
387 lines
15 KiB
HTML
|
<html>
|
||
|
<head>
|
||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||
|
<title>SimpleTest for PHP test suites</title>
|
||
|
<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
|
||
|
</head>
|
||
|
<body>
|
||
|
<div class="menu_back"><div class="menu">
|
||
|
<a href="index.html">SimpleTest</a>
|
||
|
|
|
||
|
<a href="overview.html">Overview</a>
|
||
|
|
|
||
|
<a href="unit_test_documentation.html">Unit tester</a>
|
||
|
|
|
||
|
<span class="chosen">Group tests</span>
|
||
|
|
|
||
|
<a href="mock_objects_documentation.html">Mock objects</a>
|
||
|
|
|
||
|
<a href="partial_mocks_documentation.html">Partial mocks</a>
|
||
|
|
|
||
|
<a href="reporter_documentation.html">Reporting</a>
|
||
|
|
|
||
|
<a href="expectation_documentation.html">Expectations</a>
|
||
|
|
|
||
|
<a href="web_tester_documentation.html">Web tester</a>
|
||
|
|
|
||
|
<a href="form_testing_documentation.html">Testing forms</a>
|
||
|
|
|
||
|
<a href="authentication_documentation.html">Authentication</a>
|
||
|
|
|
||
|
<a href="browser_documentation.html">Scriptable browser</a>
|
||
|
</div></div>
|
||
|
<h1>Test suite documentation</h1>
|
||
|
This page...
|
||
|
<ul>
|
||
|
<li>
|
||
|
Different ways to <a href="#group">group tests</a> together.
|
||
|
</li>
|
||
|
<li>
|
||
|
Combining group tests into <a href="#higher">larger groups</a>.
|
||
|
</li>
|
||
|
<li>
|
||
|
Integrating <a href="#legacy">legacy test cases</a> from other
|
||
|
types of PHPUnit.
|
||
|
</li>
|
||
|
</ul>
|
||
|
<div class="content">
|
||
|
<p><a class="target" name="group"><h2>Grouping tests into suites</h2></a></p>
|
||
|
<p>
|
||
|
To run test cases as part of a group, the test cases should really
|
||
|
be placed in files without the runner code...
|
||
|
<pre>
|
||
|
<strong><?php
|
||
|
require_once('../classes/io.php');
|
||
|
|
||
|
class FileTester extends UnitTestCase {
|
||
|
...
|
||
|
}
|
||
|
|
||
|
class SocketTester extends UnitTestCase {
|
||
|
...
|
||
|
}
|
||
|
?></strong>
|
||
|
</pre>
|
||
|
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.
|
||
|
</p>
|
||
|
<p>
|
||
|
If you have extended any test cases, you can include them
|
||
|
as well. In PHP 4...
|
||
|
<pre>
|
||
|
<?php
|
||
|
require_once('../classes/io.php');
|
||
|
<strong>
|
||
|
class MyFileTestCase extends UnitTestCase {
|
||
|
...
|
||
|
}
|
||
|
SimpleTest::ignore('MyFileTestCase');</strong>
|
||
|
|
||
|
class FileTester extends MyFileTestCase { ... }
|
||
|
|
||
|
class SocketTester extends UnitTestCase { ... }
|
||
|
?>
|
||
|
</pre>
|
||
|
The <span class="new_code">FileTester</span> class does
|
||
|
not contain any actual tests, but is a base class for other
|
||
|
test cases.
|
||
|
For this reason we use the
|
||
|
<span class="new_code">SimpleTestOptions::ignore()</span> 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).
|
||
|
</p>
|
||
|
<p>
|
||
|
If you are using PHP 5, you do not need this special directive at all.
|
||
|
Simply mark any test cases that should not be run as abstract...
|
||
|
<pre>
|
||
|
<strong>abstract</strong> class MyFileTestCase extends UnitTestCase {
|
||
|
...
|
||
|
}
|
||
|
|
||
|
class FileTester extends MyFileTestCase { ... }
|
||
|
|
||
|
class SocketTester extends UnitTestCase { ... }
|
||
|
</pre>
|
||
|
</p>
|
||
|
<p>
|
||
|
We will call this sample <em>file_test.php</em>.
|
||
|
Next we create a group test file, called say <em>my_group_test.php</em>.
|
||
|
You will think of a better name I am sure.
|
||
|
</p>
|
||
|
<p>
|
||
|
We will add the test file using a safe method...
|
||
|
<pre>
|
||
|
<?php
|
||
|
require_once('simpletest/unit_tester.php');
|
||
|
require_once('simpletest/reporter.php');<strong>
|
||
|
require_once('file_test.php');
|
||
|
|
||
|
$test = &new TestSuite('All file tests');
|
||
|
$test->addTestCase(new FileTestCase());
|
||
|
$test->run(new HtmlReporter());</strong>
|
||
|
?>
|
||
|
</pre>
|
||
|
This instantiates the test case before the test suite is
|
||
|
run.
|
||
|
This could get a little expensive with a large number of test
|
||
|
cases, and can be surprising behaviour.
|
||
|
</p>
|
||
|
<p>
|
||
|
The main problem is that for every test case
|
||
|
that we add we will have
|
||
|
to <span class="new_code">require_once()</span> the test code
|
||
|
file and manually instantiate each and every test case.
|
||
|
</p>
|
||
|
<p>
|
||
|
We can save a lot of typing with...
|
||
|
<pre>
|
||
|
<?php
|
||
|
require_once('simpletest/unit_tester.php');
|
||
|
require_once('simpletest/reporter.php');
|
||
|
|
||
|
$test = &new TestSuite('All file tests');<strong>
|
||
|
$test->addTestFile('file_test.php');</strong>
|
||
|
$test->run(new HtmlReporter());
|
||
|
?&gt;
|
||
|
</pre>
|
||
|
What happens here is that the <span class="new_code">TestSuite</span>
|
||
|
class has done the <span class="new_code">require_once()</span>
|
||
|
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.
|
||
|
</p>
|
||
|
<p>
|
||
|
No only that, but you can guarantee that the constructor is run
|
||
|
just before the first test method and, in PHP 5, the destructor
|
||
|
is run just after the last test method.
|
||
|
</p>
|
||
|
<p>
|
||
|
There are two things that could go wrong and which require care...
|
||
|
<ol>
|
||
|
<li>
|
||
|
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 (Note : with the new <cite>autorun</cite>
|
||
|
functionnality, this problem has now been solved).
|
||
|
</li>
|
||
|
<li>
|
||
|
New test case extension classes that get included will be
|
||
|
placed in the group test and run also.
|
||
|
You will need to add a <span class="new_code">SimpleTestOptions::ignore()</span>
|
||
|
directive for these classes, or make sure that they are included
|
||
|
before the <span class="new_code">TestSuite::addTestFile()</span>
|
||
|
line, or make sure that they are abstract classes.
|
||
|
</li>
|
||
|
</ol>
|
||
|
</p>
|
||
|
|
||
|
<p><a class="target" name="higher"><h2>Composite suites</h2></a></p>
|
||
|
<p>
|
||
|
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.
|
||
|
</p>
|
||
|
<p>
|
||
|
To get a more flexible group test we can subclass
|
||
|
<span class="new_code">TestSuite</span> and then instantiate it as needed...
|
||
|
<pre>
|
||
|
<?php
|
||
|
require_once('simpletest/unit_tester.php');
|
||
|
require_once('simpletest/reporter.php');
|
||
|
<strong>
|
||
|
class FileTestSuite extends TestSuite {
|
||
|
function FileTestSuite() {
|
||
|
$this->TestSuite('All file tests');
|
||
|
$this->addTestFile('file_test.php');
|
||
|
}
|
||
|
}</strong>
|
||
|
?>
|
||
|
</pre>
|
||
|
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...
|
||
|
<pre>
|
||
|
<?php
|
||
|
require_once('file_test_suite.php');
|
||
|
<strong>
|
||
|
$test = &new FileTestSuite();
|
||
|
$test->run(new HtmlReporter());</strong>
|
||
|
?>
|
||
|
</pre>
|
||
|
...or we can group them into even larger group tests.
|
||
|
We can even mix groups and test cases freely as long as
|
||
|
we are careful about double includes...
|
||
|
<pre>
|
||
|
<?php
|
||
|
<strong>
|
||
|
$test = &new BigTestSuite('Big group');
|
||
|
$test->addTestFile('file_test_suite.php');
|
||
|
$test->addTestFile('some_test_case.php');</strong>
|
||
|
$test->run(new HtmlReporter());
|
||
|
?>
|
||
|
</pre>
|
||
|
In the event of a double include, ony the first instance
|
||
|
of the test case will be run.
|
||
|
</p>
|
||
|
<p>
|
||
|
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.
|
||
|
<pre>
|
||
|
<?php
|
||
|
class FileTestSuite extends TestSuite {
|
||
|
function FileTestSuite() {
|
||
|
$this->TestSuite('All file tests');
|
||
|
$test->addTestFile('file_test.php');
|
||
|
}
|
||
|
}
|
||
|
<strong>
|
||
|
if (! defined('RUNNER')) {
|
||
|
define('RUNNER', true);</strong>
|
||
|
$test = &new FileTestSuite();
|
||
|
$test->run(new HtmlReporter());
|
||
|
}
|
||
|
?>
|
||
|
</pre>
|
||
|
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 <span class="new_code">run()</span> will run once only
|
||
|
from the top level script that has been invoked.
|
||
|
<pre>
|
||
|
<?php<strong>
|
||
|
define('RUNNER', true);</strong>
|
||
|
require_once('file_test_suite.php');
|
||
|
|
||
|
$test = &new BigTestSuite('Big group');
|
||
|
$test->addTestCase(new FileTestSuite());
|
||
|
$test->addTestCase(...);
|
||
|
$test->run(new HtmlReporter());
|
||
|
?>
|
||
|
</pre>
|
||
|
As with the normal test cases, a <span class="new_code">TestSuite</span> can
|
||
|
be loaded with the <span class="new_code">TestSuite::addTestFile()</span> method.
|
||
|
<pre>
|
||
|
<?php
|
||
|
define('RUNNER', true);
|
||
|
|
||
|
$test = &new BigTestSuite('Big group');<strong>
|
||
|
$test->addTestFile('file_test_suite.php');
|
||
|
$test->addTestFile(...);</strong>
|
||
|
$test->run(new HtmlReporter());
|
||
|
?>
|
||
|
</pre>
|
||
|
</p>
|
||
|
|
||
|
<p><a class="target" name="legacy"><h2>Integrating legacy test cases</h2></a></p>
|
||
|
<p>
|
||
|
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.
|
||
|
</p>
|
||
|
<p>
|
||
|
Say we have the following
|
||
|
<a href="http://sourceforge.net/projects/phpunit">PhpUnit</a>
|
||
|
test case in the file <em>config_test.php</em>...
|
||
|
<pre>
|
||
|
<strong>class ConfigFileTest extends TestCase {
|
||
|
function ConfigFileTest() {
|
||
|
$this->TestCase('Config file test');
|
||
|
}
|
||
|
|
||
|
function testContents() {
|
||
|
$config = new ConfigFile('test.conf');
|
||
|
$this->assertRegexp('/me/', $config->getValue('username'));
|
||
|
}
|
||
|
}</strong>
|
||
|
</pre>
|
||
|
The group test can recognise this as long as we include
|
||
|
the appropriate adapter class before we add the test
|
||
|
file...
|
||
|
<pre>
|
||
|
<?php
|
||
|
require_once('simpletest/unit_tester.php');
|
||
|
require_once('simpletest/reporter.php');<strong>
|
||
|
require_once('simpletest/adapters/phpunit_test_case.php');</strong>
|
||
|
|
||
|
$test = &new TestSuite('All file tests');<strong>
|
||
|
$test->addTestFile('config_test.php');</strong>
|
||
|
$test->run(new HtmlReporter());
|
||
|
?>
|
||
|
</pre>
|
||
|
There are only two adapters, the other is for the
|
||
|
<a href="http://pear.php.net/manual/en/package.php.phpunit.php">PEAR</a>
|
||
|
1.0 unit tester...
|
||
|
<pre>
|
||
|
<?php
|
||
|
require_once('simpletest/unit_tester.php');
|
||
|
require_once('simpletest/reporter.php');<strong>
|
||
|
require_once('simpletest/adapters/pear_test_case.php');</strong>
|
||
|
|
||
|
$test = &new TestSuite('All file tests');<strong>
|
||
|
$test->addTestFile('some_pear_test_cases.php');</strong>
|
||
|
$test->run(new HtmlReporter());
|
||
|
?>
|
||
|
</pre>
|
||
|
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.
|
||
|
</p>
|
||
|
|
||
|
</div>
|
||
|
References and related information...
|
||
|
<ul>
|
||
|
<li>
|
||
|
SimpleTest project page on <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
|
||
|
</li>
|
||
|
<li>
|
||
|
SimpleTest download page on <a href="http://www.lastcraft.com/simple_test.php">LastCraft</a>.
|
||
|
</li>
|
||
|
</ul>
|
||
|
<div class="menu_back"><div class="menu">
|
||
|
<a href="index.html">SimpleTest</a>
|
||
|
|
|
||
|
<a href="overview.html">Overview</a>
|
||
|
|
|
||
|
<a href="unit_test_documentation.html">Unit tester</a>
|
||
|
|
|
||
|
<span class="chosen">Group tests</span>
|
||
|
|
|
||
|
<a href="mock_objects_documentation.html">Mock objects</a>
|
||
|
|
|
||
|
<a href="partial_mocks_documentation.html">Partial mocks</a>
|
||
|
|
|
||
|
<a href="reporter_documentation.html">Reporting</a>
|
||
|
|
|
||
|
<a href="expectation_documentation.html">Expectations</a>
|
||
|
|
|
||
|
<a href="web_tester_documentation.html">Web tester</a>
|
||
|
|
|
||
|
<a href="form_testing_documentation.html">Testing forms</a>
|
||
|
|
|
||
|
<a href="authentication_documentation.html">Authentication</a>
|
||
|
|
|
||
|
<a href="browser_documentation.html">Scriptable browser</a>
|
||
|
</div></div>
|
||
|
<div class="copyright">
|
||
|
Copyright<br>Marcus Baker 2006
|
||
|
</div>
|
||
|
</body>
|
||
|
</html>
|