Subversion-Projekte lars-tiefland.prado

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
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-&gt;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 = &amp;new FileWriter('../temp/test.txt');
94
        $writer-&gt;write('Hello');
95
        $this-&gt;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) &lt; $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) &lt; $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-&gt;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-&gt;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-&gt;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-&gt;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-&gt;assertError();
240
$this-&gt;assertError('Catastrophe');
241
$this-&gt;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-&gt;UnitTestCase($name);
307
    }
308
 
309
    function assertFileExists($filename, $message = '%s') {
310
        $this-&gt;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 = &amp;new FileWriter('../temp/test.txt');
336
        $writer-&gt;write('Hello');<strong>
337
        $this-&gt;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
&lt;?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-&gt;UnitTestCase('File test');
374
        }
375
    }<strong>
376
 
377
    $test = &amp;new FileTestCase();
378
    $test-&gt;run(new HtmlReporter());</strong>
379
?&gt;
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>