| 1 |
lars |
1 |
<html>
|
|
|
2 |
<head>
|
|
|
3 |
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
|
4 |
<title>SimpleTest for PHP regression test documentation</title>
|
|
|
5 |
<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
|
|
|
6 |
</head>
|
|
|
7 |
<body>
|
|
|
8 |
<div class="menu_back">
|
|
|
9 |
<div class="menu">
|
|
|
10 |
<h2>
|
|
|
11 |
<a href="index.html">SimpleTest</a>
|
|
|
12 |
</h2>
|
|
|
13 |
<ul>
|
|
|
14 |
<li>
|
|
|
15 |
<a href="overview.html">Overview</a>
|
|
|
16 |
</li>
|
|
|
17 |
<li>
|
|
|
18 |
<span class="chosen">Unit tester</span>
|
|
|
19 |
</li>
|
|
|
20 |
<li>
|
|
|
21 |
<a href="group_test_documentation.html">Group tests</a>
|
|
|
22 |
</li>
|
|
|
23 |
<li>
|
|
|
24 |
<a href="mock_objects_documentation.html">Mock objects</a>
|
|
|
25 |
</li>
|
|
|
26 |
<li>
|
|
|
27 |
<a href="partial_mocks_documentation.html">Partial mocks</a>
|
|
|
28 |
</li>
|
|
|
29 |
<li>
|
|
|
30 |
<a href="reporter_documentation.html">Reporting</a>
|
|
|
31 |
</li>
|
|
|
32 |
<li>
|
|
|
33 |
<a href="expectation_documentation.html">Expectations</a>
|
|
|
34 |
</li>
|
|
|
35 |
<li>
|
|
|
36 |
<a href="web_tester_documentation.html">Web tester</a>
|
|
|
37 |
</li>
|
|
|
38 |
<li>
|
|
|
39 |
<a href="form_testing_documentation.html">Testing forms</a>
|
|
|
40 |
</li>
|
|
|
41 |
<li>
|
|
|
42 |
<a href="authentication_documentation.html">Authentication</a>
|
|
|
43 |
</li>
|
|
|
44 |
<li>
|
|
|
45 |
<a href="browser_documentation.html">Scriptable browser</a>
|
|
|
46 |
</li>
|
|
|
47 |
</ul>
|
|
|
48 |
</div>
|
|
|
49 |
</div>
|
|
|
50 |
<h1>PHP Unit Test documentation</h1>
|
|
|
51 |
<div class="content">
|
|
|
52 |
<p>
|
|
|
53 |
<a class="target" name="unit">
|
|
|
54 |
<h2>Unit test cases</h2>
|
|
|
55 |
</a>
|
|
|
56 |
</p>
|
|
|
57 |
<p>
|
|
|
58 |
The core system is a regression testing framework built around
|
|
|
59 |
test cases.
|
|
|
60 |
A sample test case looks like this...
|
|
|
61 |
<pre>
|
|
|
62 |
<strong>class FileTestCase extends UnitTestCase {
|
|
|
63 |
}</strong>
|
|
|
64 |
</pre>
|
|
|
65 |
If no test name is supplied when chaining the constructor then
|
|
|
66 |
the class name will be taken instead.
|
|
|
67 |
This will be the name displayed in the test results.
|
|
|
68 |
</p>
|
|
|
69 |
<p>
|
|
|
70 |
Actual tests are added as methods in the test case whose names
|
|
|
71 |
by default start with the string "test" and
|
|
|
72 |
when the test case is invoked all such methods are run in
|
|
|
73 |
the order that PHP introspection finds them.
|
|
|
74 |
As many test methods can be added as needed.
|
|
|
75 |
For example...
|
|
|
76 |
<pre>
|
|
|
77 |
require_once('../classes/writer.php');
|
|
|
78 |
|
|
|
79 |
class FileTestCase extends UnitTestCase {
|
|
|
80 |
function FileTestCase() {
|
|
|
81 |
$this->UnitTestCase('File test');
|
|
|
82 |
}<strong>
|
|
|
83 |
|
|
|
84 |
function setUp() {
|
|
|
85 |
@unlink('../temp/test.txt');
|
|
|
86 |
}
|
|
|
87 |
|
|
|
88 |
function tearDown() {
|
|
|
89 |
@unlink('../temp/test.txt');
|
|
|
90 |
}
|
|
|
91 |
|
|
|
92 |
function testCreation() {
|
|
|
93 |
$writer = &new FileWriter('../temp/test.txt');
|
|
|
94 |
$writer->write('Hello');
|
|
|
95 |
$this->assertTrue(file_exists('../temp/test.txt'), 'File created');
|
|
|
96 |
}</strong>
|
|
|
97 |
}
|
|
|
98 |
</pre>
|
|
|
99 |
The constructor is optional and usually omitted.
|
|
|
100 |
Without a name, the class name is taken as the name of the test case.
|
|
|
101 |
</p>
|
|
|
102 |
<p>
|
|
|
103 |
Our only test method at the moment is <span class="new_code">testCreation()</span>
|
|
|
104 |
where we check that a file has been created by our
|
|
|
105 |
<span class="new_code">Writer</span> object.
|
|
|
106 |
We could have put the <span class="new_code">unlink()</span>
|
|
|
107 |
code into this method as well, but by placing it in
|
|
|
108 |
<span class="new_code">setUp()</span> and
|
|
|
109 |
<span class="new_code">tearDown()</span> we can use it with
|
|
|
110 |
other test methods that we add.
|
|
|
111 |
</p>
|
|
|
112 |
<p>
|
|
|
113 |
The <span class="new_code">setUp()</span> method is run
|
|
|
114 |
just before each and every test method.
|
|
|
115 |
<span class="new_code">tearDown()</span> is run just after
|
|
|
116 |
each and every test method.
|
|
|
117 |
</p>
|
|
|
118 |
<p>
|
|
|
119 |
You can place some test case set up into the constructor to
|
|
|
120 |
be run once for all the methods in the test case, but
|
|
|
121 |
you risk test inteference that way.
|
|
|
122 |
This way is slightly slower, but it is safer.
|
|
|
123 |
Note that if you come from a JUnit background this will not
|
|
|
124 |
be the behaviour you are used to.
|
|
|
125 |
JUnit surprisingly reinstantiates the test case for each test
|
|
|
126 |
method to prevent such interference.
|
|
|
127 |
SimpleTest requires the end user to use <span class="new_code">setUp()</span>, but
|
|
|
128 |
supplies additional hooks for library writers.
|
|
|
129 |
</p>
|
|
|
130 |
<p>
|
|
|
131 |
The means of reporting test results (see below) are by a
|
|
|
132 |
visiting display class
|
|
|
133 |
that is notified by various <span class="new_code">assert...()</span>
|
|
|
134 |
methods.
|
|
|
135 |
Here is the full list for the <span class="new_code">UnitTestCase</span>
|
|
|
136 |
class, the default for SimpleTest...
|
|
|
137 |
<table>
|
|
|
138 |
<tbody>
|
|
|
139 |
<tr>
|
|
|
140 |
<td><span class="new_code">assertTrue($x)</span></td><td>Fail if $x is false</td>
|
|
|
141 |
</tr>
|
|
|
142 |
<tr>
|
|
|
143 |
<td><span class="new_code">assertFalse($x)</span></td><td>Fail if $x is true</td>
|
|
|
144 |
</tr>
|
|
|
145 |
<tr>
|
|
|
146 |
<td><span class="new_code">assertNull($x)</span></td><td>Fail if $x is set</td>
|
|
|
147 |
</tr>
|
|
|
148 |
<tr>
|
|
|
149 |
<td><span class="new_code">assertNotNull($x)</span></td><td>Fail if $x not set</td>
|
|
|
150 |
</tr>
|
|
|
151 |
<tr>
|
|
|
152 |
<td><span class="new_code">assertIsA($x, $t)</span></td><td>Fail if $x is not the class or type $t</td>
|
|
|
153 |
</tr>
|
|
|
154 |
<tr>
|
|
|
155 |
<td><span class="new_code">assertNotA($x, $t)</span></td><td>Fail if $x is of the class or type $t</td>
|
|
|
156 |
</tr>
|
|
|
157 |
<tr>
|
|
|
158 |
<td><span class="new_code">assertEqual($x, $y)</span></td><td>Fail if $x == $y is false</td>
|
|
|
159 |
</tr>
|
|
|
160 |
<tr>
|
|
|
161 |
<td><span class="new_code">assertNotEqual($x, $y)</span></td><td>Fail if $x == $y is true</td>
|
|
|
162 |
</tr>
|
|
|
163 |
<tr>
|
|
|
164 |
<td><span class="new_code">assertWithinMargin($x, $y, $m)</span></td><td>Fail if abs($x - $y) < $m is false</td>
|
|
|
165 |
</tr>
|
|
|
166 |
<tr>
|
|
|
167 |
<td><span class="new_code">assertOutsideMargin($x, $y, $m)</span></td><td>Fail if abs($x - $y) < $m is true</td>
|
|
|
168 |
</tr>
|
|
|
169 |
<tr>
|
|
|
170 |
<td><span class="new_code">assertIdentical($x, $y)</span></td><td>Fail if $x == $y is false or a type mismatch</td>
|
|
|
171 |
</tr>
|
|
|
172 |
<tr>
|
|
|
173 |
<td><span class="new_code">assertNotIdentical($x, $y)</span></td><td>Fail if $x == $y is true and types match</td>
|
|
|
174 |
</tr>
|
|
|
175 |
<tr>
|
|
|
176 |
<td><span class="new_code">assertReference($x, $y)</span></td><td>Fail unless $x and $y are the same variable</td>
|
|
|
177 |
</tr>
|
|
|
178 |
<tr>
|
|
|
179 |
<td><span class="new_code">assertCopy($x, $y)</span></td><td>Fail if $x and $y are the same variable</td>
|
|
|
180 |
</tr>
|
|
|
181 |
<tr>
|
|
|
182 |
<td><span class="new_code">assertPattern($p, $x)</span></td><td>Fail unless the regex $p matches $x</td>
|
|
|
183 |
</tr>
|
|
|
184 |
<tr>
|
|
|
185 |
<td><span class="new_code">assertNoPattern($p, $x)</span></td><td>Fail if the regex $p matches $x</td>
|
|
|
186 |
</tr>
|
|
|
187 |
<tr>
|
|
|
188 |
<td><span class="new_code">assertNoErrors()</span></td><td>Fail if any PHP error occoured</td>
|
|
|
189 |
</tr>
|
|
|
190 |
<tr>
|
|
|
191 |
<td><span class="new_code">assertError($x)</span></td><td>Fail if no PHP error or incorrect message/expectation</td>
|
|
|
192 |
</tr>
|
|
|
193 |
<tr>
|
|
|
194 |
<td><span class="new_code">assertExpectation($e)</span></td><td>Fail on failed expectation object</td>
|
|
|
195 |
</tr>
|
|
|
196 |
</tbody>
|
|
|
197 |
</table>
|
|
|
198 |
All assertion methods can take an optional description to
|
|
|
199 |
label the displayed result with.
|
|
|
200 |
If omitted a default message is sent instead which is usually
|
|
|
201 |
sufficient.
|
|
|
202 |
This default message can still be embedded in your own message
|
|
|
203 |
if you include "%s" within the string.
|
|
|
204 |
All the assertions return true on a pass or false on failure.
|
|
|
205 |
</p>
|
|
|
206 |
<p>
|
|
|
207 |
Some examples...
|
|
|
208 |
<pre>
|
|
|
209 |
<strong>$variable = null;
|
|
|
210 |
$this->assertNull($variable, 'Should be cleared');</strong>
|
|
|
211 |
</pre>
|
|
|
212 |
...will pass and normally show no message.
|
|
|
213 |
If you have
|
|
|
214 |
<a href="http://www.lastcraft.com/display_subclass_tutorial.php">set up the tester to display passes</a>
|
|
|
215 |
as well then the message will be displayed as is.
|
|
|
216 |
<pre>
|
|
|
217 |
<strong>$this->assertIdentical(0, false, 'Zero is not false [%s]');</strong>
|
|
|
218 |
</pre>
|
|
|
219 |
This will fail as it performs a type
|
|
|
220 |
check as well as a comparison between the two values.
|
|
|
221 |
The "%s" part is replaced by the default
|
|
|
222 |
error message that would have been shown if we had not
|
|
|
223 |
supplied our own.
|
|
|
224 |
This also allows us to nest test messages.
|
|
|
225 |
<pre>
|
|
|
226 |
<strong>$a = 1;
|
|
|
227 |
$b = $a;
|
|
|
228 |
$this->assertReference($a, $b);</strong>
|
|
|
229 |
</pre>
|
|
|
230 |
Will fail as the variable <span class="new_code">$a</span> is a copy of <span class="new_code">$b</span>.
|
|
|
231 |
<pre>
|
|
|
232 |
<strong>$this->assertPattern('/hello/i', 'Hello world');</strong>
|
|
|
233 |
</pre>
|
|
|
234 |
This will pass as using a case insensitive match the string
|
|
|
235 |
<span class="new_code">hello</span> is contained in <span class="new_code">Hello world</span>.
|
|
|
236 |
<pre>
|
|
|
237 |
<strong>trigger_error('Disaster');
|
|
|
238 |
trigger_error('Catastrophe');
|
|
|
239 |
$this->assertError();
|
|
|
240 |
$this->assertError('Catastrophe');
|
|
|
241 |
$this->assertNoErrors();</strong>
|
|
|
242 |
</pre>
|
|
|
243 |
This one takes some explanation as in fact they all pass!
|
|
|
244 |
</p>
|
|
|
245 |
<p>
|
|
|
246 |
PHP errors in SimpleTest are trapped and placed in a queue.
|
|
|
247 |
Here the first error check catches the "Disaster"
|
|
|
248 |
message without checking the text and passes.
|
|
|
249 |
This removes the error from the queue.
|
|
|
250 |
The next error check tests not only the existence of the error,
|
|
|
251 |
but also the text which here matches so another pass.
|
|
|
252 |
With the queue now empty the last test will pass as well.
|
|
|
253 |
If any unchecked errors are left at the end of a test method then
|
|
|
254 |
an exception will be reported in the test.
|
|
|
255 |
Note that SimpleTest cannot catch compile time PHP errors.
|
|
|
256 |
</p>
|
|
|
257 |
<p>
|
|
|
258 |
The test cases also have some convenience methods for debugging
|
|
|
259 |
code or extending the suite...
|
|
|
260 |
<table>
|
|
|
261 |
<tbody>
|
|
|
262 |
<tr>
|
|
|
263 |
<td><span class="new_code">setUp()</span></td><td>Runs this before each test method</td>
|
|
|
264 |
</tr>
|
|
|
265 |
<tr>
|
|
|
266 |
<td><span class="new_code">tearDown()</span></td><td>Runs this after each test method</td>
|
|
|
267 |
</tr>
|
|
|
268 |
<tr>
|
|
|
269 |
<td><span class="new_code">pass()</span></td><td>Sends a test pass</td>
|
|
|
270 |
</tr>
|
|
|
271 |
<tr>
|
|
|
272 |
<td><span class="new_code">fail()</span></td><td>Sends a test failure</td>
|
|
|
273 |
</tr>
|
|
|
274 |
<tr>
|
|
|
275 |
<td><span class="new_code">error()</span></td><td>Sends an exception event</td>
|
|
|
276 |
</tr>
|
|
|
277 |
<tr>
|
|
|
278 |
<td><span class="new_code">sendMessage()</span></td><td>Sends a status message to those displays that support it</td>
|
|
|
279 |
</tr>
|
|
|
280 |
<tr>
|
|
|
281 |
<td><span class="new_code">signal($type, $payload)</span></td><td>Sends a user defined message to the test reporter</td>
|
|
|
282 |
</tr>
|
|
|
283 |
<tr>
|
|
|
284 |
<td><span class="new_code">dump($var)</span></td><td>Does a formatted <span class="new_code">print_r()</span> for quick and dirty debugging</td>
|
|
|
285 |
</tr>
|
|
|
286 |
<tr>
|
|
|
287 |
<td><span class="new_code">swallowErrors()</span></td><td>Clears the error queue</td>
|
|
|
288 |
</tr>
|
|
|
289 |
</tbody>
|
|
|
290 |
</table>
|
|
|
291 |
</p>
|
|
|
292 |
|
|
|
293 |
<p>
|
|
|
294 |
<a class="target" name="extending_unit">
|
|
|
295 |
<h2>Extending test cases</h2>
|
|
|
296 |
</a>
|
|
|
297 |
</p>
|
|
|
298 |
<p>
|
|
|
299 |
Of course additional test methods can be added to create
|
|
|
300 |
specific types of test case too so as to extend framework...
|
|
|
301 |
<pre>
|
|
|
302 |
require_once('simpletest/unit_tester.php');
|
|
|
303 |
<strong>
|
|
|
304 |
class FileTester extends UnitTestCase {
|
|
|
305 |
function FileTester($name = false) {
|
|
|
306 |
$this->UnitTestCase($name);
|
|
|
307 |
}
|
|
|
308 |
|
|
|
309 |
function assertFileExists($filename, $message = '%s') {
|
|
|
310 |
$this->assertTrue(
|
|
|
311 |
file_exists($filename),
|
|
|
312 |
sprintf($message, 'File [$filename] existence check'));
|
|
|
313 |
}</strong>
|
|
|
314 |
}
|
|
|
315 |
</pre>
|
|
|
316 |
Here the SimpleTest library is held in a folder called
|
|
|
317 |
<em>simpletest</em> that is local.
|
|
|
318 |
Substitute your own path for this.
|
|
|
319 |
</p>
|
|
|
320 |
<p>
|
|
|
321 |
This new case can be now be inherited just like
|
|
|
322 |
a normal test case...
|
|
|
323 |
<pre>
|
|
|
324 |
class FileTestCase extends <strong>FileTester</strong> {
|
|
|
325 |
|
|
|
326 |
function setUp() {
|
|
|
327 |
@unlink('../temp/test.txt');
|
|
|
328 |
}
|
|
|
329 |
|
|
|
330 |
function tearDown() {
|
|
|
331 |
@unlink('../temp/test.txt');
|
|
|
332 |
}
|
|
|
333 |
|
|
|
334 |
function testCreation() {
|
|
|
335 |
$writer = &new FileWriter('../temp/test.txt');
|
|
|
336 |
$writer->write('Hello');<strong>
|
|
|
337 |
$this->assertFileExists('../temp/test.txt');</strong>
|
|
|
338 |
}
|
|
|
339 |
}
|
|
|
340 |
</pre>
|
|
|
341 |
</p>
|
|
|
342 |
<p>
|
|
|
343 |
If you want a test case that does not have all of the
|
|
|
344 |
<span class="new_code">UnitTestCase</span> assertions,
|
|
|
345 |
only your own and <span class="new_code">assertTrue()</span>,
|
|
|
346 |
you need to extend the <span class="new_code">SimpleTestCase</span>
|
|
|
347 |
class instead.
|
|
|
348 |
It is found in <em>simple_test.php</em> rather than
|
|
|
349 |
<em>unit_tester.php</em>.
|
|
|
350 |
See <a href="group_test_documentation.html">later</a> if you
|
|
|
351 |
want to incorporate other unit tester's
|
|
|
352 |
test cases in your test suites.
|
|
|
353 |
</p>
|
|
|
354 |
|
|
|
355 |
<p>
|
|
|
356 |
<a class="target" name="running_unit">
|
|
|
357 |
<h2>Running a single test case</h2>
|
|
|
358 |
</a>
|
|
|
359 |
</p>
|
|
|
360 |
<p>
|
|
|
361 |
You won't often run single test cases except when bashing
|
|
|
362 |
away at a module that is having difficulty and you don't
|
|
|
363 |
want to upset the main test suite.
|
|
|
364 |
Here is the scaffolding needed to run the a lone test case...
|
|
|
365 |
<pre>
|
|
|
366 |
<?php
|
|
|
367 |
require_once('simpletest/unit_tester.php');<strong>
|
|
|
368 |
require_once('simpletest/reporter.php');</strong>
|
|
|
369 |
require_once('../classes/writer.php');
|
|
|
370 |
|
|
|
371 |
class FileTestCase extends UnitTestCase {
|
|
|
372 |
function FileTestCase() {
|
|
|
373 |
$this->UnitTestCase('File test');
|
|
|
374 |
}
|
|
|
375 |
}<strong>
|
|
|
376 |
|
|
|
377 |
$test = &new FileTestCase();
|
|
|
378 |
$test->run(new HtmlReporter());</strong>
|
|
|
379 |
?>
|
|
|
380 |
</pre>
|
|
|
381 |
This script will run as is, but will output zero passes
|
|
|
382 |
and zero failures until test methods are added.
|
|
|
383 |
</p>
|
|
|
384 |
|
|
|
385 |
</div>
|
|
|
386 |
<div class="copyright">
|
|
|
387 |
Copyright<br>Marcus Baker, Jason Sweat, Perrick Penet 2004
|
|
|
388 |
</div>
|
|
|
389 |
</body>
|
|
|
390 |
</html>
|