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

D.C*_*kel 6 python pytest

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

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

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

现在,我想测试这个函数的几个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
Run Code Online (Sandbox Code Playgroud)

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

我想知道是否可以写出以下形式的内容:

@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
Run Code Online (Sandbox Code Playgroud)

这样其他参数的测试就会通过。我在网上找不到任何关于此事的信息。

AKX*_*AKX 11

怎么样这个 \xe2\x80\x93 你可以检查它的类型expected,如果它闻起来像异常类,请改用pytest.raises()

\n\n
import pytest\n\n\ndef divide_hundred_by(x):\n    if x == 0:\n        raise ZeroDivisionError("You cannot divide by zero")\n    return 100 / x\n\n\n@pytest.mark.parametrize(\n    "value, expected",\n    [\n        (10, 10),\n        (-2, -50),\n        (0.5, 200),\n        (0, ZeroDivisionError),\n    ],\n)\ndef test_divide_hundred_by(value, expected):\n    if type(expected) == type and issubclass(expected, Exception):\n        with pytest.raises(expected):\n            divide_hundred_by(value)\n    else:\n        assert divide_hundred_by(value) == expected\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果你有更多这样的事情,你可以将其重构if/with/else为辅助函数:

\n\n
import pytest\n\n\ndef divide_hundred_by(x):\n    if x == 0:\n        raise ZeroDivisionError("You cannot divide by zero")\n    return 100 / x\n\n\ndef check(fn, expected, args=(), kwargs={}):\n    if type(expected) == type and issubclass(expected, Exception):\n        with pytest.raises(expected):\n            fn(*args, **kwargs)\n    else:\n        assert fn(*args, **kwargs) == expected\n\n\n@pytest.mark.parametrize(\n    "value, expected",\n    [(10, 10), (-2, -50), (0.5, 200), (0, ZeroDivisionError)],\n)\ndef test_divide_hundred_by(value, expected):\n    check(divide_hundred_by, expected, (value,))\n
Run Code Online (Sandbox Code Playgroud)\n