Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | """ |
2 | Test script for doctest. | |
3 | """ | |
4 | ||
5 | from test import test_support | |
6 | import doctest | |
7 | import warnings | |
8 | ||
9 | ###################################################################### | |
10 | ## Sample Objects (used by test cases) | |
11 | ###################################################################### | |
12 | ||
13 | def sample_func(v): | |
14 | """ | |
15 | Blah blah | |
16 | ||
17 | >>> print sample_func(22) | |
18 | 44 | |
19 | ||
20 | Yee ha! | |
21 | """ | |
22 | return v+v | |
23 | ||
24 | class SampleClass: | |
25 | """ | |
26 | >>> print 1 | |
27 | 1 | |
28 | ||
29 | >>> # comments get ignored. so are empty PS1 and PS2 prompts: | |
30 | >>> | |
31 | ... | |
32 | ||
33 | Multiline example: | |
34 | >>> sc = SampleClass(3) | |
35 | >>> for i in range(10): | |
36 | ... sc = sc.double() | |
37 | ... print sc.get(), | |
38 | 6 12 24 48 96 192 384 768 1536 3072 | |
39 | """ | |
40 | def __init__(self, val): | |
41 | """ | |
42 | >>> print SampleClass(12).get() | |
43 | 12 | |
44 | """ | |
45 | self.val = val | |
46 | ||
47 | def double(self): | |
48 | """ | |
49 | >>> print SampleClass(12).double().get() | |
50 | 24 | |
51 | """ | |
52 | return SampleClass(self.val + self.val) | |
53 | ||
54 | def get(self): | |
55 | """ | |
56 | >>> print SampleClass(-5).get() | |
57 | -5 | |
58 | """ | |
59 | return self.val | |
60 | ||
61 | def a_staticmethod(v): | |
62 | """ | |
63 | >>> print SampleClass.a_staticmethod(10) | |
64 | 11 | |
65 | """ | |
66 | return v+1 | |
67 | a_staticmethod = staticmethod(a_staticmethod) | |
68 | ||
69 | def a_classmethod(cls, v): | |
70 | """ | |
71 | >>> print SampleClass.a_classmethod(10) | |
72 | 12 | |
73 | >>> print SampleClass(0).a_classmethod(10) | |
74 | 12 | |
75 | """ | |
76 | return v+2 | |
77 | a_classmethod = classmethod(a_classmethod) | |
78 | ||
79 | a_property = property(get, doc=""" | |
80 | >>> print SampleClass(22).a_property | |
81 | 22 | |
82 | """) | |
83 | ||
84 | class NestedClass: | |
85 | """ | |
86 | >>> x = SampleClass.NestedClass(5) | |
87 | >>> y = x.square() | |
88 | >>> print y.get() | |
89 | 25 | |
90 | """ | |
91 | def __init__(self, val=0): | |
92 | """ | |
93 | >>> print SampleClass.NestedClass().get() | |
94 | 0 | |
95 | """ | |
96 | self.val = val | |
97 | def square(self): | |
98 | return SampleClass.NestedClass(self.val*self.val) | |
99 | def get(self): | |
100 | return self.val | |
101 | ||
102 | class SampleNewStyleClass(object): | |
103 | r""" | |
104 | >>> print '1\n2\n3' | |
105 | 1 | |
106 | 2 | |
107 | 3 | |
108 | """ | |
109 | def __init__(self, val): | |
110 | """ | |
111 | >>> print SampleNewStyleClass(12).get() | |
112 | 12 | |
113 | """ | |
114 | self.val = val | |
115 | ||
116 | def double(self): | |
117 | """ | |
118 | >>> print SampleNewStyleClass(12).double().get() | |
119 | 24 | |
120 | """ | |
121 | return SampleNewStyleClass(self.val + self.val) | |
122 | ||
123 | def get(self): | |
124 | """ | |
125 | >>> print SampleNewStyleClass(-5).get() | |
126 | -5 | |
127 | """ | |
128 | return self.val | |
129 | ||
130 | ###################################################################### | |
131 | ## Fake stdin (for testing interactive debugging) | |
132 | ###################################################################### | |
133 | ||
134 | class _FakeInput: | |
135 | """ | |
136 | A fake input stream for pdb's interactive debugger. Whenever a | |
137 | line is read, print it (to simulate the user typing it), and then | |
138 | return it. The set of lines to return is specified in the | |
139 | constructor; they should not have trailing newlines. | |
140 | """ | |
141 | def __init__(self, lines): | |
142 | self.lines = lines | |
143 | ||
144 | def readline(self): | |
145 | line = self.lines.pop(0) | |
146 | print line | |
147 | return line+'\n' | |
148 | ||
149 | ###################################################################### | |
150 | ## Test Cases | |
151 | ###################################################################### | |
152 | ||
153 | def test_Example(): r""" | |
154 | Unit tests for the `Example` class. | |
155 | ||
156 | Example is a simple container class that holds: | |
157 | - `source`: A source string. | |
158 | - `want`: An expected output string. | |
159 | - `exc_msg`: An expected exception message string (or None if no | |
160 | exception is expected). | |
161 | - `lineno`: A line number (within the docstring). | |
162 | - `indent`: The example's indentation in the input string. | |
163 | - `options`: An option dictionary, mapping option flags to True or | |
164 | False. | |
165 | ||
166 | These attributes are set by the constructor. `source` and `want` are | |
167 | required; the other attributes all have default values: | |
168 | ||
169 | >>> example = doctest.Example('print 1', '1\n') | |
170 | >>> (example.source, example.want, example.exc_msg, | |
171 | ... example.lineno, example.indent, example.options) | |
172 | ('print 1\n', '1\n', None, 0, 0, {}) | |
173 | ||
174 | The first three attributes (`source`, `want`, and `exc_msg`) may be | |
175 | specified positionally; the remaining arguments should be specified as | |
176 | keyword arguments: | |
177 | ||
178 | >>> exc_msg = 'IndexError: pop from an empty list' | |
179 | >>> example = doctest.Example('[].pop()', '', exc_msg, | |
180 | ... lineno=5, indent=4, | |
181 | ... options={doctest.ELLIPSIS: True}) | |
182 | >>> (example.source, example.want, example.exc_msg, | |
183 | ... example.lineno, example.indent, example.options) | |
184 | ('[].pop()\n', '', 'IndexError: pop from an empty list\n', 5, 4, {8: True}) | |
185 | ||
186 | The constructor normalizes the `source` string to end in a newline: | |
187 | ||
188 | Source spans a single line: no terminating newline. | |
189 | >>> e = doctest.Example('print 1', '1\n') | |
190 | >>> e.source, e.want | |
191 | ('print 1\n', '1\n') | |
192 | ||
193 | >>> e = doctest.Example('print 1\n', '1\n') | |
194 | >>> e.source, e.want | |
195 | ('print 1\n', '1\n') | |
196 | ||
197 | Source spans multiple lines: require terminating newline. | |
198 | >>> e = doctest.Example('print 1;\nprint 2\n', '1\n2\n') | |
199 | >>> e.source, e.want | |
200 | ('print 1;\nprint 2\n', '1\n2\n') | |
201 | ||
202 | >>> e = doctest.Example('print 1;\nprint 2', '1\n2\n') | |
203 | >>> e.source, e.want | |
204 | ('print 1;\nprint 2\n', '1\n2\n') | |
205 | ||
206 | Empty source string (which should never appear in real examples) | |
207 | >>> e = doctest.Example('', '') | |
208 | >>> e.source, e.want | |
209 | ('\n', '') | |
210 | ||
211 | The constructor normalizes the `want` string to end in a newline, | |
212 | unless it's the empty string: | |
213 | ||
214 | >>> e = doctest.Example('print 1', '1\n') | |
215 | >>> e.source, e.want | |
216 | ('print 1\n', '1\n') | |
217 | ||
218 | >>> e = doctest.Example('print 1', '1') | |
219 | >>> e.source, e.want | |
220 | ('print 1\n', '1\n') | |
221 | ||
222 | >>> e = doctest.Example('print', '') | |
223 | >>> e.source, e.want | |
224 | ('print\n', '') | |
225 | ||
226 | The constructor normalizes the `exc_msg` string to end in a newline, | |
227 | unless it's `None`: | |
228 | ||
229 | Message spans one line | |
230 | >>> exc_msg = 'IndexError: pop from an empty list' | |
231 | >>> e = doctest.Example('[].pop()', '', exc_msg) | |
232 | >>> e.exc_msg | |
233 | 'IndexError: pop from an empty list\n' | |
234 | ||
235 | >>> exc_msg = 'IndexError: pop from an empty list\n' | |
236 | >>> e = doctest.Example('[].pop()', '', exc_msg) | |
237 | >>> e.exc_msg | |
238 | 'IndexError: pop from an empty list\n' | |
239 | ||
240 | Message spans multiple lines | |
241 | >>> exc_msg = 'ValueError: 1\n 2' | |
242 | >>> e = doctest.Example('raise ValueError("1\n 2")', '', exc_msg) | |
243 | >>> e.exc_msg | |
244 | 'ValueError: 1\n 2\n' | |
245 | ||
246 | >>> exc_msg = 'ValueError: 1\n 2\n' | |
247 | >>> e = doctest.Example('raise ValueError("1\n 2")', '', exc_msg) | |
248 | >>> e.exc_msg | |
249 | 'ValueError: 1\n 2\n' | |
250 | ||
251 | Empty (but non-None) exception message (which should never appear | |
252 | in real examples) | |
253 | >>> exc_msg = '' | |
254 | >>> e = doctest.Example('raise X()', '', exc_msg) | |
255 | >>> e.exc_msg | |
256 | '\n' | |
257 | """ | |
258 | ||
259 | def test_DocTest(): r""" | |
260 | Unit tests for the `DocTest` class. | |
261 | ||
262 | DocTest is a collection of examples, extracted from a docstring, along | |
263 | with information about where the docstring comes from (a name, | |
264 | filename, and line number). The docstring is parsed by the `DocTest` | |
265 | constructor: | |
266 | ||
267 | >>> docstring = ''' | |
268 | ... >>> print 12 | |
269 | ... 12 | |
270 | ... | |
271 | ... Non-example text. | |
272 | ... | |
273 | ... >>> print 'another\example' | |
274 | ... another | |
275 | ... example | |
276 | ... ''' | |
277 | >>> globs = {} # globals to run the test in. | |
278 | >>> parser = doctest.DocTestParser() | |
279 | >>> test = parser.get_doctest(docstring, globs, 'some_test', | |
280 | ... 'some_file', 20) | |
281 | >>> print test | |
282 | <DocTest some_test from some_file:20 (2 examples)> | |
283 | >>> len(test.examples) | |
284 | 2 | |
285 | >>> e1, e2 = test.examples | |
286 | >>> (e1.source, e1.want, e1.lineno) | |
287 | ('print 12\n', '12\n', 1) | |
288 | >>> (e2.source, e2.want, e2.lineno) | |
289 | ("print 'another\\example'\n", 'another\nexample\n', 6) | |
290 | ||
291 | Source information (name, filename, and line number) is available as | |
292 | attributes on the doctest object: | |
293 | ||
294 | >>> (test.name, test.filename, test.lineno) | |
295 | ('some_test', 'some_file', 20) | |
296 | ||
297 | The line number of an example within its containing file is found by | |
298 | adding the line number of the example and the line number of its | |
299 | containing test: | |
300 | ||
301 | >>> test.lineno + e1.lineno | |
302 | 21 | |
303 | >>> test.lineno + e2.lineno | |
304 | 26 | |
305 | ||
306 | If the docstring contains inconsistant leading whitespace in the | |
307 | expected output of an example, then `DocTest` will raise a ValueError: | |
308 | ||
309 | >>> docstring = r''' | |
310 | ... >>> print 'bad\nindentation' | |
311 | ... bad | |
312 | ... indentation | |
313 | ... ''' | |
314 | >>> parser.get_doctest(docstring, globs, 'some_test', 'filename', 0) | |
315 | Traceback (most recent call last): | |
316 | ValueError: line 4 of the docstring for some_test has inconsistent leading whitespace: 'indentation' | |
317 | ||
318 | If the docstring contains inconsistent leading whitespace on | |
319 | continuation lines, then `DocTest` will raise a ValueError: | |
320 | ||
321 | >>> docstring = r''' | |
322 | ... >>> print ('bad indentation', | |
323 | ... ... 2) | |
324 | ... ('bad', 'indentation') | |
325 | ... ''' | |
326 | >>> parser.get_doctest(docstring, globs, 'some_test', 'filename', 0) | |
327 | Traceback (most recent call last): | |
328 | ValueError: line 2 of the docstring for some_test has inconsistent leading whitespace: '... 2)' | |
329 | ||
330 | If there's no blank space after a PS1 prompt ('>>>'), then `DocTest` | |
331 | will raise a ValueError: | |
332 | ||
333 | >>> docstring = '>>>print 1\n1' | |
334 | >>> parser.get_doctest(docstring, globs, 'some_test', 'filename', 0) | |
335 | Traceback (most recent call last): | |
336 | ValueError: line 1 of the docstring for some_test lacks blank after >>>: '>>>print 1' | |
337 | ||
338 | If there's no blank space after a PS2 prompt ('...'), then `DocTest` | |
339 | will raise a ValueError: | |
340 | ||
341 | >>> docstring = '>>> if 1:\n...print 1\n1' | |
342 | >>> parser.get_doctest(docstring, globs, 'some_test', 'filename', 0) | |
343 | Traceback (most recent call last): | |
344 | ValueError: line 2 of the docstring for some_test lacks blank after ...: '...print 1' | |
345 | ||
346 | """ | |
347 | ||
348 | def test_DocTestFinder(): r""" | |
349 | Unit tests for the `DocTestFinder` class. | |
350 | ||
351 | DocTestFinder is used to extract DocTests from an object's docstring | |
352 | and the docstrings of its contained objects. It can be used with | |
353 | modules, functions, classes, methods, staticmethods, classmethods, and | |
354 | properties. | |
355 | ||
356 | Finding Tests in Functions | |
357 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
358 | For a function whose docstring contains examples, DocTestFinder.find() | |
359 | will return a single test (for that function's docstring): | |
360 | ||
361 | >>> finder = doctest.DocTestFinder() | |
362 | ||
363 | We'll simulate a __file__ attr that ends in pyc: | |
364 | ||
365 | >>> import test.test_doctest | |
366 | >>> old = test.test_doctest.__file__ | |
367 | >>> test.test_doctest.__file__ = 'test_doctest.pyc' | |
368 | ||
369 | >>> tests = finder.find(sample_func) | |
370 | ||
371 | >>> print tests # doctest: +ELLIPSIS | |
372 | [<DocTest sample_func from ...:13 (1 example)>] | |
373 | ||
374 | The exact name depends on how test_doctest was invoked, so allow for | |
375 | leading path components. | |
376 | ||
377 | >>> tests[0].filename # doctest: +ELLIPSIS | |
378 | '...test_doctest.py' | |
379 | ||
380 | >>> test.test_doctest.__file__ = old | |
381 | ||
382 | ||
383 | >>> e = tests[0].examples[0] | |
384 | >>> (e.source, e.want, e.lineno) | |
385 | ('print sample_func(22)\n', '44\n', 3) | |
386 | ||
387 | By default, tests are created for objects with no docstring: | |
388 | ||
389 | >>> def no_docstring(v): | |
390 | ... pass | |
391 | >>> finder.find(no_docstring) | |
392 | [] | |
393 | ||
394 | However, the optional argument `exclude_empty` to the DocTestFinder | |
395 | constructor can be used to exclude tests for objects with empty | |
396 | docstrings: | |
397 | ||
398 | >>> def no_docstring(v): | |
399 | ... pass | |
400 | >>> excl_empty_finder = doctest.DocTestFinder(exclude_empty=True) | |
401 | >>> excl_empty_finder.find(no_docstring) | |
402 | [] | |
403 | ||
404 | If the function has a docstring with no examples, then a test with no | |
405 | examples is returned. (This lets `DocTestRunner` collect statistics | |
406 | about which functions have no tests -- but is that useful? And should | |
407 | an empty test also be created when there's no docstring?) | |
408 | ||
409 | >>> def no_examples(v): | |
410 | ... ''' no doctest examples ''' | |
411 | >>> finder.find(no_examples) # doctest: +ELLIPSIS | |
412 | [<DocTest no_examples from ...:1 (no examples)>] | |
413 | ||
414 | Finding Tests in Classes | |
415 | ~~~~~~~~~~~~~~~~~~~~~~~~ | |
416 | For a class, DocTestFinder will create a test for the class's | |
417 | docstring, and will recursively explore its contents, including | |
418 | methods, classmethods, staticmethods, properties, and nested classes. | |
419 | ||
420 | >>> finder = doctest.DocTestFinder() | |
421 | >>> tests = finder.find(SampleClass) | |
422 | >>> tests.sort() | |
423 | >>> for t in tests: | |
424 | ... print '%2s %s' % (len(t.examples), t.name) | |
425 | 3 SampleClass | |
426 | 3 SampleClass.NestedClass | |
427 | 1 SampleClass.NestedClass.__init__ | |
428 | 1 SampleClass.__init__ | |
429 | 2 SampleClass.a_classmethod | |
430 | 1 SampleClass.a_property | |
431 | 1 SampleClass.a_staticmethod | |
432 | 1 SampleClass.double | |
433 | 1 SampleClass.get | |
434 | ||
435 | New-style classes are also supported: | |
436 | ||
437 | >>> tests = finder.find(SampleNewStyleClass) | |
438 | >>> tests.sort() | |
439 | >>> for t in tests: | |
440 | ... print '%2s %s' % (len(t.examples), t.name) | |
441 | 1 SampleNewStyleClass | |
442 | 1 SampleNewStyleClass.__init__ | |
443 | 1 SampleNewStyleClass.double | |
444 | 1 SampleNewStyleClass.get | |
445 | ||
446 | Finding Tests in Modules | |
447 | ~~~~~~~~~~~~~~~~~~~~~~~~ | |
448 | For a module, DocTestFinder will create a test for the class's | |
449 | docstring, and will recursively explore its contents, including | |
450 | functions, classes, and the `__test__` dictionary, if it exists: | |
451 | ||
452 | >>> # A module | |
453 | >>> import new | |
454 | >>> m = new.module('some_module') | |
455 | >>> def triple(val): | |
456 | ... ''' | |
457 | ... >>> print triple(11) | |
458 | ... 33 | |
459 | ... ''' | |
460 | ... return val*3 | |
461 | >>> m.__dict__.update({ | |
462 | ... 'sample_func': sample_func, | |
463 | ... 'SampleClass': SampleClass, | |
464 | ... '__doc__': ''' | |
465 | ... Module docstring. | |
466 | ... >>> print 'module' | |
467 | ... module | |
468 | ... ''', | |
469 | ... '__test__': { | |
470 | ... 'd': '>>> print 6\n6\n>>> print 7\n7\n', | |
471 | ... 'c': triple}}) | |
472 | ||
473 | >>> finder = doctest.DocTestFinder() | |
474 | >>> # Use module=test.test_doctest, to prevent doctest from | |
475 | >>> # ignoring the objects since they weren't defined in m. | |
476 | >>> import test.test_doctest | |
477 | >>> tests = finder.find(m, module=test.test_doctest) | |
478 | >>> tests.sort() | |
479 | >>> for t in tests: | |
480 | ... print '%2s %s' % (len(t.examples), t.name) | |
481 | 1 some_module | |
482 | 3 some_module.SampleClass | |
483 | 3 some_module.SampleClass.NestedClass | |
484 | 1 some_module.SampleClass.NestedClass.__init__ | |
485 | 1 some_module.SampleClass.__init__ | |
486 | 2 some_module.SampleClass.a_classmethod | |
487 | 1 some_module.SampleClass.a_property | |
488 | 1 some_module.SampleClass.a_staticmethod | |
489 | 1 some_module.SampleClass.double | |
490 | 1 some_module.SampleClass.get | |
491 | 1 some_module.__test__.c | |
492 | 2 some_module.__test__.d | |
493 | 1 some_module.sample_func | |
494 | ||
495 | Duplicate Removal | |
496 | ~~~~~~~~~~~~~~~~~ | |
497 | If a single object is listed twice (under different names), then tests | |
498 | will only be generated for it once: | |
499 | ||
500 | >>> from test import doctest_aliases | |
501 | >>> tests = excl_empty_finder.find(doctest_aliases) | |
502 | >>> tests.sort() | |
503 | >>> print len(tests) | |
504 | 2 | |
505 | >>> print tests[0].name | |
506 | test.doctest_aliases.TwoNames | |
507 | ||
508 | TwoNames.f and TwoNames.g are bound to the same object. | |
509 | We can't guess which will be found in doctest's traversal of | |
510 | TwoNames.__dict__ first, so we have to allow for either. | |
511 | ||
512 | >>> tests[1].name.split('.')[-1] in ['f', 'g'] | |
513 | True | |
514 | ||
515 | Filter Functions | |
516 | ~~~~~~~~~~~~~~~~ | |
517 | A filter function can be used to restrict which objects get examined, | |
518 | but this is temporary, undocumented internal support for testmod's | |
519 | deprecated isprivate gimmick. | |
520 | ||
521 | >>> def namefilter(prefix, base): | |
522 | ... return base.startswith('a_') | |
523 | >>> tests = doctest.DocTestFinder(_namefilter=namefilter).find(SampleClass) | |
524 | >>> tests.sort() | |
525 | >>> for t in tests: | |
526 | ... print '%2s %s' % (len(t.examples), t.name) | |
527 | 3 SampleClass | |
528 | 3 SampleClass.NestedClass | |
529 | 1 SampleClass.NestedClass.__init__ | |
530 | 1 SampleClass.__init__ | |
531 | 1 SampleClass.double | |
532 | 1 SampleClass.get | |
533 | ||
534 | By default, that excluded objects with no doctests. exclude_empty=False | |
535 | tells it to include (empty) tests for objects with no doctests. This feature | |
536 | is really to support backward compatibility in what doctest.master.summarize() | |
537 | displays. | |
538 | ||
539 | >>> tests = doctest.DocTestFinder(_namefilter=namefilter, | |
540 | ... exclude_empty=False).find(SampleClass) | |
541 | >>> tests.sort() | |
542 | >>> for t in tests: | |
543 | ... print '%2s %s' % (len(t.examples), t.name) | |
544 | 3 SampleClass | |
545 | 3 SampleClass.NestedClass | |
546 | 1 SampleClass.NestedClass.__init__ | |
547 | 0 SampleClass.NestedClass.get | |
548 | 0 SampleClass.NestedClass.square | |
549 | 1 SampleClass.__init__ | |
550 | 1 SampleClass.double | |
551 | 1 SampleClass.get | |
552 | ||
553 | If a given object is filtered out, then none of the objects that it | |
554 | contains will be added either: | |
555 | ||
556 | >>> def namefilter(prefix, base): | |
557 | ... return base == 'NestedClass' | |
558 | >>> tests = doctest.DocTestFinder(_namefilter=namefilter).find(SampleClass) | |
559 | >>> tests.sort() | |
560 | >>> for t in tests: | |
561 | ... print '%2s %s' % (len(t.examples), t.name) | |
562 | 3 SampleClass | |
563 | 1 SampleClass.__init__ | |
564 | 2 SampleClass.a_classmethod | |
565 | 1 SampleClass.a_property | |
566 | 1 SampleClass.a_staticmethod | |
567 | 1 SampleClass.double | |
568 | 1 SampleClass.get | |
569 | ||
570 | The filter function apply to contained objects, and *not* to the | |
571 | object explicitly passed to DocTestFinder: | |
572 | ||
573 | >>> def namefilter(prefix, base): | |
574 | ... return base == 'SampleClass' | |
575 | >>> tests = doctest.DocTestFinder(_namefilter=namefilter).find(SampleClass) | |
576 | >>> len(tests) | |
577 | 9 | |
578 | ||
579 | Turning off Recursion | |
580 | ~~~~~~~~~~~~~~~~~~~~~ | |
581 | DocTestFinder can be told not to look for tests in contained objects | |
582 | using the `recurse` flag: | |
583 | ||
584 | >>> tests = doctest.DocTestFinder(recurse=False).find(SampleClass) | |
585 | >>> tests.sort() | |
586 | >>> for t in tests: | |
587 | ... print '%2s %s' % (len(t.examples), t.name) | |
588 | 3 SampleClass | |
589 | ||
590 | Line numbers | |
591 | ~~~~~~~~~~~~ | |
592 | DocTestFinder finds the line number of each example: | |
593 | ||
594 | >>> def f(x): | |
595 | ... ''' | |
596 | ... >>> x = 12 | |
597 | ... | |
598 | ... some text | |
599 | ... | |
600 | ... >>> # examples are not created for comments & bare prompts. | |
601 | ... >>> | |
602 | ... ... | |
603 | ... | |
604 | ... >>> for x in range(10): | |
605 | ... ... print x, | |
606 | ... 0 1 2 3 4 5 6 7 8 9 | |
607 | ... >>> x/2 | |
608 | ... 6 | |
609 | ... ''' | |
610 | >>> test = doctest.DocTestFinder().find(f)[0] | |
611 | >>> [e.lineno for e in test.examples] | |
612 | [1, 9, 12] | |
613 | """ | |
614 | ||
615 | def test_DocTestParser(): r""" | |
616 | Unit tests for the `DocTestParser` class. | |
617 | ||
618 | DocTestParser is used to parse docstrings containing doctest examples. | |
619 | ||
620 | The `parse` method divides a docstring into examples and intervening | |
621 | text: | |
622 | ||
623 | >>> s = ''' | |
624 | ... >>> x, y = 2, 3 # no output expected | |
625 | ... >>> if 1: | |
626 | ... ... print x | |
627 | ... ... print y | |
628 | ... 2 | |
629 | ... 3 | |
630 | ... | |
631 | ... Some text. | |
632 | ... >>> x+y | |
633 | ... 5 | |
634 | ... ''' | |
635 | >>> parser = doctest.DocTestParser() | |
636 | >>> for piece in parser.parse(s): | |
637 | ... if isinstance(piece, doctest.Example): | |
638 | ... print 'Example:', (piece.source, piece.want, piece.lineno) | |
639 | ... else: | |
640 | ... print ' Text:', `piece` | |
641 | Text: '\n' | |
642 | Example: ('x, y = 2, 3 # no output expected\n', '', 1) | |
643 | Text: '' | |
644 | Example: ('if 1:\n print x\n print y\n', '2\n3\n', 2) | |
645 | Text: '\nSome text.\n' | |
646 | Example: ('x+y\n', '5\n', 9) | |
647 | Text: '' | |
648 | ||
649 | The `get_examples` method returns just the examples: | |
650 | ||
651 | >>> for piece in parser.get_examples(s): | |
652 | ... print (piece.source, piece.want, piece.lineno) | |
653 | ('x, y = 2, 3 # no output expected\n', '', 1) | |
654 | ('if 1:\n print x\n print y\n', '2\n3\n', 2) | |
655 | ('x+y\n', '5\n', 9) | |
656 | ||
657 | The `get_doctest` method creates a Test from the examples, along with the | |
658 | given arguments: | |
659 | ||
660 | >>> test = parser.get_doctest(s, {}, 'name', 'filename', lineno=5) | |
661 | >>> (test.name, test.filename, test.lineno) | |
662 | ('name', 'filename', 5) | |
663 | >>> for piece in test.examples: | |
664 | ... print (piece.source, piece.want, piece.lineno) | |
665 | ('x, y = 2, 3 # no output expected\n', '', 1) | |
666 | ('if 1:\n print x\n print y\n', '2\n3\n', 2) | |
667 | ('x+y\n', '5\n', 9) | |
668 | """ | |
669 | ||
670 | class test_DocTestRunner: | |
671 | def basics(): r""" | |
672 | Unit tests for the `DocTestRunner` class. | |
673 | ||
674 | DocTestRunner is used to run DocTest test cases, and to accumulate | |
675 | statistics. Here's a simple DocTest case we can use: | |
676 | ||
677 | >>> def f(x): | |
678 | ... ''' | |
679 | ... >>> x = 12 | |
680 | ... >>> print x | |
681 | ... 12 | |
682 | ... >>> x/2 | |
683 | ... 6 | |
684 | ... ''' | |
685 | >>> test = doctest.DocTestFinder().find(f)[0] | |
686 | ||
687 | The main DocTestRunner interface is the `run` method, which runs a | |
688 | given DocTest case in a given namespace (globs). It returns a tuple | |
689 | `(f,t)`, where `f` is the number of failed tests and `t` is the number | |
690 | of tried tests. | |
691 | ||
692 | >>> doctest.DocTestRunner(verbose=False).run(test) | |
693 | (0, 3) | |
694 | ||
695 | If any example produces incorrect output, then the test runner reports | |
696 | the failure and proceeds to the next example: | |
697 | ||
698 | >>> def f(x): | |
699 | ... ''' | |
700 | ... >>> x = 12 | |
701 | ... >>> print x | |
702 | ... 14 | |
703 | ... >>> x/2 | |
704 | ... 6 | |
705 | ... ''' | |
706 | >>> test = doctest.DocTestFinder().find(f)[0] | |
707 | >>> doctest.DocTestRunner(verbose=True).run(test) | |
708 | ... # doctest: +ELLIPSIS | |
709 | Trying: | |
710 | x = 12 | |
711 | Expecting nothing | |
712 | ok | |
713 | Trying: | |
714 | print x | |
715 | Expecting: | |
716 | 14 | |
717 | ********************************************************************** | |
718 | File ..., line 4, in f | |
719 | Failed example: | |
720 | print x | |
721 | Expected: | |
722 | 14 | |
723 | Got: | |
724 | 12 | |
725 | Trying: | |
726 | x/2 | |
727 | Expecting: | |
728 | 6 | |
729 | ok | |
730 | (1, 3) | |
731 | """ | |
732 | def verbose_flag(): r""" | |
733 | The `verbose` flag makes the test runner generate more detailed | |
734 | output: | |
735 | ||
736 | >>> def f(x): | |
737 | ... ''' | |
738 | ... >>> x = 12 | |
739 | ... >>> print x | |
740 | ... 12 | |
741 | ... >>> x/2 | |
742 | ... 6 | |
743 | ... ''' | |
744 | >>> test = doctest.DocTestFinder().find(f)[0] | |
745 | ||
746 | >>> doctest.DocTestRunner(verbose=True).run(test) | |
747 | Trying: | |
748 | x = 12 | |
749 | Expecting nothing | |
750 | ok | |
751 | Trying: | |
752 | print x | |
753 | Expecting: | |
754 | 12 | |
755 | ok | |
756 | Trying: | |
757 | x/2 | |
758 | Expecting: | |
759 | 6 | |
760 | ok | |
761 | (0, 3) | |
762 | ||
763 | If the `verbose` flag is unspecified, then the output will be verbose | |
764 | iff `-v` appears in sys.argv: | |
765 | ||
766 | >>> # Save the real sys.argv list. | |
767 | >>> old_argv = sys.argv | |
768 | ||
769 | >>> # If -v does not appear in sys.argv, then output isn't verbose. | |
770 | >>> sys.argv = ['test'] | |
771 | >>> doctest.DocTestRunner().run(test) | |
772 | (0, 3) | |
773 | ||
774 | >>> # If -v does appear in sys.argv, then output is verbose. | |
775 | >>> sys.argv = ['test', '-v'] | |
776 | >>> doctest.DocTestRunner().run(test) | |
777 | Trying: | |
778 | x = 12 | |
779 | Expecting nothing | |
780 | ok | |
781 | Trying: | |
782 | print x | |
783 | Expecting: | |
784 | 12 | |
785 | ok | |
786 | Trying: | |
787 | x/2 | |
788 | Expecting: | |
789 | 6 | |
790 | ok | |
791 | (0, 3) | |
792 | ||
793 | >>> # Restore sys.argv | |
794 | >>> sys.argv = old_argv | |
795 | ||
796 | In the remaining examples, the test runner's verbosity will be | |
797 | explicitly set, to ensure that the test behavior is consistent. | |
798 | """ | |
799 | def exceptions(): r""" | |
800 | Tests of `DocTestRunner`'s exception handling. | |
801 | ||
802 | An expected exception is specified with a traceback message. The | |
803 | lines between the first line and the type/value may be omitted or | |
804 | replaced with any other string: | |
805 | ||
806 | >>> def f(x): | |
807 | ... ''' | |
808 | ... >>> x = 12 | |
809 | ... >>> print x/0 | |
810 | ... Traceback (most recent call last): | |
811 | ... ZeroDivisionError: integer division or modulo by zero | |
812 | ... ''' | |
813 | >>> test = doctest.DocTestFinder().find(f)[0] | |
814 | >>> doctest.DocTestRunner(verbose=False).run(test) | |
815 | (0, 2) | |
816 | ||
817 | An example may not generate output before it raises an exception; if | |
818 | it does, then the traceback message will not be recognized as | |
819 | signaling an expected exception, so the example will be reported as an | |
820 | unexpected exception: | |
821 | ||
822 | >>> def f(x): | |
823 | ... ''' | |
824 | ... >>> x = 12 | |
825 | ... >>> print 'pre-exception output', x/0 | |
826 | ... pre-exception output | |
827 | ... Traceback (most recent call last): | |
828 | ... ZeroDivisionError: integer division or modulo by zero | |
829 | ... ''' | |
830 | >>> test = doctest.DocTestFinder().find(f)[0] | |
831 | >>> doctest.DocTestRunner(verbose=False).run(test) | |
832 | ... # doctest: +ELLIPSIS | |
833 | ********************************************************************** | |
834 | File ..., line 4, in f | |
835 | Failed example: | |
836 | print 'pre-exception output', x/0 | |
837 | Exception raised: | |
838 | ... | |
839 | ZeroDivisionError: integer division or modulo by zero | |
840 | (1, 2) | |
841 | ||
842 | Exception messages may contain newlines: | |
843 | ||
844 | >>> def f(x): | |
845 | ... r''' | |
846 | ... >>> raise ValueError, 'multi\nline\nmessage' | |
847 | ... Traceback (most recent call last): | |
848 | ... ValueError: multi | |
849 | ... line | |
850 | ... message | |
851 | ... ''' | |
852 | >>> test = doctest.DocTestFinder().find(f)[0] | |
853 | >>> doctest.DocTestRunner(verbose=False).run(test) | |
854 | (0, 1) | |
855 | ||
856 | If an exception is expected, but an exception with the wrong type or | |
857 | message is raised, then it is reported as a failure: | |
858 | ||
859 | >>> def f(x): | |
860 | ... r''' | |
861 | ... >>> raise ValueError, 'message' | |
862 | ... Traceback (most recent call last): | |
863 | ... ValueError: wrong message | |
864 | ... ''' | |
865 | >>> test = doctest.DocTestFinder().find(f)[0] | |
866 | >>> doctest.DocTestRunner(verbose=False).run(test) | |
867 | ... # doctest: +ELLIPSIS | |
868 | ********************************************************************** | |
869 | File ..., line 3, in f | |
870 | Failed example: | |
871 | raise ValueError, 'message' | |
872 | Expected: | |
873 | Traceback (most recent call last): | |
874 | ValueError: wrong message | |
875 | Got: | |
876 | Traceback (most recent call last): | |
877 | ... | |
878 | ValueError: message | |
879 | (1, 1) | |
880 | ||
881 | However, IGNORE_EXCEPTION_DETAIL can be used to allow a mismatch in the | |
882 | detail: | |
883 | ||
884 | >>> def f(x): | |
885 | ... r''' | |
886 | ... >>> raise ValueError, 'message' #doctest: +IGNORE_EXCEPTION_DETAIL | |
887 | ... Traceback (most recent call last): | |
888 | ... ValueError: wrong message | |
889 | ... ''' | |
890 | >>> test = doctest.DocTestFinder().find(f)[0] | |
891 | >>> doctest.DocTestRunner(verbose=False).run(test) | |
892 | (0, 1) | |
893 | ||
894 | But IGNORE_EXCEPTION_DETAIL does not allow a mismatch in the exception type: | |
895 | ||
896 | >>> def f(x): | |
897 | ... r''' | |
898 | ... >>> raise ValueError, 'message' #doctest: +IGNORE_EXCEPTION_DETAIL | |
899 | ... Traceback (most recent call last): | |
900 | ... TypeError: wrong type | |
901 | ... ''' | |
902 | >>> test = doctest.DocTestFinder().find(f)[0] | |
903 | >>> doctest.DocTestRunner(verbose=False).run(test) | |
904 | ... # doctest: +ELLIPSIS | |
905 | ********************************************************************** | |
906 | File ..., line 3, in f | |
907 | Failed example: | |
908 | raise ValueError, 'message' #doctest: +IGNORE_EXCEPTION_DETAIL | |
909 | Expected: | |
910 | Traceback (most recent call last): | |
911 | TypeError: wrong type | |
912 | Got: | |
913 | Traceback (most recent call last): | |
914 | ... | |
915 | ValueError: message | |
916 | (1, 1) | |
917 | ||
918 | If an exception is raised but not expected, then it is reported as an | |
919 | unexpected exception: | |
920 | ||
921 | >>> def f(x): | |
922 | ... r''' | |
923 | ... >>> 1/0 | |
924 | ... 0 | |
925 | ... ''' | |
926 | >>> test = doctest.DocTestFinder().find(f)[0] | |
927 | >>> doctest.DocTestRunner(verbose=False).run(test) | |
928 | ... # doctest: +ELLIPSIS | |
929 | ********************************************************************** | |
930 | File ..., line 3, in f | |
931 | Failed example: | |
932 | 1/0 | |
933 | Exception raised: | |
934 | Traceback (most recent call last): | |
935 | ... | |
936 | ZeroDivisionError: integer division or modulo by zero | |
937 | (1, 1) | |
938 | """ | |
939 | def optionflags(): r""" | |
940 | Tests of `DocTestRunner`'s option flag handling. | |
941 | ||
942 | Several option flags can be used to customize the behavior of the test | |
943 | runner. These are defined as module constants in doctest, and passed | |
944 | to the DocTestRunner constructor (multiple constants should be or-ed | |
945 | together). | |
946 | ||
947 | The DONT_ACCEPT_TRUE_FOR_1 flag disables matches between True/False | |
948 | and 1/0: | |
949 | ||
950 | >>> def f(x): | |
951 | ... '>>> True\n1\n' | |
952 | ||
953 | >>> # Without the flag: | |
954 | >>> test = doctest.DocTestFinder().find(f)[0] | |
955 | >>> doctest.DocTestRunner(verbose=False).run(test) | |
956 | (0, 1) | |
957 | ||
958 | >>> # With the flag: | |
959 | >>> test = doctest.DocTestFinder().find(f)[0] | |
960 | >>> flags = doctest.DONT_ACCEPT_TRUE_FOR_1 | |
961 | >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test) | |
962 | ... # doctest: +ELLIPSIS | |
963 | ********************************************************************** | |
964 | File ..., line 2, in f | |
965 | Failed example: | |
966 | True | |
967 | Expected: | |
968 | 1 | |
969 | Got: | |
970 | True | |
971 | (1, 1) | |
972 | ||
973 | The DONT_ACCEPT_BLANKLINE flag disables the match between blank lines | |
974 | and the '<BLANKLINE>' marker: | |
975 | ||
976 | >>> def f(x): | |
977 | ... '>>> print "a\\n\\nb"\na\n<BLANKLINE>\nb\n' | |
978 | ||
979 | >>> # Without the flag: | |
980 | >>> test = doctest.DocTestFinder().find(f)[0] | |
981 | >>> doctest.DocTestRunner(verbose=False).run(test) | |
982 | (0, 1) | |
983 | ||
984 | >>> # With the flag: | |
985 | >>> test = doctest.DocTestFinder().find(f)[0] | |
986 | >>> flags = doctest.DONT_ACCEPT_BLANKLINE | |
987 | >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test) | |
988 | ... # doctest: +ELLIPSIS | |
989 | ********************************************************************** | |
990 | File ..., line 2, in f | |
991 | Failed example: | |
992 | print "a\n\nb" | |
993 | Expected: | |
994 | a | |
995 | <BLANKLINE> | |
996 | b | |
997 | Got: | |
998 | a | |
999 | <BLANKLINE> | |
1000 | b | |
1001 | (1, 1) | |
1002 | ||
1003 | The NORMALIZE_WHITESPACE flag causes all sequences of whitespace to be | |
1004 | treated as equal: | |
1005 | ||
1006 | >>> def f(x): | |
1007 | ... '>>> print 1, 2, 3\n 1 2\n 3' | |
1008 | ||
1009 | >>> # Without the flag: | |
1010 | >>> test = doctest.DocTestFinder().find(f)[0] | |
1011 | >>> doctest.DocTestRunner(verbose=False).run(test) | |
1012 | ... # doctest: +ELLIPSIS | |
1013 | ********************************************************************** | |
1014 | File ..., line 2, in f | |
1015 | Failed example: | |
1016 | print 1, 2, 3 | |
1017 | Expected: | |
1018 | 1 2 | |
1019 | 3 | |
1020 | Got: | |
1021 | 1 2 3 | |
1022 | (1, 1) | |
1023 | ||
1024 | >>> # With the flag: | |
1025 | >>> test = doctest.DocTestFinder().find(f)[0] | |
1026 | >>> flags = doctest.NORMALIZE_WHITESPACE | |
1027 | >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test) | |
1028 | (0, 1) | |
1029 | ||
1030 | An example from the docs: | |
1031 | >>> print range(20) #doctest: +NORMALIZE_WHITESPACE | |
1032 | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, | |
1033 | 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] | |
1034 | ||
1035 | The ELLIPSIS flag causes ellipsis marker ("...") in the expected | |
1036 | output to match any substring in the actual output: | |
1037 | ||
1038 | >>> def f(x): | |
1039 | ... '>>> print range(15)\n[0, 1, 2, ..., 14]\n' | |
1040 | ||
1041 | >>> # Without the flag: | |
1042 | >>> test = doctest.DocTestFinder().find(f)[0] | |
1043 | >>> doctest.DocTestRunner(verbose=False).run(test) | |
1044 | ... # doctest: +ELLIPSIS | |
1045 | ********************************************************************** | |
1046 | File ..., line 2, in f | |
1047 | Failed example: | |
1048 | print range(15) | |
1049 | Expected: | |
1050 | [0, 1, 2, ..., 14] | |
1051 | Got: | |
1052 | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] | |
1053 | (1, 1) | |
1054 | ||
1055 | >>> # With the flag: | |
1056 | >>> test = doctest.DocTestFinder().find(f)[0] | |
1057 | >>> flags = doctest.ELLIPSIS | |
1058 | >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test) | |
1059 | (0, 1) | |
1060 | ||
1061 | ... also matches nothing: | |
1062 | ||
1063 | >>> for i in range(100): | |
1064 | ... print i**2, #doctest: +ELLIPSIS | |
1065 | 0 1...4...9 16 ... 36 49 64 ... 9801 | |
1066 | ||
1067 | ... can be surprising; e.g., this test passes: | |
1068 | ||
1069 | >>> for i in range(21): #doctest: +ELLIPSIS | |
1070 | ... print i, | |
1071 | 0 1 2 ...1...2...0 | |
1072 | ||
1073 | Examples from the docs: | |
1074 | ||
1075 | >>> print range(20) # doctest:+ELLIPSIS | |
1076 | [0, 1, ..., 18, 19] | |
1077 | ||
1078 | >>> print range(20) # doctest: +ELLIPSIS | |
1079 | ... # doctest: +NORMALIZE_WHITESPACE | |
1080 | [0, 1, ..., 18, 19] | |
1081 | ||
1082 | The REPORT_UDIFF flag causes failures that involve multi-line expected | |
1083 | and actual outputs to be displayed using a unified diff: | |
1084 | ||
1085 | >>> def f(x): | |
1086 | ... r''' | |
1087 | ... >>> print '\n'.join('abcdefg') | |
1088 | ... a | |
1089 | ... B | |
1090 | ... c | |
1091 | ... d | |
1092 | ... f | |
1093 | ... g | |
1094 | ... h | |
1095 | ... ''' | |
1096 | ||
1097 | >>> # Without the flag: | |
1098 | >>> test = doctest.DocTestFinder().find(f)[0] | |
1099 | >>> doctest.DocTestRunner(verbose=False).run(test) | |
1100 | ... # doctest: +ELLIPSIS | |
1101 | ********************************************************************** | |
1102 | File ..., line 3, in f | |
1103 | Failed example: | |
1104 | print '\n'.join('abcdefg') | |
1105 | Expected: | |
1106 | a | |
1107 | B | |
1108 | c | |
1109 | d | |
1110 | f | |
1111 | g | |
1112 | h | |
1113 | Got: | |
1114 | a | |
1115 | b | |
1116 | c | |
1117 | d | |
1118 | e | |
1119 | f | |
1120 | g | |
1121 | (1, 1) | |
1122 | ||
1123 | >>> # With the flag: | |
1124 | >>> test = doctest.DocTestFinder().find(f)[0] | |
1125 | >>> flags = doctest.REPORT_UDIFF | |
1126 | >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test) | |
1127 | ... # doctest: +ELLIPSIS | |
1128 | ********************************************************************** | |
1129 | File ..., line 3, in f | |
1130 | Failed example: | |
1131 | print '\n'.join('abcdefg') | |
1132 | Differences (unified diff with -expected +actual): | |
1133 | @@ -1,7 +1,7 @@ | |
1134 | a | |
1135 | -B | |
1136 | +b | |
1137 | c | |
1138 | d | |
1139 | +e | |
1140 | f | |
1141 | g | |
1142 | -h | |
1143 | (1, 1) | |
1144 | ||
1145 | The REPORT_CDIFF flag causes failures that involve multi-line expected | |
1146 | and actual outputs to be displayed using a context diff: | |
1147 | ||
1148 | >>> # Reuse f() from the REPORT_UDIFF example, above. | |
1149 | >>> test = doctest.DocTestFinder().find(f)[0] | |
1150 | >>> flags = doctest.REPORT_CDIFF | |
1151 | >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test) | |
1152 | ... # doctest: +ELLIPSIS | |
1153 | ********************************************************************** | |
1154 | File ..., line 3, in f | |
1155 | Failed example: | |
1156 | print '\n'.join('abcdefg') | |
1157 | Differences (context diff with expected followed by actual): | |
1158 | *************** | |
1159 | *** 1,7 **** | |
1160 | a | |
1161 | ! B | |
1162 | c | |
1163 | d | |
1164 | f | |
1165 | g | |
1166 | - h | |
1167 | --- 1,7 ---- | |
1168 | a | |
1169 | ! b | |
1170 | c | |
1171 | d | |
1172 | + e | |
1173 | f | |
1174 | g | |
1175 | (1, 1) | |
1176 | ||
1177 | ||
1178 | The REPORT_NDIFF flag causes failures to use the difflib.Differ algorithm | |
1179 | used by the popular ndiff.py utility. This does intraline difference | |
1180 | marking, as well as interline differences. | |
1181 | ||
1182 | >>> def f(x): | |
1183 | ... r''' | |
1184 | ... >>> print "a b c d e f g h i j k l m" | |
1185 | ... a b c d e f g h i j k 1 m | |
1186 | ... ''' | |
1187 | >>> test = doctest.DocTestFinder().find(f)[0] | |
1188 | >>> flags = doctest.REPORT_NDIFF | |
1189 | >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test) | |
1190 | ... # doctest: +ELLIPSIS | |
1191 | ********************************************************************** | |
1192 | File ..., line 3, in f | |
1193 | Failed example: | |
1194 | print "a b c d e f g h i j k l m" | |
1195 | Differences (ndiff with -expected +actual): | |
1196 | - a b c d e f g h i j k 1 m | |
1197 | ? ^ | |
1198 | + a b c d e f g h i j k l m | |
1199 | ? + ++ ^ | |
1200 | (1, 1) | |
1201 | ||
1202 | The REPORT_ONLY_FIRST_FAILURE supresses result output after the first | |
1203 | failing example: | |
1204 | ||
1205 | >>> def f(x): | |
1206 | ... r''' | |
1207 | ... >>> print 1 # first success | |
1208 | ... 1 | |
1209 | ... >>> print 2 # first failure | |
1210 | ... 200 | |
1211 | ... >>> print 3 # second failure | |
1212 | ... 300 | |
1213 | ... >>> print 4 # second success | |
1214 | ... 4 | |
1215 | ... >>> print 5 # third failure | |
1216 | ... 500 | |
1217 | ... ''' | |
1218 | >>> test = doctest.DocTestFinder().find(f)[0] | |
1219 | >>> flags = doctest.REPORT_ONLY_FIRST_FAILURE | |
1220 | >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test) | |
1221 | ... # doctest: +ELLIPSIS | |
1222 | ********************************************************************** | |
1223 | File ..., line 5, in f | |
1224 | Failed example: | |
1225 | print 2 # first failure | |
1226 | Expected: | |
1227 | 200 | |
1228 | Got: | |
1229 | 2 | |
1230 | (3, 5) | |
1231 | ||
1232 | However, output from `report_start` is not supressed: | |
1233 | ||
1234 | >>> doctest.DocTestRunner(verbose=True, optionflags=flags).run(test) | |
1235 | ... # doctest: +ELLIPSIS | |
1236 | Trying: | |
1237 | print 1 # first success | |
1238 | Expecting: | |
1239 | 1 | |
1240 | ok | |
1241 | Trying: | |
1242 | print 2 # first failure | |
1243 | Expecting: | |
1244 | 200 | |
1245 | ********************************************************************** | |
1246 | File ..., line 5, in f | |
1247 | Failed example: | |
1248 | print 2 # first failure | |
1249 | Expected: | |
1250 | 200 | |
1251 | Got: | |
1252 | 2 | |
1253 | (3, 5) | |
1254 | ||
1255 | For the purposes of REPORT_ONLY_FIRST_FAILURE, unexpected exceptions | |
1256 | count as failures: | |
1257 | ||
1258 | >>> def f(x): | |
1259 | ... r''' | |
1260 | ... >>> print 1 # first success | |
1261 | ... 1 | |
1262 | ... >>> raise ValueError(2) # first failure | |
1263 | ... 200 | |
1264 | ... >>> print 3 # second failure | |
1265 | ... 300 | |
1266 | ... >>> print 4 # second success | |
1267 | ... 4 | |
1268 | ... >>> print 5 # third failure | |
1269 | ... 500 | |
1270 | ... ''' | |
1271 | >>> test = doctest.DocTestFinder().find(f)[0] | |
1272 | >>> flags = doctest.REPORT_ONLY_FIRST_FAILURE | |
1273 | >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test) | |
1274 | ... # doctest: +ELLIPSIS | |
1275 | ********************************************************************** | |
1276 | File ..., line 5, in f | |
1277 | Failed example: | |
1278 | raise ValueError(2) # first failure | |
1279 | Exception raised: | |
1280 | ... | |
1281 | ValueError: 2 | |
1282 | (3, 5) | |
1283 | ||
1284 | """ | |
1285 | ||
1286 | def option_directives(): r""" | |
1287 | Tests of `DocTestRunner`'s option directive mechanism. | |
1288 | ||
1289 | Option directives can be used to turn option flags on or off for a | |
1290 | single example. To turn an option on for an example, follow that | |
1291 | example with a comment of the form ``# doctest: +OPTION``: | |
1292 | ||
1293 | >>> def f(x): r''' | |
1294 | ... >>> print range(10) # should fail: no ellipsis | |
1295 | ... [0, 1, ..., 9] | |
1296 | ... | |
1297 | ... >>> print range(10) # doctest: +ELLIPSIS | |
1298 | ... [0, 1, ..., 9] | |
1299 | ... ''' | |
1300 | >>> test = doctest.DocTestFinder().find(f)[0] | |
1301 | >>> doctest.DocTestRunner(verbose=False).run(test) | |
1302 | ... # doctest: +ELLIPSIS | |
1303 | ********************************************************************** | |
1304 | File ..., line 2, in f | |
1305 | Failed example: | |
1306 | print range(10) # should fail: no ellipsis | |
1307 | Expected: | |
1308 | [0, 1, ..., 9] | |
1309 | Got: | |
1310 | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] | |
1311 | (1, 2) | |
1312 | ||
1313 | To turn an option off for an example, follow that example with a | |
1314 | comment of the form ``# doctest: -OPTION``: | |
1315 | ||
1316 | >>> def f(x): r''' | |
1317 | ... >>> print range(10) | |
1318 | ... [0, 1, ..., 9] | |
1319 | ... | |
1320 | ... >>> # should fail: no ellipsis | |
1321 | ... >>> print range(10) # doctest: -ELLIPSIS | |
1322 | ... [0, 1, ..., 9] | |
1323 | ... ''' | |
1324 | >>> test = doctest.DocTestFinder().find(f)[0] | |
1325 | >>> doctest.DocTestRunner(verbose=False, | |
1326 | ... optionflags=doctest.ELLIPSIS).run(test) | |
1327 | ... # doctest: +ELLIPSIS | |
1328 | ********************************************************************** | |
1329 | File ..., line 6, in f | |
1330 | Failed example: | |
1331 | print range(10) # doctest: -ELLIPSIS | |
1332 | Expected: | |
1333 | [0, 1, ..., 9] | |
1334 | Got: | |
1335 | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] | |
1336 | (1, 2) | |
1337 | ||
1338 | Option directives affect only the example that they appear with; they | |
1339 | do not change the options for surrounding examples: | |
1340 | ||
1341 | >>> def f(x): r''' | |
1342 | ... >>> print range(10) # Should fail: no ellipsis | |
1343 | ... [0, 1, ..., 9] | |
1344 | ... | |
1345 | ... >>> print range(10) # doctest: +ELLIPSIS | |
1346 | ... [0, 1, ..., 9] | |
1347 | ... | |
1348 | ... >>> print range(10) # Should fail: no ellipsis | |
1349 | ... [0, 1, ..., 9] | |
1350 | ... ''' | |
1351 | >>> test = doctest.DocTestFinder().find(f)[0] | |
1352 | >>> doctest.DocTestRunner(verbose=False).run(test) | |
1353 | ... # doctest: +ELLIPSIS | |
1354 | ********************************************************************** | |
1355 | File ..., line 2, in f | |
1356 | Failed example: | |
1357 | print range(10) # Should fail: no ellipsis | |
1358 | Expected: | |
1359 | [0, 1, ..., 9] | |
1360 | Got: | |
1361 | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] | |
1362 | ********************************************************************** | |
1363 | File ..., line 8, in f | |
1364 | Failed example: | |
1365 | print range(10) # Should fail: no ellipsis | |
1366 | Expected: | |
1367 | [0, 1, ..., 9] | |
1368 | Got: | |
1369 | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] | |
1370 | (2, 3) | |
1371 | ||
1372 | Multiple options may be modified by a single option directive. They | |
1373 | may be separated by whitespace, commas, or both: | |
1374 | ||
1375 | >>> def f(x): r''' | |
1376 | ... >>> print range(10) # Should fail | |
1377 | ... [0, 1, ..., 9] | |
1378 | ... >>> print range(10) # Should succeed | |
1379 | ... ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE | |
1380 | ... [0, 1, ..., 9] | |
1381 | ... ''' | |
1382 | >>> test = doctest.DocTestFinder().find(f)[0] | |
1383 | >>> doctest.DocTestRunner(verbose=False).run(test) | |
1384 | ... # doctest: +ELLIPSIS | |
1385 | ********************************************************************** | |
1386 | File ..., line 2, in f | |
1387 | Failed example: | |
1388 | print range(10) # Should fail | |
1389 | Expected: | |
1390 | [0, 1, ..., 9] | |
1391 | Got: | |
1392 | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] | |
1393 | (1, 2) | |
1394 | ||
1395 | >>> def f(x): r''' | |
1396 | ... >>> print range(10) # Should fail | |
1397 | ... [0, 1, ..., 9] | |
1398 | ... >>> print range(10) # Should succeed | |
1399 | ... ... # doctest: +ELLIPSIS,+NORMALIZE_WHITESPACE | |
1400 | ... [0, 1, ..., 9] | |
1401 | ... ''' | |
1402 | >>> test = doctest.DocTestFinder().find(f)[0] | |
1403 | >>> doctest.DocTestRunner(verbose=False).run(test) | |
1404 | ... # doctest: +ELLIPSIS | |
1405 | ********************************************************************** | |
1406 | File ..., line 2, in f | |
1407 | Failed example: | |
1408 | print range(10) # Should fail | |
1409 | Expected: | |
1410 | [0, 1, ..., 9] | |
1411 | Got: | |
1412 | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] | |
1413 | (1, 2) | |
1414 | ||
1415 | >>> def f(x): r''' | |
1416 | ... >>> print range(10) # Should fail | |
1417 | ... [0, 1, ..., 9] | |
1418 | ... >>> print range(10) # Should succeed | |
1419 | ... ... # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE | |
1420 | ... [0, 1, ..., 9] | |
1421 | ... ''' | |
1422 | >>> test = doctest.DocTestFinder().find(f)[0] | |
1423 | >>> doctest.DocTestRunner(verbose=False).run(test) | |
1424 | ... # doctest: +ELLIPSIS | |
1425 | ********************************************************************** | |
1426 | File ..., line 2, in f | |
1427 | Failed example: | |
1428 | print range(10) # Should fail | |
1429 | Expected: | |
1430 | [0, 1, ..., 9] | |
1431 | Got: | |
1432 | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] | |
1433 | (1, 2) | |
1434 | ||
1435 | The option directive may be put on the line following the source, as | |
1436 | long as a continuation prompt is used: | |
1437 | ||
1438 | >>> def f(x): r''' | |
1439 | ... >>> print range(10) | |
1440 | ... ... # doctest: +ELLIPSIS | |
1441 | ... [0, 1, ..., 9] | |
1442 | ... ''' | |
1443 | >>> test = doctest.DocTestFinder().find(f)[0] | |
1444 | >>> doctest.DocTestRunner(verbose=False).run(test) | |
1445 | (0, 1) | |
1446 | ||
1447 | For examples with multi-line source, the option directive may appear | |
1448 | at the end of any line: | |
1449 | ||
1450 | >>> def f(x): r''' | |
1451 | ... >>> for x in range(10): # doctest: +ELLIPSIS | |
1452 | ... ... print x, | |
1453 | ... 0 1 2 ... 9 | |
1454 | ... | |
1455 | ... >>> for x in range(10): | |
1456 | ... ... print x, # doctest: +ELLIPSIS | |
1457 | ... 0 1 2 ... 9 | |
1458 | ... ''' | |
1459 | >>> test = doctest.DocTestFinder().find(f)[0] | |
1460 | >>> doctest.DocTestRunner(verbose=False).run(test) | |
1461 | (0, 2) | |
1462 | ||
1463 | If more than one line of an example with multi-line source has an | |
1464 | option directive, then they are combined: | |
1465 | ||
1466 | >>> def f(x): r''' | |
1467 | ... Should fail (option directive not on the last line): | |
1468 | ... >>> for x in range(10): # doctest: +ELLIPSIS | |
1469 | ... ... print x, # doctest: +NORMALIZE_WHITESPACE | |
1470 | ... 0 1 2...9 | |
1471 | ... ''' | |
1472 | >>> test = doctest.DocTestFinder().find(f)[0] | |
1473 | >>> doctest.DocTestRunner(verbose=False).run(test) | |
1474 | (0, 1) | |
1475 | ||
1476 | It is an error to have a comment of the form ``# doctest:`` that is | |
1477 | *not* followed by words of the form ``+OPTION`` or ``-OPTION``, where | |
1478 | ``OPTION`` is an option that has been registered with | |
1479 | `register_option`: | |
1480 | ||
1481 | >>> # Error: Option not registered | |
1482 | >>> s = '>>> print 12 #doctest: +BADOPTION' | |
1483 | >>> test = doctest.DocTestParser().get_doctest(s, {}, 's', 's.py', 0) | |
1484 | Traceback (most recent call last): | |
1485 | ValueError: line 1 of the doctest for s has an invalid option: '+BADOPTION' | |
1486 | ||
1487 | >>> # Error: No + or - prefix | |
1488 | >>> s = '>>> print 12 #doctest: ELLIPSIS' | |
1489 | >>> test = doctest.DocTestParser().get_doctest(s, {}, 's', 's.py', 0) | |
1490 | Traceback (most recent call last): | |
1491 | ValueError: line 1 of the doctest for s has an invalid option: 'ELLIPSIS' | |
1492 | ||
1493 | It is an error to use an option directive on a line that contains no | |
1494 | source: | |
1495 | ||
1496 | >>> s = '>>> # doctest: +ELLIPSIS' | |
1497 | >>> test = doctest.DocTestParser().get_doctest(s, {}, 's', 's.py', 0) | |
1498 | Traceback (most recent call last): | |
1499 | ValueError: line 0 of the doctest for s has an option directive on a line with no example: '# doctest: +ELLIPSIS' | |
1500 | """ | |
1501 | ||
1502 | def test_testsource(): r""" | |
1503 | Unit tests for `testsource()`. | |
1504 | ||
1505 | The testsource() function takes a module and a name, finds the (first) | |
1506 | test with that name in that module, and converts it to a script. The | |
1507 | example code is converted to regular Python code. The surrounding | |
1508 | words and expected output are converted to comments: | |
1509 | ||
1510 | >>> import test.test_doctest | |
1511 | >>> name = 'test.test_doctest.sample_func' | |
1512 | >>> print doctest.testsource(test.test_doctest, name) | |
1513 | # Blah blah | |
1514 | # | |
1515 | print sample_func(22) | |
1516 | # Expected: | |
1517 | ## 44 | |
1518 | # | |
1519 | # Yee ha! | |
1520 | <BLANKLINE> | |
1521 | ||
1522 | >>> name = 'test.test_doctest.SampleNewStyleClass' | |
1523 | >>> print doctest.testsource(test.test_doctest, name) | |
1524 | print '1\n2\n3' | |
1525 | # Expected: | |
1526 | ## 1 | |
1527 | ## 2 | |
1528 | ## 3 | |
1529 | <BLANKLINE> | |
1530 | ||
1531 | >>> name = 'test.test_doctest.SampleClass.a_classmethod' | |
1532 | >>> print doctest.testsource(test.test_doctest, name) | |
1533 | print SampleClass.a_classmethod(10) | |
1534 | # Expected: | |
1535 | ## 12 | |
1536 | print SampleClass(0).a_classmethod(10) | |
1537 | # Expected: | |
1538 | ## 12 | |
1539 | <BLANKLINE> | |
1540 | """ | |
1541 | ||
1542 | def test_debug(): r""" | |
1543 | ||
1544 | Create a docstring that we want to debug: | |
1545 | ||
1546 | >>> s = ''' | |
1547 | ... >>> x = 12 | |
1548 | ... >>> print x | |
1549 | ... 12 | |
1550 | ... ''' | |
1551 | ||
1552 | Create some fake stdin input, to feed to the debugger: | |
1553 | ||
1554 | >>> import tempfile | |
1555 | >>> real_stdin = sys.stdin | |
1556 | >>> sys.stdin = _FakeInput(['next', 'print x', 'continue']) | |
1557 | ||
1558 | Run the debugger on the docstring, and then restore sys.stdin. | |
1559 | ||
1560 | >>> try: doctest.debug_src(s) | |
1561 | ... finally: sys.stdin = real_stdin | |
1562 | > <string>(1)?() | |
1563 | (Pdb) next | |
1564 | 12 | |
1565 | --Return-- | |
1566 | > <string>(1)?()->None | |
1567 | (Pdb) print x | |
1568 | 12 | |
1569 | (Pdb) continue | |
1570 | ||
1571 | """ | |
1572 | ||
1573 | def test_pdb_set_trace(): | |
1574 | """Using pdb.set_trace from a doctest. | |
1575 | ||
1576 | You can use pdb.set_trace from a doctest. To do so, you must | |
1577 | retrieve the set_trace function from the pdb module at the time | |
1578 | you use it. The doctest module changes sys.stdout so that it can | |
1579 | capture program output. It also temporarily replaces pdb.set_trace | |
1580 | with a version that restores stdout. This is necessary for you to | |
1581 | see debugger output. | |
1582 | ||
1583 | >>> doc = ''' | |
1584 | ... >>> x = 42 | |
1585 | ... >>> import pdb; pdb.set_trace() | |
1586 | ... ''' | |
1587 | >>> parser = doctest.DocTestParser() | |
1588 | >>> test = parser.get_doctest(doc, {}, "foo", "foo.py", 0) | |
1589 | >>> runner = doctest.DocTestRunner(verbose=False) | |
1590 | ||
1591 | To demonstrate this, we'll create a fake standard input that | |
1592 | captures our debugger input: | |
1593 | ||
1594 | >>> import tempfile | |
1595 | >>> real_stdin = sys.stdin | |
1596 | >>> sys.stdin = _FakeInput([ | |
1597 | ... 'print x', # print data defined by the example | |
1598 | ... 'continue', # stop debugging | |
1599 | ... '']) | |
1600 | ||
1601 | >>> try: runner.run(test) | |
1602 | ... finally: sys.stdin = real_stdin | |
1603 | --Return-- | |
1604 | > <doctest foo[1]>(1)?()->None | |
1605 | -> import pdb; pdb.set_trace() | |
1606 | (Pdb) print x | |
1607 | 42 | |
1608 | (Pdb) continue | |
1609 | (0, 2) | |
1610 | ||
1611 | You can also put pdb.set_trace in a function called from a test: | |
1612 | ||
1613 | >>> def calls_set_trace(): | |
1614 | ... y=2 | |
1615 | ... import pdb; pdb.set_trace() | |
1616 | ||
1617 | >>> doc = ''' | |
1618 | ... >>> x=1 | |
1619 | ... >>> calls_set_trace() | |
1620 | ... ''' | |
1621 | >>> test = parser.get_doctest(doc, globals(), "foo", "foo.py", 0) | |
1622 | >>> real_stdin = sys.stdin | |
1623 | >>> sys.stdin = _FakeInput([ | |
1624 | ... 'print y', # print data defined in the function | |
1625 | ... 'up', # out of function | |
1626 | ... 'print x', # print data defined by the example | |
1627 | ... 'continue', # stop debugging | |
1628 | ... '']) | |
1629 | ||
1630 | >>> try: | |
1631 | ... runner.run(test) | |
1632 | ... finally: | |
1633 | ... sys.stdin = real_stdin | |
1634 | --Return-- | |
1635 | > <doctest test.test_doctest.test_pdb_set_trace[8]>(3)calls_set_trace()->None | |
1636 | -> import pdb; pdb.set_trace() | |
1637 | (Pdb) print y | |
1638 | 2 | |
1639 | (Pdb) up | |
1640 | > <doctest foo[1]>(1)?() | |
1641 | -> calls_set_trace() | |
1642 | (Pdb) print x | |
1643 | 1 | |
1644 | (Pdb) continue | |
1645 | (0, 2) | |
1646 | ||
1647 | During interactive debugging, source code is shown, even for | |
1648 | doctest examples: | |
1649 | ||
1650 | >>> doc = ''' | |
1651 | ... >>> def f(x): | |
1652 | ... ... g(x*2) | |
1653 | ... >>> def g(x): | |
1654 | ... ... print x+3 | |
1655 | ... ... import pdb; pdb.set_trace() | |
1656 | ... >>> f(3) | |
1657 | ... ''' | |
1658 | >>> test = parser.get_doctest(doc, globals(), "foo", "foo.py", 0) | |
1659 | >>> real_stdin = sys.stdin | |
1660 | >>> sys.stdin = _FakeInput([ | |
1661 | ... 'list', # list source from example 2 | |
1662 | ... 'next', # return from g() | |
1663 | ... 'list', # list source from example 1 | |
1664 | ... 'next', # return from f() | |
1665 | ... 'list', # list source from example 3 | |
1666 | ... 'continue', # stop debugging | |
1667 | ... '']) | |
1668 | >>> try: runner.run(test) | |
1669 | ... finally: sys.stdin = real_stdin | |
1670 | ... # doctest: +NORMALIZE_WHITESPACE | |
1671 | --Return-- | |
1672 | > <doctest foo[1]>(3)g()->None | |
1673 | -> import pdb; pdb.set_trace() | |
1674 | (Pdb) list | |
1675 | 1 def g(x): | |
1676 | 2 print x+3 | |
1677 | 3 -> import pdb; pdb.set_trace() | |
1678 | [EOF] | |
1679 | (Pdb) next | |
1680 | --Return-- | |
1681 | > <doctest foo[0]>(2)f()->None | |
1682 | -> g(x*2) | |
1683 | (Pdb) list | |
1684 | 1 def f(x): | |
1685 | 2 -> g(x*2) | |
1686 | [EOF] | |
1687 | (Pdb) next | |
1688 | --Return-- | |
1689 | > <doctest foo[2]>(1)?()->None | |
1690 | -> f(3) | |
1691 | (Pdb) list | |
1692 | 1 -> f(3) | |
1693 | [EOF] | |
1694 | (Pdb) continue | |
1695 | ********************************************************************** | |
1696 | File "foo.py", line 7, in foo | |
1697 | Failed example: | |
1698 | f(3) | |
1699 | Expected nothing | |
1700 | Got: | |
1701 | 9 | |
1702 | (1, 3) | |
1703 | """ | |
1704 | ||
1705 | def test_pdb_set_trace_nested(): | |
1706 | """This illustrates more-demanding use of set_trace with nested functions. | |
1707 | ||
1708 | >>> class C(object): | |
1709 | ... def calls_set_trace(self): | |
1710 | ... y = 1 | |
1711 | ... import pdb; pdb.set_trace() | |
1712 | ... self.f1() | |
1713 | ... y = 2 | |
1714 | ... def f1(self): | |
1715 | ... x = 1 | |
1716 | ... self.f2() | |
1717 | ... x = 2 | |
1718 | ... def f2(self): | |
1719 | ... z = 1 | |
1720 | ... z = 2 | |
1721 | ||
1722 | >>> calls_set_trace = C().calls_set_trace | |
1723 | ||
1724 | >>> doc = ''' | |
1725 | ... >>> a = 1 | |
1726 | ... >>> calls_set_trace() | |
1727 | ... ''' | |
1728 | >>> parser = doctest.DocTestParser() | |
1729 | >>> runner = doctest.DocTestRunner(verbose=False) | |
1730 | >>> test = parser.get_doctest(doc, globals(), "foo", "foo.py", 0) | |
1731 | >>> real_stdin = sys.stdin | |
1732 | >>> sys.stdin = _FakeInput([ | |
1733 | ... 'print y', # print data defined in the function | |
1734 | ... 'step', 'step', 'step', 'step', 'step', 'step', 'print z', | |
1735 | ... 'up', 'print x', | |
1736 | ... 'up', 'print y', | |
1737 | ... 'up', 'print foo', | |
1738 | ... 'continue', # stop debugging | |
1739 | ... '']) | |
1740 | ||
1741 | >>> try: | |
1742 | ... runner.run(test) | |
1743 | ... finally: | |
1744 | ... sys.stdin = real_stdin | |
1745 | > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(5)calls_set_trace() | |
1746 | -> self.f1() | |
1747 | (Pdb) print y | |
1748 | 1 | |
1749 | (Pdb) step | |
1750 | --Call-- | |
1751 | > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(7)f1() | |
1752 | -> def f1(self): | |
1753 | (Pdb) step | |
1754 | > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(8)f1() | |
1755 | -> x = 1 | |
1756 | (Pdb) step | |
1757 | > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(9)f1() | |
1758 | -> self.f2() | |
1759 | (Pdb) step | |
1760 | --Call-- | |
1761 | > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(11)f2() | |
1762 | -> def f2(self): | |
1763 | (Pdb) step | |
1764 | > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(12)f2() | |
1765 | -> z = 1 | |
1766 | (Pdb) step | |
1767 | > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(13)f2() | |
1768 | -> z = 2 | |
1769 | (Pdb) print z | |
1770 | 1 | |
1771 | (Pdb) up | |
1772 | > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(9)f1() | |
1773 | -> self.f2() | |
1774 | (Pdb) print x | |
1775 | 1 | |
1776 | (Pdb) up | |
1777 | > <doctest test.test_doctest.test_pdb_set_trace_nested[0]>(5)calls_set_trace() | |
1778 | -> self.f1() | |
1779 | (Pdb) print y | |
1780 | 1 | |
1781 | (Pdb) up | |
1782 | > <doctest foo[1]>(1)?() | |
1783 | -> calls_set_trace() | |
1784 | (Pdb) print foo | |
1785 | *** NameError: name 'foo' is not defined | |
1786 | (Pdb) continue | |
1787 | (0, 2) | |
1788 | """ | |
1789 | ||
1790 | def test_DocTestSuite(): | |
1791 | """DocTestSuite creates a unittest test suite from a doctest. | |
1792 | ||
1793 | We create a Suite by providing a module. A module can be provided | |
1794 | by passing a module object: | |
1795 | ||
1796 | >>> import unittest | |
1797 | >>> import test.sample_doctest | |
1798 | >>> suite = doctest.DocTestSuite(test.sample_doctest) | |
1799 | >>> suite.run(unittest.TestResult()) | |
1800 | <unittest.TestResult run=9 errors=0 failures=4> | |
1801 | ||
1802 | We can also supply the module by name: | |
1803 | ||
1804 | >>> suite = doctest.DocTestSuite('test.sample_doctest') | |
1805 | >>> suite.run(unittest.TestResult()) | |
1806 | <unittest.TestResult run=9 errors=0 failures=4> | |
1807 | ||
1808 | We can use the current module: | |
1809 | ||
1810 | >>> suite = test.sample_doctest.test_suite() | |
1811 | >>> suite.run(unittest.TestResult()) | |
1812 | <unittest.TestResult run=9 errors=0 failures=4> | |
1813 | ||
1814 | We can supply global variables. If we pass globs, they will be | |
1815 | used instead of the module globals. Here we'll pass an empty | |
1816 | globals, triggering an extra error: | |
1817 | ||
1818 | >>> suite = doctest.DocTestSuite('test.sample_doctest', globs={}) | |
1819 | >>> suite.run(unittest.TestResult()) | |
1820 | <unittest.TestResult run=9 errors=0 failures=5> | |
1821 | ||
1822 | Alternatively, we can provide extra globals. Here we'll make an | |
1823 | error go away by providing an extra global variable: | |
1824 | ||
1825 | >>> suite = doctest.DocTestSuite('test.sample_doctest', | |
1826 | ... extraglobs={'y': 1}) | |
1827 | >>> suite.run(unittest.TestResult()) | |
1828 | <unittest.TestResult run=9 errors=0 failures=3> | |
1829 | ||
1830 | You can pass option flags. Here we'll cause an extra error | |
1831 | by disabling the blank-line feature: | |
1832 | ||
1833 | >>> suite = doctest.DocTestSuite('test.sample_doctest', | |
1834 | ... optionflags=doctest.DONT_ACCEPT_BLANKLINE) | |
1835 | >>> suite.run(unittest.TestResult()) | |
1836 | <unittest.TestResult run=9 errors=0 failures=5> | |
1837 | ||
1838 | You can supply setUp and tearDown functions: | |
1839 | ||
1840 | >>> def setUp(t): | |
1841 | ... import test.test_doctest | |
1842 | ... test.test_doctest.sillySetup = True | |
1843 | ||
1844 | >>> def tearDown(t): | |
1845 | ... import test.test_doctest | |
1846 | ... del test.test_doctest.sillySetup | |
1847 | ||
1848 | Here, we installed a silly variable that the test expects: | |
1849 | ||
1850 | >>> suite = doctest.DocTestSuite('test.sample_doctest', | |
1851 | ... setUp=setUp, tearDown=tearDown) | |
1852 | >>> suite.run(unittest.TestResult()) | |
1853 | <unittest.TestResult run=9 errors=0 failures=3> | |
1854 | ||
1855 | But the tearDown restores sanity: | |
1856 | ||
1857 | >>> import test.test_doctest | |
1858 | >>> test.test_doctest.sillySetup | |
1859 | Traceback (most recent call last): | |
1860 | ... | |
1861 | AttributeError: 'module' object has no attribute 'sillySetup' | |
1862 | ||
1863 | The setUp and tearDown funtions are passed test objects. Here | |
1864 | we'll use the setUp function to supply the missing variable y: | |
1865 | ||
1866 | >>> def setUp(test): | |
1867 | ... test.globs['y'] = 1 | |
1868 | ||
1869 | >>> suite = doctest.DocTestSuite('test.sample_doctest', setUp=setUp) | |
1870 | >>> suite.run(unittest.TestResult()) | |
1871 | <unittest.TestResult run=9 errors=0 failures=3> | |
1872 | ||
1873 | Here, we didn't need to use a tearDown function because we | |
1874 | modified the test globals, which are a copy of the | |
1875 | sample_doctest module dictionary. The test globals are | |
1876 | automatically cleared for us after a test. | |
1877 | ||
1878 | Finally, you can provide an alternate test finder. Here we'll | |
1879 | use a custom test_finder to to run just the test named bar. | |
1880 | However, the test in the module docstring, and the two tests | |
1881 | in the module __test__ dict, aren't filtered, so we actually | |
1882 | run three tests besides bar's. The filtering mechanisms are | |
1883 | poorly conceived, and will go away someday. | |
1884 | ||
1885 | >>> finder = doctest.DocTestFinder( | |
1886 | ... _namefilter=lambda prefix, base: base!='bar') | |
1887 | >>> suite = doctest.DocTestSuite('test.sample_doctest', | |
1888 | ... test_finder=finder) | |
1889 | >>> suite.run(unittest.TestResult()) | |
1890 | <unittest.TestResult run=4 errors=0 failures=1> | |
1891 | """ | |
1892 | ||
1893 | def test_DocFileSuite(): | |
1894 | """We can test tests found in text files using a DocFileSuite. | |
1895 | ||
1896 | We create a suite by providing the names of one or more text | |
1897 | files that include examples: | |
1898 | ||
1899 | >>> import unittest | |
1900 | >>> suite = doctest.DocFileSuite('test_doctest.txt', | |
1901 | ... 'test_doctest2.txt') | |
1902 | >>> suite.run(unittest.TestResult()) | |
1903 | <unittest.TestResult run=2 errors=0 failures=2> | |
1904 | ||
1905 | The test files are looked for in the directory containing the | |
1906 | calling module. A package keyword argument can be provided to | |
1907 | specify a different relative location. | |
1908 | ||
1909 | >>> import unittest | |
1910 | >>> suite = doctest.DocFileSuite('test_doctest.txt', | |
1911 | ... 'test_doctest2.txt', | |
1912 | ... package='test') | |
1913 | >>> suite.run(unittest.TestResult()) | |
1914 | <unittest.TestResult run=2 errors=0 failures=2> | |
1915 | ||
1916 | '/' should be used as a path separator. It will be converted | |
1917 | to a native separator at run time: | |
1918 | ||
1919 | >>> suite = doctest.DocFileSuite('../test/test_doctest.txt') | |
1920 | >>> suite.run(unittest.TestResult()) | |
1921 | <unittest.TestResult run=1 errors=0 failures=1> | |
1922 | ||
1923 | If DocFileSuite is used from an interactive session, then files | |
1924 | are resolved relative to the directory of sys.argv[0]: | |
1925 | ||
1926 | >>> import new, os.path, test.test_doctest | |
1927 | >>> save_argv = sys.argv | |
1928 | >>> sys.argv = [test.test_doctest.__file__] | |
1929 | >>> suite = doctest.DocFileSuite('test_doctest.txt', | |
1930 | ... package=new.module('__main__')) | |
1931 | >>> sys.argv = save_argv | |
1932 | ||
1933 | By setting `module_relative=False`, os-specific paths may be | |
1934 | used (including absolute paths and paths relative to the | |
1935 | working directory): | |
1936 | ||
1937 | >>> # Get the absolute path of the test package. | |
1938 | >>> test_doctest_path = os.path.abspath(test.test_doctest.__file__) | |
1939 | >>> test_pkg_path = os.path.split(test_doctest_path)[0] | |
1940 | ||
1941 | >>> # Use it to find the absolute path of test_doctest.txt. | |
1942 | >>> test_file = os.path.join(test_pkg_path, 'test_doctest.txt') | |
1943 | ||
1944 | >>> suite = doctest.DocFileSuite(test_file, module_relative=False) | |
1945 | >>> suite.run(unittest.TestResult()) | |
1946 | <unittest.TestResult run=1 errors=0 failures=1> | |
1947 | ||
1948 | It is an error to specify `package` when `module_relative=False`: | |
1949 | ||
1950 | >>> suite = doctest.DocFileSuite(test_file, module_relative=False, | |
1951 | ... package='test') | |
1952 | Traceback (most recent call last): | |
1953 | ValueError: Package may only be specified for module-relative paths. | |
1954 | ||
1955 | You can specify initial global variables: | |
1956 | ||
1957 | >>> suite = doctest.DocFileSuite('test_doctest.txt', | |
1958 | ... 'test_doctest2.txt', | |
1959 | ... globs={'favorite_color': 'blue'}) | |
1960 | >>> suite.run(unittest.TestResult()) | |
1961 | <unittest.TestResult run=2 errors=0 failures=1> | |
1962 | ||
1963 | In this case, we supplied a missing favorite color. You can | |
1964 | provide doctest options: | |
1965 | ||
1966 | >>> suite = doctest.DocFileSuite('test_doctest.txt', | |
1967 | ... 'test_doctest2.txt', | |
1968 | ... optionflags=doctest.DONT_ACCEPT_BLANKLINE, | |
1969 | ... globs={'favorite_color': 'blue'}) | |
1970 | >>> suite.run(unittest.TestResult()) | |
1971 | <unittest.TestResult run=2 errors=0 failures=2> | |
1972 | ||
1973 | And, you can provide setUp and tearDown functions: | |
1974 | ||
1975 | You can supply setUp and teatDoen functions: | |
1976 | ||
1977 | >>> def setUp(t): | |
1978 | ... import test.test_doctest | |
1979 | ... test.test_doctest.sillySetup = True | |
1980 | ||
1981 | >>> def tearDown(t): | |
1982 | ... import test.test_doctest | |
1983 | ... del test.test_doctest.sillySetup | |
1984 | ||
1985 | Here, we installed a silly variable that the test expects: | |
1986 | ||
1987 | >>> suite = doctest.DocFileSuite('test_doctest.txt', | |
1988 | ... 'test_doctest2.txt', | |
1989 | ... setUp=setUp, tearDown=tearDown) | |
1990 | >>> suite.run(unittest.TestResult()) | |
1991 | <unittest.TestResult run=2 errors=0 failures=1> | |
1992 | ||
1993 | But the tearDown restores sanity: | |
1994 | ||
1995 | >>> import test.test_doctest | |
1996 | >>> test.test_doctest.sillySetup | |
1997 | Traceback (most recent call last): | |
1998 | ... | |
1999 | AttributeError: 'module' object has no attribute 'sillySetup' | |
2000 | ||
2001 | The setUp and tearDown funtions are passed test objects. | |
2002 | Here, we'll use a setUp function to set the favorite color in | |
2003 | test_doctest.txt: | |
2004 | ||
2005 | >>> def setUp(test): | |
2006 | ... test.globs['favorite_color'] = 'blue' | |
2007 | ||
2008 | >>> suite = doctest.DocFileSuite('test_doctest.txt', setUp=setUp) | |
2009 | >>> suite.run(unittest.TestResult()) | |
2010 | <unittest.TestResult run=1 errors=0 failures=0> | |
2011 | ||
2012 | Here, we didn't need to use a tearDown function because we | |
2013 | modified the test globals. The test globals are | |
2014 | automatically cleared for us after a test. | |
2015 | ||
2016 | """ | |
2017 | ||
2018 | def test_trailing_space_in_test(): | |
2019 | """ | |
2020 | Trailing spaces in expected output are significant: | |
2021 | ||
2022 | >>> x, y = 'foo', '' | |
2023 | >>> print x, y | |
2024 | foo \n | |
2025 | """ | |
2026 | ||
2027 | ||
2028 | def test_unittest_reportflags(): | |
2029 | """Default unittest reporting flags can be set to control reporting | |
2030 | ||
2031 | Here, we'll set the REPORT_ONLY_FIRST_FAILURE option so we see | |
2032 | only the first failure of each test. First, we'll look at the | |
2033 | output without the flag. The file test_doctest.txt file has two | |
2034 | tests. They both fail if blank lines are disabled: | |
2035 | ||
2036 | >>> suite = doctest.DocFileSuite('test_doctest.txt', | |
2037 | ... optionflags=doctest.DONT_ACCEPT_BLANKLINE) | |
2038 | >>> import unittest | |
2039 | >>> result = suite.run(unittest.TestResult()) | |
2040 | >>> print result.failures[0][1] # doctest: +ELLIPSIS | |
2041 | Traceback ... | |
2042 | Failed example: | |
2043 | favorite_color | |
2044 | ... | |
2045 | Failed example: | |
2046 | if 1: | |
2047 | ... | |
2048 | ||
2049 | Note that we see both failures displayed. | |
2050 | ||
2051 | >>> old = doctest.set_unittest_reportflags( | |
2052 | ... doctest.REPORT_ONLY_FIRST_FAILURE) | |
2053 | ||
2054 | Now, when we run the test: | |
2055 | ||
2056 | >>> result = suite.run(unittest.TestResult()) | |
2057 | >>> print result.failures[0][1] # doctest: +ELLIPSIS | |
2058 | Traceback ... | |
2059 | Failed example: | |
2060 | favorite_color | |
2061 | Exception raised: | |
2062 | ... | |
2063 | NameError: name 'favorite_color' is not defined | |
2064 | <BLANKLINE> | |
2065 | <BLANKLINE> | |
2066 | ||
2067 | We get only the first failure. | |
2068 | ||
2069 | If we give any reporting options when we set up the tests, | |
2070 | however: | |
2071 | ||
2072 | >>> suite = doctest.DocFileSuite('test_doctest.txt', | |
2073 | ... optionflags=doctest.DONT_ACCEPT_BLANKLINE | doctest.REPORT_NDIFF) | |
2074 | ||
2075 | Then the default eporting options are ignored: | |
2076 | ||
2077 | >>> result = suite.run(unittest.TestResult()) | |
2078 | >>> print result.failures[0][1] # doctest: +ELLIPSIS | |
2079 | Traceback ... | |
2080 | Failed example: | |
2081 | favorite_color | |
2082 | ... | |
2083 | Failed example: | |
2084 | if 1: | |
2085 | print 'a' | |
2086 | ||
2087 | print 'b' | |
2088 | Differences (ndiff with -expected +actual): | |
2089 | a | |
2090 | - <BLANKLINE> | |
2091 | + | |
2092 | b | |
2093 | <BLANKLINE> | |
2094 | <BLANKLINE> | |
2095 | ||
2096 | ||
2097 | Test runners can restore the formatting flags after they run: | |
2098 | ||
2099 | >>> ignored = doctest.set_unittest_reportflags(old) | |
2100 | ||
2101 | """ | |
2102 | ||
2103 | def test_testfile(): r""" | |
2104 | Tests for the `testfile()` function. This function runs all the | |
2105 | doctest examples in a given file. In its simple invokation, it is | |
2106 | called with the name of a file, which is taken to be relative to the | |
2107 | calling module. The return value is (#failures, #tests). | |
2108 | ||
2109 | >>> doctest.testfile('test_doctest.txt') # doctest: +ELLIPSIS | |
2110 | ********************************************************************** | |
2111 | File "...", line 6, in test_doctest.txt | |
2112 | Failed example: | |
2113 | favorite_color | |
2114 | Exception raised: | |
2115 | ... | |
2116 | NameError: name 'favorite_color' is not defined | |
2117 | ********************************************************************** | |
2118 | 1 items had failures: | |
2119 | 1 of 2 in test_doctest.txt | |
2120 | ***Test Failed*** 1 failures. | |
2121 | (1, 2) | |
2122 | >>> doctest.master = None # Reset master. | |
2123 | ||
2124 | (Note: we'll be clearing doctest.master after each call to | |
2125 | `doctest.testfile`, to supress warnings about multiple tests with the | |
2126 | same name.) | |
2127 | ||
2128 | Globals may be specified with the `globs` and `extraglobs` parameters: | |
2129 | ||
2130 | >>> globs = {'favorite_color': 'blue'} | |
2131 | >>> doctest.testfile('test_doctest.txt', globs=globs) | |
2132 | (0, 2) | |
2133 | >>> doctest.master = None # Reset master. | |
2134 | ||
2135 | >>> extraglobs = {'favorite_color': 'red'} | |
2136 | >>> doctest.testfile('test_doctest.txt', globs=globs, | |
2137 | ... extraglobs=extraglobs) # doctest: +ELLIPSIS | |
2138 | ********************************************************************** | |
2139 | File "...", line 6, in test_doctest.txt | |
2140 | Failed example: | |
2141 | favorite_color | |
2142 | Expected: | |
2143 | 'blue' | |
2144 | Got: | |
2145 | 'red' | |
2146 | ********************************************************************** | |
2147 | 1 items had failures: | |
2148 | 1 of 2 in test_doctest.txt | |
2149 | ***Test Failed*** 1 failures. | |
2150 | (1, 2) | |
2151 | >>> doctest.master = None # Reset master. | |
2152 | ||
2153 | The file may be made relative to a given module or package, using the | |
2154 | optional `module_relative` parameter: | |
2155 | ||
2156 | >>> doctest.testfile('test_doctest.txt', globs=globs, | |
2157 | ... module_relative='test') | |
2158 | (0, 2) | |
2159 | >>> doctest.master = None # Reset master. | |
2160 | ||
2161 | Verbosity can be increased with the optional `verbose` paremter: | |
2162 | ||
2163 | >>> doctest.testfile('test_doctest.txt', globs=globs, verbose=True) | |
2164 | Trying: | |
2165 | favorite_color | |
2166 | Expecting: | |
2167 | 'blue' | |
2168 | ok | |
2169 | Trying: | |
2170 | if 1: | |
2171 | print 'a' | |
2172 | ||
2173 | print 'b' | |
2174 | Expecting: | |
2175 | a | |
2176 | <BLANKLINE> | |
2177 | b | |
2178 | ok | |
2179 | 1 items passed all tests: | |
2180 | 2 tests in test_doctest.txt | |
2181 | 2 tests in 1 items. | |
2182 | 2 passed and 0 failed. | |
2183 | Test passed. | |
2184 | (0, 2) | |
2185 | >>> doctest.master = None # Reset master. | |
2186 | ||
2187 | The name of the test may be specified with the optional `name` | |
2188 | parameter: | |
2189 | ||
2190 | >>> doctest.testfile('test_doctest.txt', name='newname') | |
2191 | ... # doctest: +ELLIPSIS | |
2192 | ********************************************************************** | |
2193 | File "...", line 6, in newname | |
2194 | ... | |
2195 | (1, 2) | |
2196 | >>> doctest.master = None # Reset master. | |
2197 | ||
2198 | The summary report may be supressed with the optional `report` | |
2199 | parameter: | |
2200 | ||
2201 | >>> doctest.testfile('test_doctest.txt', report=False) | |
2202 | ... # doctest: +ELLIPSIS | |
2203 | ********************************************************************** | |
2204 | File "...", line 6, in test_doctest.txt | |
2205 | Failed example: | |
2206 | favorite_color | |
2207 | Exception raised: | |
2208 | ... | |
2209 | NameError: name 'favorite_color' is not defined | |
2210 | (1, 2) | |
2211 | >>> doctest.master = None # Reset master. | |
2212 | ||
2213 | The optional keyword argument `raise_on_error` can be used to raise an | |
2214 | exception on the first error (which may be useful for postmortem | |
2215 | debugging): | |
2216 | ||
2217 | >>> doctest.testfile('test_doctest.txt', raise_on_error=True) | |
2218 | ... # doctest: +ELLIPSIS | |
2219 | Traceback (most recent call last): | |
2220 | UnexpectedException: ... | |
2221 | >>> doctest.master = None # Reset master. | |
2222 | """ | |
2223 | ||
2224 | # old_test1, ... used to live in doctest.py, but cluttered it. Note | |
2225 | # that these use the deprecated doctest.Tester, so should go away (or | |
2226 | # be rewritten) someday. | |
2227 | ||
2228 | # Ignore all warnings about the use of class Tester in this module. | |
2229 | # Note that the name of this module may differ depending on how it's | |
2230 | # imported, so the use of __name__ is important. | |
2231 | warnings.filterwarnings("ignore", "class Tester", DeprecationWarning, | |
2232 | __name__, 0) | |
2233 | ||
2234 | def old_test1(): r""" | |
2235 | >>> from doctest import Tester | |
2236 | >>> t = Tester(globs={'x': 42}, verbose=0) | |
2237 | >>> t.runstring(r''' | |
2238 | ... >>> x = x * 2 | |
2239 | ... >>> print x | |
2240 | ... 42 | |
2241 | ... ''', 'XYZ') | |
2242 | ********************************************************************** | |
2243 | Line 3, in XYZ | |
2244 | Failed example: | |
2245 | print x | |
2246 | Expected: | |
2247 | 42 | |
2248 | Got: | |
2249 | 84 | |
2250 | (1, 2) | |
2251 | >>> t.runstring(">>> x = x * 2\n>>> print x\n84\n", 'example2') | |
2252 | (0, 2) | |
2253 | >>> t.summarize() | |
2254 | ********************************************************************** | |
2255 | 1 items had failures: | |
2256 | 1 of 2 in XYZ | |
2257 | ***Test Failed*** 1 failures. | |
2258 | (1, 4) | |
2259 | >>> t.summarize(verbose=1) | |
2260 | 1 items passed all tests: | |
2261 | 2 tests in example2 | |
2262 | ********************************************************************** | |
2263 | 1 items had failures: | |
2264 | 1 of 2 in XYZ | |
2265 | 4 tests in 2 items. | |
2266 | 3 passed and 1 failed. | |
2267 | ***Test Failed*** 1 failures. | |
2268 | (1, 4) | |
2269 | """ | |
2270 | ||
2271 | def old_test2(): r""" | |
2272 | >>> from doctest import Tester | |
2273 | >>> t = Tester(globs={}, verbose=1) | |
2274 | >>> test = r''' | |
2275 | ... # just an example | |
2276 | ... >>> x = 1 + 2 | |
2277 | ... >>> x | |
2278 | ... 3 | |
2279 | ... ''' | |
2280 | >>> t.runstring(test, "Example") | |
2281 | Running string Example | |
2282 | Trying: | |
2283 | x = 1 + 2 | |
2284 | Expecting nothing | |
2285 | ok | |
2286 | Trying: | |
2287 | x | |
2288 | Expecting: | |
2289 | 3 | |
2290 | ok | |
2291 | 0 of 2 examples failed in string Example | |
2292 | (0, 2) | |
2293 | """ | |
2294 | ||
2295 | def old_test3(): r""" | |
2296 | >>> from doctest import Tester | |
2297 | >>> t = Tester(globs={}, verbose=0) | |
2298 | >>> def _f(): | |
2299 | ... '''Trivial docstring example. | |
2300 | ... >>> assert 2 == 2 | |
2301 | ... ''' | |
2302 | ... return 32 | |
2303 | ... | |
2304 | >>> t.rundoc(_f) # expect 0 failures in 1 example | |
2305 | (0, 1) | |
2306 | """ | |
2307 | ||
2308 | def old_test4(): """ | |
2309 | >>> import new | |
2310 | >>> m1 = new.module('_m1') | |
2311 | >>> m2 = new.module('_m2') | |
2312 | >>> test_data = \""" | |
2313 | ... def _f(): | |
2314 | ... '''>>> assert 1 == 1 | |
2315 | ... ''' | |
2316 | ... def g(): | |
2317 | ... '''>>> assert 2 != 1 | |
2318 | ... ''' | |
2319 | ... class H: | |
2320 | ... '''>>> assert 2 > 1 | |
2321 | ... ''' | |
2322 | ... def bar(self): | |
2323 | ... '''>>> assert 1 < 2 | |
2324 | ... ''' | |
2325 | ... \""" | |
2326 | >>> exec test_data in m1.__dict__ | |
2327 | >>> exec test_data in m2.__dict__ | |
2328 | >>> m1.__dict__.update({"f2": m2._f, "g2": m2.g, "h2": m2.H}) | |
2329 | ||
2330 | Tests that objects outside m1 are excluded: | |
2331 | ||
2332 | >>> from doctest import Tester | |
2333 | >>> t = Tester(globs={}, verbose=0) | |
2334 | >>> t.rundict(m1.__dict__, "rundict_test", m1) # f2 and g2 and h2 skipped | |
2335 | (0, 4) | |
2336 | ||
2337 | Once more, not excluding stuff outside m1: | |
2338 | ||
2339 | >>> t = Tester(globs={}, verbose=0) | |
2340 | >>> t.rundict(m1.__dict__, "rundict_test_pvt") # None are skipped. | |
2341 | (0, 8) | |
2342 | ||
2343 | The exclusion of objects from outside the designated module is | |
2344 | meant to be invoked automagically by testmod. | |
2345 | ||
2346 | >>> doctest.testmod(m1, verbose=False) | |
2347 | (0, 4) | |
2348 | """ | |
2349 | ||
2350 | ###################################################################### | |
2351 | ## Main | |
2352 | ###################################################################### | |
2353 | ||
2354 | def test_main(): | |
2355 | # Check the doctest cases in doctest itself: | |
2356 | test_support.run_doctest(doctest, verbosity=True) | |
2357 | # Check the doctest cases defined here: | |
2358 | from test import test_doctest | |
2359 | test_support.run_doctest(test_doctest, verbosity=True) | |
2360 | ||
2361 | import trace, sys, re, StringIO | |
2362 | def test_coverage(coverdir): | |
2363 | tracer = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix,], | |
2364 | trace=0, count=1) | |
2365 | tracer.run('reload(doctest); test_main()') | |
2366 | r = tracer.results() | |
2367 | print 'Writing coverage results...' | |
2368 | r.write_results(show_missing=True, summary=True, | |
2369 | coverdir=coverdir) | |
2370 | ||
2371 | if __name__ == '__main__': | |
2372 | if '-c' in sys.argv: | |
2373 | test_coverage('/tmp/doctest.cover') | |
2374 | else: | |
2375 | test_main() |