python - pytest.mark.parametrize 似乎只能失败预期的异常

标签 python exception pytest

当参数化引发预期异常的测试时,我一直使用以下形式:

import pytest

class SomeException(Exception):
    pass

class AnotherException(Exception):
    pass

@pytest.mark.parametrize(
    'error',
    [None,
     pytest.mark.raises(SomeException('the message'),
                        exception=SomeException),
     pytest.mark.raises(AnotherException('the message'),
                        exception=AnotherException),
     pytest.mark.raises(Exception('the message'),
                        exception=Exception),
     ])
def test_mark_raises(error):
    if error:
        raise error

请注意,我已经安装了 pytest-raises 包。好的,这可行,但我最近注意到它引发了弃用警告:

RemovedInPytest4Warning: Applying marks directly to parameters is deprecated, please use pytest.param(..., marks=...) instead.

好的,没问题。我们将更新参数列表。但这一直是有问题的。 pytest.param 有一个 'marks=' 参数,但传入 pytest.mark.raises 不起作用。我发现在 pytest.param 中使用异常处理的唯一方法(实际上似乎完全有效)如下:

import pytest

class SomeException(Exception):
    pass

class AnotherException(Exception):
    pass

@pytest.mark.parametrize(
    'error',
    [None,
     pytest.param(SomeException('the message'),
                  marks=pytest.mark.xfail(exception=SomeException)),
     pytest.param(AnotherException('the message'),
                  marks=pytest.mark.xfail(exception=AnotherException)),
     pytest.param(Exception('the message'),
                  marks=pytest.mark.xfail(exception=Exception)),
     ])
def test_mark_raises(error):
    if error:
        raise error

好吧,这似乎确实有效。但它并没有通过测试,而是让测试失败了。

我不喜欢这样。如果我期望测试能够提高 特定的异常,它实际上引发了异常, 那么我会认为测试已经通过,而不是“xfailed”。

如果我正在检查一堆 pytest 结果(在某些情况下超过 1500 个), 识别哪些测试失败在视觉上需要更多工作 因为他们预计会出现某种故障情况,以及哪些故障情况 失败是因为它们还没有实现(或者其他一些原因) 这表明我们需要修复某些问题)。

我不喜欢收到一堆警告,但我也希望测试能够正确显示它们已通过。有谁知道在出现预期异常行为的情况下与 pytest.param 一起使用的正确构造吗?

最佳答案

如果要禁用输出中的警告,可以使用 --disable-warnings 标志。

当您不希望测试失败时,您正在使用 xfail 引发异常。您应该使用 pytest.raises 来引发异常 - link 。如果您想使用标记来引发异常,则应该使用自定义标记并编写自己的测试收集器。 conftest.py 示例:

import pytest

def pytest_runtest_setup(item):
    envmarker = item.get_marker("passwithex")
    if envmarker is not None:
        pytest.raises(ErrorName)

测试代码:

import pytest

class SomeException(Exception):
    pass

class AnotherException(Exception):
    pass

@pytest.mark.parametrize(
    'error',
    [None,
     pytest.param(SomeException('the message'),
                  marks=pytest.mark.passwithex),
     pytest.param(AnotherException('the message'),
                  marks=pytest.mark.xfail(exception=AnotherException)),
     pytest.param(Exception('the message'),
                  marks=pytest.mark.xfail(exception=Exception)),
     ])
def test_mark_raises(error):
    if error:
        raise error

关于python - pytest.mark.parametrize 似乎只能失败预期的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52807722/

相关文章:

.net - 如何将 JObject 反序列化为 .NET 对象

python - 如何在异步单元测试中模拟方法?

python - 从数据框列列表创建术语频率字典

python - 如何使用 Cerberus 返回自定义规则名称/错误代码?

java - Camel onException 之后的多个处理程序

python - 如何在每个测试用例中都有一个记录器?

python - 通过自身而不是方法参数的类的 Pytest fixture

javascript - 如何在 JavaScript 中获取 JSON 数据数组?

python - 有效地调整图像的ndarray

java - 无法找到错误的根本原因(GWT-Umbrella 异常)