source: trunk/server/www/vendors/simpletest/docs/en/form_testing_documentation.html @ 6

Last change on this file since 6 was 6, checked in by sander, 11 years ago

Added SimpleTest? test framework

File size: 14.1 KB
Line 
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
4<title>Simple Test documentation for testing HTML forms</title>
5<link rel="stylesheet" type="text/css" href="docs.css" title="Styles">
6</head>
7<body>
8<div class="menu_back"><div class="menu">
9<a href="index.html">SimpleTest</a>
10                |
11                <a href="overview.html">Overview</a>
12                |
13                <a href="unit_test_documentation.html">Unit tester</a>
14                |
15                <a href="group_test_documentation.html">Group tests</a>
16                |
17                <a href="mock_objects_documentation.html">Mock objects</a>
18                |
19                <a href="partial_mocks_documentation.html">Partial mocks</a>
20                |
21                <a href="reporter_documentation.html">Reporting</a>
22                |
23                <a href="expectation_documentation.html">Expectations</a>
24                |
25                <a href="web_tester_documentation.html">Web tester</a>
26                |
27                <span class="chosen">Testing forms</span>
28                |
29                <a href="authentication_documentation.html">Authentication</a>
30                |
31                <a href="browser_documentation.html">Scriptable browser</a>
32</div></div>
33<h1>Form testing documentation</h1>
34        This page...
35        <ul>
36<li>
37            Changing form values and successfully
38            <a href="#submit">Submitting a simple form</a>
39        </li>
40<li>
41            Handling <a href="#multiple">widgets with multiple values</a>
42            by setting lists.
43        </li>
44<li>
45            Bypassing javascript to <a href="#hidden-field">set a hidden field</a>.
46        </li>
47<li>
48            <a href="#raw">Raw posting</a> when you don't have a button
49            to click.
50        </li>
51</ul>
52<div class="content">
53        <p><a class="target" name="submit"><h2>Submitting a simple form</h2></a></p>
54            <p>
55                When a page is fetched by the <span class="new_code">WebTestCase</span>
56                using <span class="new_code">get()</span> or
57                <span class="new_code">post()</span> the page content is
58                automatically parsed.
59                This results in any form controls that are inside &lt;form&gt; tags
60                being available from within the test case.
61                For example, if we have this snippet of HTML...
62<pre>
63&lt;form&gt;
64    &lt;input type="text" name="a" value="A default" /&gt;
65    &lt;input type="submit" value="Go" /&gt;
66&lt;/form&gt;
67</pre>
68                Which looks like this...
69            </p>
70            <p>
71                <form class="demo">
72                    <input type="text" name="a" value="A default">
73                    <input type="submit" value="Go">
74                </form>
75            </p>
76            <p>
77                We can navigate to this code, via the
78                <a href="http://www.lastcraft.com/form_testing_documentation.php">LastCraft</a>
79                site, with the following test...
80<pre>
81class SimpleFormTests extends WebTestCase {
82    <strong>
83    function testDefaultValue() {
84        $this-&gt;get('http://www.lastcraft.com/form_testing_documentation.php');
85        $this-&gt;assertField('a', 'A default');
86    }</strong>
87}
88</pre>
89                Immediately after loading the page all of the HTML controls are set at
90                their default values just as they would appear in the web browser.
91                The assertion tests that a HTML widget exists in the page with the
92                name "a" and that it is currently set to the value
93                "A default".
94                As usual, we could use a pattern expectation instead if a fixed
95                string.
96            </p>
97            <p>
98                We could submit the form straight away, but first we'll change
99                the value of the text field and only then submit it...
100<pre>
101class SimpleFormTests extends WebTestCase {
102
103    function testDefaultValue() {
104        $this-&gt;get('http://www.my-site.com/');
105        $this-&gt;assertField('a', 'A default');<strong>
106        $this-&gt;setField('a', 'New value');
107        $this-&gt;click('Go');</strong>
108    }
109}
110</pre>
111                Because we didn't specify a method attribute on the form tag, and
112                didn't specify an action either, the test case will follow
113                the usual browser behaviour of submitting the form data as a <em>GET</em>
114                request back to the same location.
115                SimpleTest tries to emulate typical browser behaviour as much as possible,
116                rather than attempting to catch missing attributes on tags.
117                This is because the target of the testing framework is the PHP application
118                logic, not syntax or other errors in the HTML code.
119                For HTML errors, other tools such as
120                <a href="http://www.w3.org/People/Raggett/tidy/">HTMLTidy</a> should be used.
121            </p>
122            <p>
123                If a field is not present in any form, or if an option is unavailable,
124                then <span class="new_code">WebTestCase::setField()</span> will return
125                <span class="new_code">false</span>.
126                For example, suppose we wish to verify that a "Superuser"
127                option is not present in this form...
128<pre>
129&lt;strong&gt;Select type of user to add:&lt;/strong&gt;
130&lt;select name="type"&gt;
131    &lt;option&gt;Subscriber&lt;/option&gt;
132    &lt;option&gt;Author&lt;/option&gt;
133    &lt;option&gt;Administrator&lt;/option&gt;
134&lt;/select&gt;
135</pre>
136                Which looks like...
137            </p>
138            <p>
139                <form class="demo">
140                    <strong>Select type of user to add:</strong>
141                    <select name="type">
142                        <option>Subscriber</option>
143                        <option>Author</option>
144                        <option>Administrator</option>
145                    </select>
146                </form>
147            </p>
148            <p>
149                The following test will confirm it...
150<pre>
151class SimpleFormTests extends WebTestCase {
152    ...
153    function testNoSuperuserChoiceAvailable() {<strong>
154        $this-&gt;get('http://www.lastcraft.com/form_testing_documentation.php');
155        $this-&gt;assertFalse($this-&gt;setField('type', 'Superuser'));</strong>
156    }
157}
158</pre>
159                The selection will not be changed on a failure to set
160                a widget value.
161            </p>
162            <p>
163                Here is the full list of widgets currently supported...
164                <ul>
165                    <li>Text fields, including hidden and password fields.</li>
166                    <li>Submit buttons including the button tag, although not yet reset buttons</li>
167                    <li>Text area. This includes text wrapping behaviour.</li>
168                    <li>Checkboxes, including multiple checkboxes in the same form.</li>
169                    <li>Drop down selections, including multiple selects.</li>
170                    <li>Radio buttons.</li>
171                    <li>Images.</li>
172                </ul>
173            </p>
174            <p>
175                The browser emulation offered by SimpleTest mimics
176                the actions which can be perform by a user on a
177                standard HTML page. Javascript is not supported, and
178                it's unlikely that support will be added any time
179                soon.
180            </p>
181            <p>
182                Of particular note is that the Javascript idiom of
183                passing form results by setting a hidden field cannot
184                be performed using the normal SimpleTest
185                commands. See below for a way to test such forms.
186            </p>
187       
188        <p><a class="target" name="multiple"><h2>Fields with multiple values</h2></a></p>
189            <p>
190                SimpleTest can cope with two types of multivalue controls: Multiple
191                selection drop downs, and multiple checkboxes with the same name
192                within a form.
193                The multivalue nature of these means that setting and testing
194                are slightly different.
195                Using checkboxes as an example...
196<pre>
197&lt;form class="demo"&gt;
198    &lt;strong&gt;Create privileges allowed:&lt;/strong&gt;
199    &lt;input type="checkbox" name="crud" value="c" checked&gt;&lt;br&gt;
200    &lt;strong&gt;Retrieve privileges allowed:&lt;/strong&gt;
201    &lt;input type="checkbox" name="crud" value="r" checked&gt;&lt;br&gt;
202    &lt;strong&gt;Update privileges allowed:&lt;/strong&gt;
203    &lt;input type="checkbox" name="crud" value="u" checked&gt;&lt;br&gt;
204    &lt;strong&gt;Destroy privileges allowed:&lt;/strong&gt;
205    &lt;input type="checkbox" name="crud" value="d" checked&gt;&lt;br&gt;
206    &lt;input type="submit" value="Enable Privileges"&gt;
207&lt;/form&gt;
208</pre>
209                Which renders as...
210            </p>
211            <p>
212                <form class="demo">
213                    <strong>Create privileges allowed:</strong>
214                    <input type="checkbox" name="crud" value="c" checked><br>
215                    <strong>Retrieve privileges allowed:</strong>
216                    <input type="checkbox" name="crud" value="r" checked><br>
217                    <strong>Update privileges allowed:</strong>
218                    <input type="checkbox" name="crud" value="u" checked><br>
219                    <strong>Destroy privileges allowed:</strong>
220                    <input type="checkbox" name="crud" value="d" checked><br>
221                    <input type="submit" value="Enable Privileges">
222                </form>
223            </p>
224            <p>
225                If we wish to disable all but the retrieval privileges and
226                submit this information we can do it like this...
227<pre>
228class SimpleFormTests extends WebTestCase {
229    ...<strong>
230    function testDisableNastyPrivileges() {
231        $this-&gt;get('http://www.lastcraft.com/form_testing_documentation.php');
232        $this-&gt;assertField('crud', array('c', 'r', 'u', 'd'));
233        $this-&gt;setField('crud', array('r'));
234        $this-&gt;click('Enable Privileges');
235    }</strong>
236}
237</pre>
238                Instead of setting the field to a single value, we give it a list
239                of values.
240                We do the same when testing expected values.
241                We can then write other test code to confirm the effect of this, perhaps
242                by logging in as that user and attempting an update.
243            </p>
244       
245        <p><a class="target" name="hidden-field"><h2>Forms which use javascript to set a hidden field</h2></a></p>
246            <p>
247                If you want to test a form which relies on javascript to set a hidden
248                field, you can't just call setField().
249                The following code will <em>not</em> work:
250<pre>
251class SimpleFormTests extends WebTestCase {
252    function testMyJavascriptForm() {
253        <strong>// This does *not* work</strong>
254        $this-&gt;setField('a_hidden_field', '123');
255        $this-&gt;clickSubmit('OK');
256    }
257}
258</pre>
259                Instead, you need to pass the additional form parameters to the
260                clickSubmit() method:
261<pre>
262class SimpleFormTests extends WebTestCase {
263    function testMyJavascriptForm() {
264        // Pass the hidden field value as an additional POST variable
265        <strong>$this-&gt;clickSubmit('OK', array('a_hidden_field'=&gt;'123'));</strong>
266    }
267
268}
269</pre>
270            </p>
271            <p>
272                Bear in mind that in doing this you're effectively stubbing out a
273                part of your software (the javascript code in the form), and
274                perhaps you might be better off using something like
275                <a href="http://selenium.openqa.org/">Selenium</a> to ensure a complete
276                acceptance test.
277            </p>
278       
279        <p><a class="target" name="raw"><h2>Raw posting</h2></a></p>
280            <p>
281                If you want to test a form handler, but have not yet written
282                or do not have access to the form itself, you can create a
283                form submission by hand.
284<pre>
285class SimpleFormTests extends WebTestCase {
286    ...<strong>   
287    function testAttemptedHack() {
288        $this-&gt;post(
289                'http://www.my-site.com/add_user.php',
290                array('type' =&gt; 'superuser'));
291        $this-&gt;assertNoText('user created');
292    }</strong>
293}
294</pre>
295                By adding data to the <span class="new_code">WebTestCase::post()</span>
296                method, we are attempting to fetch the page as a form submission.
297            </p>
298       
299    </div>
300        References and related information...
301        <ul>
302<li>
303            SimpleTest project page on <a href="http://sourceforge.net/projects/simpletest/">SourceForge</a>.
304        </li>
305<li>
306            SimpleTest download page on <a href="http://www.lastcraft.com/simple_test.php">LastCraft</a>.
307        </li>
308<li>
309            The <a href="http://simpletest.org/api/">developer's API for SimpleTest</a>
310            gives full detail on the classes and assertions available.
311        </li>
312</ul>
313<div class="menu_back"><div class="menu">
314<a href="index.html">SimpleTest</a>
315                |
316                <a href="overview.html">Overview</a>
317                |
318                <a href="unit_test_documentation.html">Unit tester</a>
319                |
320                <a href="group_test_documentation.html">Group tests</a>
321                |
322                <a href="mock_objects_documentation.html">Mock objects</a>
323                |
324                <a href="partial_mocks_documentation.html">Partial mocks</a>
325                |
326                <a href="reporter_documentation.html">Reporting</a>
327                |
328                <a href="expectation_documentation.html">Expectations</a>
329                |
330                <a href="web_tester_documentation.html">Web tester</a>
331                |
332                <span class="chosen">Testing forms</span>
333                |
334                <a href="authentication_documentation.html">Authentication</a>
335                |
336                <a href="browser_documentation.html">Scriptable browser</a>
337</div></div>
338<div class="copyright">
339            Copyright<br>Marcus Baker 2006
340        </div>
341</body>
342</html>
Note: See TracBrowser for help on using the repository browser.