Pytest: Why did not raise with ZeroDivisionError??

Created on 25 Dec 2015  Â·  4Comments  Â·  Source: pytest-dev/pytest

exception.py

def divide_anti_pattern(a, b):
    try:
        result = a / b
    except:
        result = None
    return result


def divide_best_practice(a, b):
    result = None
    try:
        result = a / b
    except ZeroDivisionError:
        print('Type error: division by 0.')
    except TypeError:
        # E.g., if b is a string
        print("Type error: division by '{0}'.".format(b))
    except Exception as e:
        # handle any other exception
        print("Error '{0}' occurred. Arguments {1}.".format(e.args))
    else:
        # Excute if no exception occurred
        print('No errors')
    finally:
        # Excute always
        if result is None:
            result = 0
    return result

test_exception.py

import pytest
from pytest import raises

from tests.anti_patterns.exception import divide_anti_pattern, divide_best_practice


class TestDivideAntiPattern:
    def test_divide_anti_pattern(self):
        assert divide_anti_pattern(5, 5) == 1

    def test_divide_anti_pattern_with_divide_zero(self):
        assert divide_anti_pattern(5, 0) == None


class TestDivideBestPractice:
    def test_divide_best_practice(self):
        assert divide_best_practice(5, 4) == 1.25

    def test_divide_best_practice_with_divide_zero(self):
        with raises(ZeroDivisionError):
            divide_best_practice(15, 0)

    def test_divide_best_practice_with_divide_zero2(self):
        with raises(ZeroDivisionError):
            print(1/0)

(reservation) untitled1 (master) ✗ py.test tests/anti_patterns/test_exception.py
================================================= test session starts =================================================
platform darwin -- Python 3.4.3, pytest-2.8.5, py-1.4.31, pluggy-0.3.1
rootdir: /Users/re4lfl0w/PycharmProjects/untitled1/tests, inifile: pytest.ini
plugins: cov-2.2.0, django-2.9.1, xdist-1.13.1
collected 5 items 

tests/anti_patterns/test_exception.py ...F.

====================================================== FAILURES =======================================================
__________________________ TestDivideBestPractice.test_divide_best_practice_with_divide_zero __________________________

self = <test_exception.TestDivideBestPractice object at 0x1065bada0>

    def test_divide_best_practice_with_divide_zero(self):
        with raises(ZeroDivisionError):
>           divide_best_practice(15, 0)
E           Failed: DID NOT RAISE

tests/anti_patterns/test_exception.py:21: Failed
------------------------------------------------ Captured stdout call -------------------------------------------------
Type error: division by 0.

Most helpful comment

If you catch it, raises no longer Sees it,

All 4 comments

If you catch it, raises no longer Sees it,

If you just call divide_best_practice outside a test, you will see that it won't raise ZeroDivisionError either. That's because, as @RonnyPfannschmidt said, you are catching it and just printing a message, effectively swallowing it to the caller. So pytest is correct here.

If you want the caller to see the exception, you have to re-raise it yourself:

    except ZeroDivisionError:
        print('Type error: division by 0.')
        raise

@RonnyPfannschmidt Thank you.
@nicoddemus Thank you. I realized your example code. I forget 'raise'. ok. understand. Always write 'raise' in except??

If you want to propagate the exception to the caller, then yes. The are situations where you might want to handle the exception locally though.

Was this page helpful?
0 / 5 - 0 ratings