1
1
""" Python test discovery, setup and run of test functions. """
2
2
3
+ import re
3
4
import fnmatch
4
5
import inspect
5
6
import sys
@@ -1134,7 +1135,7 @@ def raises(expected_exception, *args, **kwargs):
1134
1135
>>> with raises(ValueError) as exc_info:
1135
1136
... if value > 10:
1136
1137
... raise ValueError("value must be <= 10")
1137
- ... assert str( exc_info.value) == "value must be <= 10" # this will not execute
1138
+ ... assert exc_info.type == ValueError # this will not execute
1138
1139
1139
1140
Instead, the following approach must be taken (note the difference in
1140
1141
scope)::
@@ -1143,7 +1144,16 @@ def raises(expected_exception, *args, **kwargs):
1143
1144
... if value > 10:
1144
1145
... raise ValueError("value must be <= 10")
1145
1146
...
1146
- >>> assert str(exc_info.value) == "value must be <= 10"
1147
+ >>> assert exc_info.type == ValueError
1148
+
1149
+ Or you can use the keyword argument ``match`` to assert that the
1150
+ exception matches a text or regex::
1151
+
1152
+ >>> with raises(ValueError, match='must be 0 or None'):
1153
+ ... raise ValueError("value must be 0 or None")
1154
+
1155
+ >>> with raises(ValueError, match=r'must be \d+$'):
1156
+ ... raise ValueError("value must be 42")
1147
1157
1148
1158
1149
1159
Or you can specify a callable by passing a to-be-called lambda::
@@ -1194,11 +1204,15 @@ def raises(expected_exception, *args, **kwargs):
1194
1204
raise TypeError (msg % type (expected_exception ))
1195
1205
1196
1206
message = "DID NOT RAISE {0}" .format (expected_exception )
1207
+ match_expr = None
1197
1208
1198
1209
if not args :
1199
1210
if "message" in kwargs :
1200
1211
message = kwargs .pop ("message" )
1201
- return RaisesContext (expected_exception , message )
1212
+ if "match" in kwargs :
1213
+ match_expr = kwargs .pop ("match" )
1214
+ message += " matching '{0}'" .format (match_expr )
1215
+ return RaisesContext (expected_exception , message , match_expr )
1202
1216
elif isinstance (args [0 ], str ):
1203
1217
code , = args
1204
1218
assert isinstance (code , str )
@@ -1222,9 +1236,10 @@ def raises(expected_exception, *args, **kwargs):
1222
1236
pytest .fail (message )
1223
1237
1224
1238
class RaisesContext (object ):
1225
- def __init__ (self , expected_exception , message ):
1239
+ def __init__ (self , expected_exception , message , match_expr ):
1226
1240
self .expected_exception = expected_exception
1227
1241
self .message = message
1242
+ self .match_expr = match_expr
1228
1243
self .excinfo = None
1229
1244
1230
1245
def __enter__ (self ):
@@ -1243,6 +1258,8 @@ def __exit__(self, *tp):
1243
1258
exc_type , value , traceback = tp
1244
1259
tp = exc_type , exc_type (value ), traceback
1245
1260
self .excinfo .__init__ (tp )
1261
+ if self .match_expr and not re .search (self .match_expr , str (self .excinfo )):
1262
+ pytest .fail (self .message )
1246
1263
suppress_exception = issubclass (self .excinfo .type , self .expected_exception )
1247
1264
if sys .version_info [0 ] == 2 and suppress_exception :
1248
1265
sys .exc_clear ()
0 commit comments