Py.test:如何参数化某些值应返回错误时

时间:2019-07-03 12:58:26

标签: python pytest

我是测试领域的新手,我想知道是否可以对应该返回值的参数进行参数化,而对可以将错误返回单个测试的参数进行参数化。

假设我有一个简单的函数divide_hundred_by(x),定义如下:

def divide_hundred_by(x):
    if x == 0: 
         raise ZeroDivisionError('You cannot divide by zero') 
    return 100/x

现在,我想针对 x 的几个值对该函数进行测试,并对该测试进行参数化。我发现我可以使用:

import pytest

@pytest.mark.parametrize('value, expected',
                         [
                             (10, 10),
                             (-2, -50),
                             (0.5, 200)
                         ]
                         )
def test_divide_hundred_by(value, expected):

    with pytest.raises(ZeroDivisionError): 
        divide_hundred_by(0)

    assert divide_hundred_by(value) == expected

但是,这可以确保如果警告部分失败,则所有值的整个测试都会失败,这不是我想要的。

我想知道是否可以编写以下形式的东西:

@pytest.mark.parametrize('value, expected',
                         [
                             (10, 10),
                             (-2, -50),
                             (0.5, 200),
                             (0, "ZeroDivisionError") 
                         ]
                         )
def test_divide_hundred_by(value, expected):
    assert divide_hundred_by(value) == expected

,以便其他参数通过测试。我在网上找不到任何东西。

1 个答案:

答案 0 :(得分:1)

如何处理–您可以检查expected的类型,如果它闻起来像异常类,请改用pytest.raises()

import pytest


def divide_hundred_by(x):
    if x == 0:
        raise ZeroDivisionError("You cannot divide by zero")
    return 100 / x


@pytest.mark.parametrize(
    "value, expected",
    [
        (10, 10),
        (-2, -50),
        (0.5, 200),
        (0, ZeroDivisionError),
    ],
)
def test_divide_hundred_by(value, expected):
    if type(expected) == type and issubclass(expected, Exception):
        with pytest.raises(expected):
            divide_hundred_by(value)
    else:
        assert divide_hundred_by(value) == expected

如果您有更多这类事情,可以将if/with/else位重构为帮助函数:

import pytest


def divide_hundred_by(x):
    if x == 0:
        raise ZeroDivisionError("You cannot divide by zero")
    return 100 / x


def check(fn, expected, args=(), kwargs={}):
    if type(expected) == type and issubclass(expected, Exception):
        with pytest.raises(expected):
            fn(*args, **kwargs)
    else:
        assert fn(*args, **kwargs) == expected


@pytest.mark.parametrize(
    "value, expected",
    [(10, 10), (-2, -50), (0.5, 200), (0, ZeroDivisionError)],
)
def test_divide_hundred_by(value, expected):
    check(divide_hundred_by, expected, (value,))