@@ -98,6 +98,27 @@ and if you need to have access to the actual exception info you may use:
98
98
the actual exception raised. The main attributes of interest are
99
99
``.type ``, ``.value `` and ``.traceback ``.
100
100
101
+ Note that ``pytest.raises `` will match the exception type or any subclasses (like the standard ``except `` statement).
102
+ If you want to check if a block of code is raising an exact exception type, you need to check that explicitly:
103
+
104
+
105
+ .. code-block :: python
106
+
107
+ def test_recursion_depth ():
108
+ def foo ():
109
+ raise NotImplementedError
110
+
111
+ with pytest.raises(RuntimeError ) as excinfo:
112
+ foo()
113
+ assert type (excinfo.value) is RuntimeError
114
+
115
+ The :func: `pytest.raises ` call will succeed, even though the function raises :class: `NotImplementedError `, because
116
+ :class: `NotImplementedError ` is a subclass of :class: `RuntimeError `; however the following `assert ` statement will
117
+ catch the problem.
118
+
119
+ Matching exception messages
120
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
121
+
101
122
You can pass a ``match `` keyword parameter to the context-manager to test
102
123
that a regular expression matches on the string representation of an exception
103
124
(similar to the ``TestCase.assertRaisesRegex `` method from ``unittest ``):
@@ -115,9 +136,15 @@ that a regular expression matches on the string representation of an exception
115
136
with pytest.raises(ValueError , match = r " . * 123 . * " ):
116
137
myfunc()
117
138
118
- The regexp parameter of the ``match `` parameter is matched with the ``re.search ``
119
- function, so in the above example ``match='123' `` would have worked as
120
- well.
139
+ Notes:
140
+
141
+ * The ``match `` parameter is matched with the :func: `re.search `
142
+ function, so in the above example ``match='123' `` would have worked as well.
143
+ * The ``match `` parameter also matches against `PEP-678 <https://peps.python.org/pep-0678/ >`__ ``__notes__ ``.
144
+
145
+
146
+ Matching exception groups
147
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
121
148
122
149
You can also use the :func: `excinfo.group_contains() <pytest.ExceptionInfo.group_contains> `
123
150
method to test for exceptions returned as part of an ``ExceptionGroup ``:
@@ -165,32 +192,55 @@ exception at a specific level; exceptions contained directly in the top
165
192
assert not excinfo.group_contains(RuntimeError , depth = 2 )
166
193
assert not excinfo.group_contains(TypeError , depth = 1 )
167
194
168
- There's an alternate form of the :func: `pytest.raises ` function where you pass
169
- a function that will be executed with the given ``*args `` and ``**kwargs `` and
170
- assert that the given exception is raised:
195
+ Alternate form (legacy)
196
+ ~~~~~~~~~~~~~~~~~~~~~~~
197
+
198
+ There is an alternate form where you pass
199
+ a function that will be executed, along ``*args `` and ``**kwargs ``, and :func: `pytest.raises `
200
+ will execute the function with the arguments and assert that the given exception is raised:
171
201
172
202
.. code-block :: python
173
203
174
- pytest.raises(ExpectedException, func, * args, ** kwargs)
204
+ def func (x ):
205
+ if x <= 0 :
206
+ raise ValueError (" x needs to be larger than zero" )
207
+
208
+
209
+ pytest.raises(ValueError , func, x = - 1 )
175
210
176
211
The reporter will provide you with helpful output in case of failures such as *no
177
212
exception * or *wrong exception *.
178
213
179
- Note that it is also possible to specify a "raises" argument to
180
- ``pytest.mark.xfail ``, which checks that the test is failing in a more
214
+ This form was the original :func: `pytest.raises ` API, developed before the ``with `` statement was
215
+ added to the Python language. Nowadays, this form is rarely used, with the context-manager form (using ``with ``)
216
+ being considered more readable.
217
+ Nonetheless, this form is fully supported and not deprecated in any way.
218
+
219
+ xfail mark and pytest.raises
220
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
221
+
222
+ It is also possible to specify a ``raises `` argument to
223
+ :ref: `pytest.mark.xfail <pytest.mark.xfail ref >`, which checks that the test is failing in a more
181
224
specific way than just having any exception raised:
182
225
183
226
.. code-block :: python
184
227
228
+ def f ():
229
+ raise IndexError ()
230
+
231
+
185
232
@pytest.mark.xfail (raises = IndexError )
186
233
def test_f ():
187
234
f()
188
235
189
- Using :func: `pytest.raises ` is likely to be better for cases where you are
190
- testing exceptions your own code is deliberately raising, whereas using
191
- ``@pytest.mark.xfail `` with a check function is probably better for something
192
- like documenting unfixed bugs (where the test describes what "should" happen)
193
- or bugs in dependencies.
236
+
237
+ This will only "xfail" if the test fails by raising ``IndexError `` or subclasses.
238
+
239
+ * Using :ref: `pytest.mark.xfail <pytest.mark.xfail ref >` with the ``raises `` parameter is probably better for something
240
+ like documenting unfixed bugs (where the test describes what "should" happen) or bugs in dependencies.
241
+
242
+ * Using :func: `pytest.raises ` is likely to be better for cases where you are
243
+ testing exceptions your own code is deliberately raising, which is the majority of cases.
194
244
195
245
196
246
.. _`assertwarns` :
0 commit comments