File: display_subclass_tutorial.xml

package info (click to toggle)
postfixadmin 2.3.5-2%2Bdeb7u1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 6,200 kB
  • sloc: php: 25,767; xml: 14,485; perl: 964; sh: 664; python: 169; makefile: 84
file content (273 lines) | stat: -rw-r--r-- 11,670 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
<?xml version="1.0"?>
<page title="Changing the test display" here="Showing passes">
    <long_title>PHP unit testing tutorial - Subclassing the test display</long_title>
    <content>
        <p>
            The display component of SimpleTest is actually the part
            to be developed last.
            Some of the following section will change in the future
            and hopefully more sophisticated display components will
            be written, but
            in the meantime if a minimal display is not enough, here
            is how to roll your own.
        </p>
        <p>
            <a class="target" name="passes"><h2>I want to see the passes!</h2></a>
        </p>
        <p>
            Oh all right then, here&apos;s how.
        </p>
        <p>
            We have to subclass the attached display, which in our case
            is currently <code>HtmlReporter</code>.
            The <code>HtmlReporter</code> class is in
            the file <em>simpletest/reporter.php</em> and currently has
            the following interface...
<php><![CDATA[
class HtmlReporter extends TestDisplay {
    public TestHtmlDisplay() { ... }
    public void paintHeader(string $test_name) { ... }
    public void paintFooter(string $test_name) { ... }
    public void paintStart(string $test_name, $size) { ... }
    public void paintEnd(string $test_name, $size) { ... }
    public void paintFail(string $message) { ... }
    public void paintPass(string $message) { ... }
    protected string _getCss() { ... }
    public array getTestList() { ... }
    public integer getPassCount() { ... }
    public integer getFailCount() { ... }
    public integer getTestCaseCount() { ... }
    public integer getTestCaseProgress { ... }
}
]]></php>
            Here is what the relevant methods mean.
            You can see the
            <a href="reporter_documentation.php#html">whole list here</a>
            if you are interested.
            <ul class="api">
                <li>
                    <code>HtmlReporter()</code><br />
                    is the constructor.
                    Note that the unit test sets up the link to the display
                    rather than the other way around.
                    The display is a passive receiver of test events.
                    This allows easy adaption of the display for other test
                    systems beside unit tests, such as monitoring servers.
                    It also means that the unit test can write to more than
                    one display at a time.
                </li>
                <li>
                    <code>void paintFail(string $message)</code><br />
                    paints a failure.
                    See below.
                </li>
                <li>
                    <code>void paintPass(string $message)</code><br />
                    by default does nothing.
                    This is the method we will modify.
                </li>
                <li>
                    <code>string _getCss()</code><br />
                    returns the CSS styles as a string for the page header
                    method.
                    Additional styles have to be appended here.
                </li>
                <li>
                    <code>array getTestList()</code><br />
                    is a convenience method for subclasses.
                    Lists the current nesting of the tests as a list
                    of test names.
                    The first, most deeply nested test, is first in the
                    list and the current test method will be last.
                </li>
            </ul>
        </p>
        <p>
            To show the passes we just need the
            <code>paintPass()</code> method to behave
            just like <code>paintFail()</code>.
            Of course we won&apos;t modify the original.
            We&apos;ll subclass.
        </p>
        <p>
            <a class="target" name="subclass"><h2>A display subclass</h2></a>
        </p>
        <p>
            Firstly we&apos;ll create a <em>tests/show_passes.php</em> file
            in our logging project and then place in it this empty class...
<php><![CDATA[
<strong><?php
    if (! defined('SIMPLE_TEST')) {
        define('SIMPLE_TEST', 'simpletest/');
    }
    require_once(SIMPLE_TEST . 'reporter.php');
    
    class ShowPasses extends HtmlReporter {
        
        function ShowPasses() {
            $this->HtmlReporter();
        }
    }
?>
]]></php>
            A quick peruse of the
            <a href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/simpletest/simpletest/reporter.php?content-type=text/vnd.viewcvs-markup">SimpleTest code base</a> shows the
            <code>paintFail()</code> implementation
            at the time of writing to look like this...
<php><![CDATA[
function paintFail($message) {
    parent::paintFail($message);
    print "<span class=\"fail\">Fail</span>: ";
    $breadcrumb = $this->getTestList();
    array_shift($breadcrumb);
    print implode("-&gt;", $breadcrumb);
    print "-&gt;$message<br />\n";
}
]]></php>
            Essentially it chains to the parent&apos;s version, which we
            have to do also to preserve house keeping, and then
            prints a breadcrumbs trail calculated from the current test
            list.
            It drops the top level tests name, though.
            As it is the same on every test that would be a little bit too
            much information.
            Transposing this to our new class...
<php><![CDATA[
class ShowPasses extends HtmlReporter {
    
    function ShowPasses() {
        $this->HtmlReporter();
    }
    <strong>
    function paintPass($message) {
        parent::paintPass($message);
        print "<span class=\"pass\">Pass</span>: ";
        $breadcrumb = $this->getTestList();
        array_shift($breadcrumb);
        print implode("-&gt;", $breadcrumb);
        print "-&gt;$message<br />\n";
    }</strong>
}
]]></php>
            So far so good.
            Now to make use of our new class we have to modify our
            <em>tests/all_tests.php</em> file...
<php><![CDATA[
<?php
    if (! defined('SIMPLE_TEST')) {
        define('SIMPLE_TEST', 'simpletest/');
    }
    require_once(SIMPLE_TEST . 'unit_tester.php');<strong>
    require_once('show_passes.php');</strong>

    $test = &new TestSuite('All tests');
    $test->addTestFile('log_test.php');
    $test->addTestFile('clock_test.php');
    $test->run(<strong>new ShowPasses()</strong>);
?>
]]></php>
            We can run this to see the results of our handywork...
            <div class="demo">
                <h1>All tests</h1>
                Pass: log_test.php-&gt;Log class test-&gt;testappendingtofile-&gt;Expecting [/Test line 1/] in [Test line 1]<br />
                Pass: log_test.php-&gt;Log class test-&gt;testappendingtofile-&gt;Expecting [/Test line 2/] in [Test line 2]<br />
                Pass: log_test.php-&gt;Log class test-&gt;testcreatingnewfile-&gt;Created before message<br />
                Pass: log_test.php-&gt;Log class test-&gt;testcreatingnewfile-&gt;File created<br />
                Pass: clock_test.php-&gt;Clock class test-&gt;testclockadvance-&gt;Advancement<br />
                Pass: clock_test.php-&gt;Clock class test-&gt;testclocktellstime-&gt;Now is the right time<br />
                <div style="padding: 8px; margin-top: 1em; background-color: green; color: white;">3/3 test cases complete.
                <strong>6</strong> passes and <strong>0</strong> fails.</div>
            </div>
            Nice, but no gold star.
            We have lost a little formatting here.
            The display does not have a CSS style for
            <code>span.pass</code>, but we can add this
            easily by overriding one more method...
<php><![CDATA[
class ShowPasses extends HtmlReporter {
    
    function ShowPasses() {
        $this->HtmlReporter();
    }
    
    function paintPass($message) {
        parent::paintPass($message);
        print "<span class=\"pass\">Pass</span>: ";
        $breadcrumb = $this->getTestList();
        array_shift($breadcrumb);
        print implode("-&gt;", $breadcrumb);
        print "->$message<br />\n";
    }
    <strong>
    function _getCss() {
        return parent::_getCss() . ' .pass { color: green; }';
    }</strong>
}
]]></php>
            If you are adding the code as you go, you will see the style
            appended when you do view source on the test results page in your browser.
            To the eye the display itself should now look like this...
            <div class="demo">
                <h1>All tests</h1>
                <span class="pass">Pass</span>: log_test.php-&gt;Log class test-&gt;testappendingtofile-&gt;Expecting [/Test line 1/] in [Test line 1]<br />
                <span class="pass">Pass</span>: log_test.php-&gt;Log class test-&gt;testappendingtofile-&gt;Expecting [/Test line 2/] in [Test line 2]<br />
                <span class="pass">Pass</span>: log_test.php-&gt;Log class test-&gt;testcreatingnewfile-&gt;Created before message<br />
                <span class="pass">Pass</span>: log_test.php-&gt;Log class test-&gt;testcreatingnewfile-&gt;File created<br />
                <span class="pass">Pass</span>: clock_test.php-&gt;Clock class test-&gt;testclockadvance-&gt;Advancement<br />
                <span class="pass">Pass</span>: clock_test.php-&gt;Clock class test-&gt;testclocktellstime-&gt;Now is the right time<br />
                <div style="padding: 8px; margin-top: 1em; background-color: green; color: white;">3/3 test cases complete.
                <strong>6</strong> passes and <strong>0</strong> fails.</div>
            </div>
            Some people definitely prefer to see the passes being added
            as they are working on code; the feeling that you are getting
            work done is nice after all.
            Once you have to scroll up and down the page to find failures
            though, you soon come to realise its dark side.
        </p>
        <p>
            Try it both ways and see which you prefer.
            We&apos;ll leave it in for a bit anyhow when looking at the
            <a href="mock_objects_tutorial.php">mock objects coming up</a>.
            This is the first test tool that generates additional tests
            and it will be useful to see what is happening behind the scenes.
        </p>
    </content>
    <internal>
        <link>
            How to Change the display to <a href="#passes">show test passes</a>.
        </link>
        <link>
            <a href="#subclass">Subclassing the <code>HtmlReporter</code> class</a>.
        </link>
    </internal>
    <external>
        <link>
            The previous tutorial section was
            <a href="subclass_tutorial.php">subclassing the test case</a>.
        </link>
        <link>
            This section is very specific to
            <a href="simple_test.php">SimpleTest</a>.
            If you use another tool you will want to skip this.
        </link>
    </external>
    <meta>
        <keywords>
            software development test first,
            php general programming advice,
            programming php,
            software development tools,
            php tutorial,
            free php sample code,
            architecture,
            sample test cases,
            php simple test framework,
            php resources,
            php test case examples,
            phpunit,
            simpletest,
            unit test,
            php testing
        </keywords>
    </meta>
</page>