File: plugin_exceptions.rst

package info (click to toggle)
nose 1.3.7-9
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 2,900 kB
  • sloc: python: 15,733; makefile: 99; xml: 42; sh: 2
file content (149 lines) | stat: -rw-r--r-- 5,380 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
When Plugins Fail
-----------------

Plugin methods should not fail silently. When a plugin method raises
an exception before or during the execution of a test, the exception
will be wrapped in a :class:`nose.failure.Failure` instance and appear as a
failing test. Exceptions raised at other times, such as in the
preparation phase with ``prepareTestLoader`` or ``prepareTestResult``,
or after a test executes, in ``afterTest`` will stop the entire test
run.

    >>> import os
    >>> import sys
    >>> from nose.plugins import Plugin
    >>> from nose.plugins.plugintest import run_buffered as run

Our first test plugins take no command-line arguments and raises
AttributeError in beforeTest and afterTest. 

    >>> class EnabledPlugin(Plugin):
    ...     """Plugin that takes no command-line arguments"""
    ...
    ...     enabled = True
    ...
    ...     def configure(self, options, conf):
    ...         pass
    ...     def options(self, parser, env={}):
    ...         pass    
    >>> class FailBeforePlugin(EnabledPlugin):
    ...     name = "fail-before"
    ...	    
    ...     def beforeTest(self, test):
    ...         raise AttributeError()    
    >>> class FailAfterPlugin(EnabledPlugin):
    ...     name = "fail-after"
    ...	    
    ...     def afterTest(self, test):
    ...         raise AttributeError()

Running tests with the fail-before plugin enabled will result in all
tests failing.

    >>> support = os.path.join(os.path.dirname(__file__), 'support')
    >>> suitepath = os.path.join(support, 'test_spam.py')
    >>> run(argv=['nosetests', suitepath],
    ...     plugins=[FailBeforePlugin()])
    EE
    ======================================================================
    ERROR: test_spam.test_spam
    ----------------------------------------------------------------------
    Traceback (most recent call last):
    ...
    AttributeError
    <BLANKLINE>
    ======================================================================
    ERROR: test_spam.test_eggs
    ----------------------------------------------------------------------
    Traceback (most recent call last):
    ...
    AttributeError
    <BLANKLINE>
    ----------------------------------------------------------------------
    Ran 0 tests in ...s
    <BLANKLINE>
    FAILED (errors=2)

But with the fail-after plugin, the entire test run will fail.

    >>> run(argv=['nosetests', suitepath],
    ...     plugins=[FailAfterPlugin()])
    Traceback (most recent call last):
    ...
    AttributeError

Likewise, since the next plugin fails in a preparatory method, outside
of test execution, the entire test run fails when the plugin is used.

    >>> class FailPreparationPlugin(EnabledPlugin):
    ...     name = "fail-prepare"
    ...     
    ...     def prepareTestLoader(self, loader):
    ...         raise TypeError("That loader is not my type")
    >>> run(argv=['nosetests', suitepath],
    ...     plugins=[FailPreparationPlugin()])
    Traceback (most recent call last):
    ...
    TypeError: That loader is not my type


Even AttributeErrors and TypeErrors are not silently suppressed as
they used to be for some generative plugin methods (issue152).

These methods caught TypeError and AttributeError and did not record
the exception, before issue152 was fixed: .loadTestsFromDir(),
.loadTestsFromModule(), .loadTestsFromTestCase(),
loadTestsFromTestClass, and .makeTest().  Now, the exception is
caught, but logged as a Failure.

    >>> class FailLoadPlugin(EnabledPlugin):
    ...     name = "fail-load"
    ...     
    ...     def loadTestsFromModule(self, module):
    ...         # we're testing exception handling behaviour during
    ...         # iteration, so be a generator function, without
    ...         # actually yielding any tests
    ...         if False:
    ...             yield None
    ...         raise TypeError("bug in plugin")
    >>> run(argv=['nosetests', suitepath],
    ...     plugins=[FailLoadPlugin()])
    ..E
    ======================================================================
    ERROR: Failure: TypeError (bug in plugin)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
    ...
    TypeError: bug in plugin
    <BLANKLINE>
    ----------------------------------------------------------------------
    Ran 3 tests in ...s
    <BLANKLINE>
    FAILED (errors=1)


Also, before issue152 was resolved, .loadTestsFromFile() and
.loadTestsFromName() didn't catch these errors at all, so the
following test would crash nose:

    >>> class FailLoadFromNamePlugin(EnabledPlugin):
    ...     name = "fail-load-from-name"
    ...     
    ...     def loadTestsFromName(self, name, module=None, importPath=None):
    ...         if False:
    ...             yield None
    ...         raise TypeError("bug in plugin")
    >>> run(argv=['nosetests', suitepath],
    ...     plugins=[FailLoadFromNamePlugin()])
    E
    ======================================================================
    ERROR: Failure: TypeError (bug in plugin)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
    ...
    TypeError: bug in plugin
    <BLANKLINE>
    ----------------------------------------------------------------------
    Ran 1 test in ...s
    <BLANKLINE>
    FAILED (errors=1)