Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly assert that an exception gets raised in pytest?

Code:

# coding=utf-8 import pytest   def whatever():     return 9/0  def test_whatever():     try:         whatever()     except ZeroDivisionError as exc:         pytest.fail(exc, pytrace=True) 

Output:

================================ 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 make pytest print traceback, so I would see where in the whatever function an exception was raised?

like image 266
Gill Bates Avatar asked Apr 28 '14 09:04

Gill Bates


People also ask

How do I check if an exception is raised in Python?

assertRaises() – It allows an exception to be encapsulated, meaning that the test can throw an exception without exiting the execution, as is normally the case for unhandled exceptions. The test passes if exception is raised, gives an error if another exception is raised, or fails if no exception is raised.

How do you raise an exception in Python?

As a Python developer you can choose to throw an exception if a condition occurs. To throw (or raise) an exception, use the raise keyword.


2 Answers

pytest.raises(Exception) is what you need.

Code

import pytest  def test_passes():     with pytest.raises(Exception) as e_info:         x = 1 / 0  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 

Output

============================================================================================= 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 ====================================================================================== 

Note that e_info saves the exception object so you can extract details from it. For example, if you want to check the exception call stack or another nested exception inside.

like image 58
Murilo Giacometti Avatar answered Sep 22 '22 12:09

Murilo Giacometti


Do you mean something like this:

def test_raises():     with pytest.raises(Exception) as exc_info:            raise Exception('some info')     # these asserts are identical; you can use either one        assert exc_info.value.args[0] == 'some info'     assert str(exc_info.value) == 'some info' 
like image 29
simpleranchero Avatar answered Sep 20 '22 12:09

simpleranchero