root/misc/ep2006.txt

Revision 52 (checked in by johnny, 6 years ago)

More data.

Line 
1
2     =========
3     HyperTest
4     =========
5
6         Guido Wesdorp
7         EuroPython 2006
8         guido@merlinux.de
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27     Introduction
28     ============
29
30       * More JavaScript :|
31
32       * EcmaUnit, HTTPUnit, AppTest
33
34       * Python command-line runner
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51     Existing solutions, and why they suck
52     =====================================
53
54       * Unit tests suites
55
56       * Functional testing
57
58       * No AJAX, no low-level JS testing
59
60       * Haven't seen everything yet...
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75     EcmaUnit - Unit tests
76     =====================
77
78       * Origin: Kupu
79
80       * Traditional unit test API, like Python's 'unittest'
81
82       * May be replaced with more light-weight lib later
83
84       * Also works in Spidermonkey
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99     function TestTestCase() {
100         this.name = 'TestTestCase';
101
102         this.setUp = function() {
103             /* not in use here */
104         };
105
106         this.testAssert = function() {
107             this.assert(true);
108             this.assertThrows(this.assert, undefined, this, false);
109         };
110            
111         this.testAssertEquals = function() {
112             this.assertEquals('foo', 'foo');
113             this.assertThrows(this.assertEquals, undefined, this,
114                                 'foo', 'bar');
115         };
116     };
117
118     TestTestCase.prototype = new TestCase;
119
120     window.ecmaunit_test_registry.push(TestTestCase);
121
122
123     HTTP (REST) tests
124     =================
125
126       * Uses XMLHttpRequest
127
128       * Examine returned headers and body
129
130       * Test with real clients
131
132       * Can mostly be replaced with server-side tests,
133
134       * but nice when all tests are JS
135
136
137
138
139
140
141
142
143
144
145
146
147     function test_square_root(testcase, status, headers, body) {
148         testcase.assertEquals(status, '200');
149         testcase.assertEquals(headers['content-type'].substr(0, 10),
150                                 'text/plain');
151         testcase.assertEquals(string.strip(body), '4');
152     };
153
154     window.httpunit_test_registry.push([
155         test_square_root, // test function
156         'httptestdata/square_root.txt', // url to test
157         'POST', // method
158         {'Content-Type': 'application/x-www-form-urlencoded'}, // headers
159         'int=16' // body
160     ]);
161
162
163
164
165
166
167
168
169
170
171     App (functional) tests
172     ======================
173
174       * Sequence of user actions
175
176       * Low-level functional testing
177
178       * Light-weight framework with some helper functions
179
180       * More high-level APIs will be made available later
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195     function test_sync(at, browser) {
196         /* simple test of a plain HTML document */
197         at.assertEquals(browser.title,
198                                 'Test document 1');
199         at.assertEquals(
200             string.strip(
201                 browser.document.getElementsByTagName(
202                     'body'
203                 )[0].childNodes[0].nodeValue
204             ),
205             'Test document content'
206         );
207         // in the end we have to make sure we send the browser to the right
208         // next location, either by clicking a button or by setting a new
209         // location
210         browser.navigateTo('test_async.html');
211     };
212
213     window.app_test_registry.push(['test_sync.html', test_sync]);
214
215
216
217
218
219     AJAX - hard to test
220     ===================
221
222       * Outside of any main loops
223
224       * Errors in event handlers can not be caught
225
226       * No sleep() or tight loops
227
228       * Polling or callbacks
229
230       * No test suites that handle it
231
232
233
234
235
236
237
238
239
240
241
242
243     Async app tests
244     ===============
245
246       * Return special value, continue outside of the test function
247
248       * User has to navigate away *and* call callback when done
249
250       * Errors are not caught, user has to do error handling
251
252       * No other ways to solve it... but at least it's possible!
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267     var poll_and_continue = function(at, browser, callback, orgtext) {
268         var newtext = browser.getText(
269             browser.document.getElementById('container')
270         );
271         if (newtext == orgtext) {
272             misclib.schedule(window, poll_and_continue, 100, at,
273                                 browser, callback, orgtext);
274             return;
275         };
276         at.assertEquals(string.strip(newtext), 'Text loaded');
277         callback();
278     };
279     function test_async(at, browser, callback) {
280         var orgtext = browser.getText(
281             browser.document.getElementById('container')
282         );
283         poll_and_continue(at, browser, callback, orgtext);
284         browser.getElementsByText('load')[0].click();
285        
286         return at.CONTINUE_ASYNC;
287     };
288     window.app_test_registry.push(['test_async.html', test_async]);
289
290
291     Browsertest test runner
292     =======================
293
294       * Python script
295
296       * boots web server and runs browsers
297
298       * browsers POST results to web server
299
300       * web server receives and processes results
301
302       * integration into Python test libs (py.test)
303
304
305
306
307
308
309
310
311
312
313
314
315     johnny@medusa:~/projects/hypertest/trunk/hypertest$ ./run_browsertest
316     Going to test browser: epiphany
317     TestEcmaUnitTestCase (testecmaunit.js, js test)
318     TestTestCase - testAssert: OK
319     TestTestCase - testAssertEquals: OK
320     TestTestCase - testAssertNotEquals: OK
321     TestTestCase - testAssertTrue: OK
322     TestTestCase - testAssertFalse: OK
323     TestTestCase - testAssertThrows: OK
324     time spent: 8 msecs
325
326     TestHTTPUnitTestCase (testhttpunittests.js, http test)
327     TestHTTPUnitTestCase - test_square_root: OK
328     time spent: 75 msecs
329
330     TestAppTestTestCase (testapptests.js, app test)
331     TestAppTestTestCase - apptestdata/test_sync.html: OK
332     TestAppTestTestCase - apptestdata/test_async.html: OK
333     time spent: 439 msecs
334
335     johnny@medusa:~/projects/hypertest/trunk/hypertest$
336
337
338
339     py.test integration
340     ===================
341
342       * Hopefully soon...
343
344       * Unit test integration via spidermonkey
345
346       * Full integration using browsertest
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363     References
364     ==========
365
366       * http://hypertest.johnnydebris.net
367
368       * http://johnnydebris.net:8080/svn
369
370       * http://kupu.oscom.org
371
372       * guido@merlinux.de
373
374
375
376
377
378
379
380
381
382
383
384
385
386
Note: See TracBrowser for help on using the browser.