New issue 475: Misleading pytest exception description
https://bitbucket.org/hpk42/pytest/issue/475/misleading-pytest-exception-description
Jurko Gospodnetić:
Today, while mentoring a new colleague in Python and TDD, she ran into a pytest
exception description which confused her, and with her being a novice
programmer, was completely out of her league to debug.
Here is a reduced script demonstrating the issue:
```
InvalidLabSize = -1
class Lab:
def __init__(self, size):
if size <= 0:
raise Exception(InvalidLabSize)
import pytest
def test_invalid_lab_size():
with pytest.raises(InvalidLabSize):
Lab(0)
```
The given test code has a bug - ```pytest.raises()``` should be given
```Exception``` class as its parameter and not an integer ```InvalidLabSize```.
However, pytest
reports this in a most misleading way:
```
#!text
D:\Workplace>py3 -m pytest aaa.py
============================= test session starts =============================
platform win32 -- Python 3.3.3 -- py-1.4.20 -- pytest-2.5.2
collected 1 items
aaa.py F
================================== FAILURES ===================================
____________________________ test_invalid_lab_size ____________________________
def test_invalid_lab_size():
with pytest.raises(InvalidLabSize):
> Lab(0)
E TypeError: issubclass() arg 2 must be a class or tuple of classes
aaa.py:15: TypeError
========================== 1 failed in 0.05 seconds ===========================
```
First, it points to an incorrect code line - it points to the code line
```Lab(0)``` as causing the error when in fact it was the line before that
caused it.
Second, it complains about some 'argument number 2' to some ```issubclass()```
call having to be a class or a tuple of classes, when neither the user code nor
anything displayed in the given exception stack information contains any
```issubclass()``` calls.
It should in fact say that the first parameter to ```pyteset.raises()``` should
be a class or a tuple of classes.
----
As a side-note, I tried rewriting the test using the older pytest.raises()
calling style (without using a ```with``` context manager):
```
#!python
InvalidLabSize = -1
class Lab:
def __init__(self, size):
if size <= 0:
raise Exception(InvalidLabSize)
import pytest
def test_invalid_lab_size():
pytest.raises(InvalidLabSize, Lab, 0)
```
and this reports much more relevant information when run under Python 3.x:
```
D:\Workplace>py3 -m pytest aaa.py
============================= test session starts =============================
platform win32 -- Python 3.3.3 -- py-1.4.20 -- pytest-2.5.2
collected 1 items
aaa.py F
================================== FAILURES ===================================
____________________________ test_invalid_lab_size ____________________________
def test_invalid_lab_size():
> pytest.raises(InvalidLabSize, Lab, 0)
E TypeError: catching classes that do not inherit from BaseException is
not allowed
aaa.py:31: TypeError
========================== 1 failed in 0.04 seconds ===========================
```
Running it under Python 2.x on the other hand displays a bit less but still
misleading information:
```
D:\Workplace>py2 -m pytest aaa.py
============================= test session starts =============================
platform win32 -- Python 2.7.6 -- py-1.4.20 -- pytest-2.5.2
collected 1 items
aaa.py F
================================== FAILURES ===================================
____________________________ test_invalid_lab_size ____________________________
def test_invalid_lab_size():
> pytest.raises(InvalidLabSize, Lab, 0)
aaa.py:31:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <aaa.Lab instance at 0x0000000003043B88>, size = 0
def __init__(self, size):
if size <= 0:
> raise Exception(InvalidLabSize)
E Exception: -1
aaa.py:24: Exception
========================== 1 failed in 0.12 seconds ===========================
```
It says that an Exception got raised when it should in fact say that an
Exception got raised but an integer -1 was expected.
Hope this helps.
Best regards,
Jurko Gospodnetić
_______________________________________________
pytest-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pytest-commit