Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unexpected result: pytest.raises with match parameter when asserting error

Sanity check please!

I'm trying to understand an unexpected test failure when including the exact message returned from an incorrect function call to the match parameter of pytest.raises().

The docs state:

match – if specified, asserts that the exception matches a text or regex

The sequence of instructions in the repl below pretty much says it all, but for some reason the last test fails.

PS C:\Users\peter_000\OneDrive\git\test> pipenv run python
Loading .env environment variables…
Python 3.6.4 (v3.6.4:d48eceb, Dec 19 2017, 06:54:40) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>>
>>>
>>> import pytest
>>> pytest.__version__
'4.4.1'
>>>
>>> with pytest.raises(TypeError, match='a string'):
...     raise TypeError('a string')  # passes
...
>>> def func():
...     pass
...
>>> func(None)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: func() takes 0 positional arguments but 1 was given
>>>
>>>
>>> with pytest.raises(TypeError, match='func() takes 0 positional arguments but 1 was given'):
...     func(None)  # fails
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
TypeError: func() takes 0 positional arguments but 1 was given

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "C:\Users\peter_000\.virtualenvs\test-_0Fb_hDQ\lib\site-packages\_pytest\python_api.py", line 735, in __exit__
    self.excinfo.match(self.match_expr)
  File "C:\Users\peter_000\.virtualenvs\test-_0Fb_hDQ\lib\site-packages\_pytest\_code\code.py", line 575, in match
    assert 0, "Pattern '{!s}' not found in '{!s}'".format(regexp, self.value)
AssertionError: Pattern 'func() takes 0 positional arguments but 1 was given' not found in 'func() takes 0 positional arguments but 1 was given'
>>>

I thought that perhaps the '()' might mean something in regex that would cause the strings not to match but:

>>> with pytest.raises(TypeError, match='func()'):
...     raise TypeError('func()')

... passes.

like image 537
SuperShoot Avatar asked May 04 '19 11:05

SuperShoot


1 Answers

Match takes a regular expression pattern, and some characters like () are special. You need to escape them:

>>> with pytest.raises(TypeError, match=r'func\(\) takes 0 positional arguments but 1 was given'):
... #                                   ^     ^^^^
...     func(None)  # succeeds
>>>

The reason why it was failing before is that () in a regular expression corresponds to an empty group, and so your pattern would have matched the string func takes 0 positional arguments but 1 was given.

The reason why match='func()' passes is that the particular regex is looking for func anywhere in the string: it may be followed or preceded by any text.

like image 56
Andrea Corbellini Avatar answered Oct 29 '22 23:10

Andrea Corbellini