温馨提示:本文翻译自stackoverflow.com,查看原文请点击:python - Py.test: How to parametrize when some values should return an error
pytest python

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

发布于 2020-03-27 10:23:39

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

假设我有一个简单的函数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

这样其他参数将通过测试。我在网上找不到任何东西。

查看更多

查看更多

提问者
D.C.
被浏览
269
AKX 2019-07-03 21:19

怎么样?您可以检查的类型,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,))