Question
Check testing code below:
- # coding=utf-8
- import pytest
- def whatever():
- return 9/0
- def test_whatever():
- try:
- whatever()
- except ZeroDivisionError as exc:
- pytest.fail(exc, pytrace=True)
- ================================ test session starts =================================
- platform linux2 -- Python 2.7.3 -- py-1.4.20 -- pytest-2.5.2
- plugins: django, cov
- collected 1 items
- pytest_test.py F
- ====================================== FAILURES ======================================
- ___________________________________ test_whatever ____________________________________
- def test_whatever():
- try:
- whatever()
- except ZeroDivisionError as exc:
- > pytest.fail(exc, pytrace=True)
- E Failed: integer division or modulo by zero
- pytest_test.py:12: Failed
- ============================== 1 failed in 1.16 seconds ==============================
How-To
There are two ways to handle these kind of cases in pytest by catching expected exception (Assertions about expected exceptions):
Usage of pytest.raises:
- def whatever():
- return 9/0
- def test_whatever():
- with pytest.raises(ZeroDivisionError):
- whatever()
- ============================= test session starts ============================
- platform linux2 -- Python 2.7.10, pytest-3.2.3, py-1.4.34, pluggy-0.4.0 --
- /usr/local/python_2.7_10/bin/python
- cachedir: .cache
- rootdir: /home/ukpdl, inifile:
- collected 1 item
- test_fun.py::test_whatever PASSED
- ======================== 1 passed in 0.01 seconds =============================
Usage of pytest.mark.xfail:
- @pytest.mark.xfail(raises=ZeroDivisionError)
- def test_whatever():
- whatever()
- ============================= test session starts ============================
- platform linux2 -- Python 2.7.10, pytest-3.2.3, py-1.4.34, pluggy-0.4.0 --
- /usr/local/python_2.7_10/bin/python
- cachedir: .cache
- rootdir: /home/ukpdl, inifile:
- collected 1 item
- test_fun.py::test_whatever xfail
- ======================== 1 xfailed in 0.03 seconds=============================
Regarding to print the trackback from pytest, pytest.raises(Exception) as e_info is what you need. Check sample code as below:
- /tmp/test.py
- import pytest
- import logging
- def test_passes():
- with pytest.raises(Exception) as e_info:
- x = 1 / 0
- logging.error('Expected exception: {}'.format(e_info))
- def test_passes_without_info():
- with pytest.raises(Exception):
- x = 1 / 0
- def test_fails():
- with pytest.raises(Exception) as e_info:
- x = 1 / 1
- def test_fails_without_info():
- with pytest.raises(Exception):
- x = 1 / 1
- # Don't do this. Assertions are caught as exceptions.
- def test_passes_but_should_not():
- try:
- x = 1 / 1
- assert False
- except Exception:
- assert True
- # Even if the appropriate exception is caught, it is bad style,
- # because the test result is less informative
- # than it would be with pytest.raises(e)
- # (it just says pass or fail.)
- def test_passes_but_bad_style():
- try:
- x = 1 / 0
- assert False
- except ZeroDivisionError:
- assert True
- def test_fails_but_bad_style():
- try:
- x = 1 / 1
- assert False
- except ZeroDivisionError:
- assert True
- ...
- ../../tmp/test.py ERROR:root:Expected exception: /tmp/test.py:6: ZeroDivisionError: division by zero
- ...
- === test session starts ===
- platform linux2 -- Python 2.7.6 -- py-1.4.26 -- pytest-2.6.4
- collected 7 items
- test.py ..FF..F
- === FAILURES ===
- ___ test_fails ____
- def test_fails():
- with pytest.raises(Exception) as e_info:
- > x = 1 / 1
- E Failed: DID NOT RAISE
- test.py:13: Failed
- ___ test_fails_without_info ____
- def test_fails_without_info():
- with pytest.raises(Exception):
- > x = 1 / 1
- E Failed: DID NOT RAISE
- test.py:17: Failed
- ___ test_fails_but_bad_style ___
- def test_fails_but_bad_style():
- try:
- x = 1 / 1
- > assert False
- E assert False
- test.py:43: AssertionError
- === 3 failed, 4 passed in 0.02 seconds ===
沒有留言:
張貼留言