pytest 在一行中断言多个对象

pytest assert multiple objects in single line

提问人:liteyagami 提问时间:2/25/2022 更新时间:3/1/2022 访问量:1302

问:

我正在使用 pytest 为同一条件断言多个对象。 编写重复代码的板。我想知道如何将这些多个对象组合在一起,以便在一条线上同时进行测试。

以下是我当前的代码:

assert response['a'] is not None
assert response['b'] is not None
assert response['c'] is not None
assert response['d'] is not None

从本质上讲,我正在寻找的是这样的:
assert response['a'], response['b'], response['c'], response['d'] is not None

我确实研究了参数夹具,但看起来这不适合我当前的用例。

python-3.x pytest 断言 相等

评论

4赞 jasonharper 2/25/2022
for param in ('a', 'b', 'c', 'd'): assert response[param] is not None也许。
0赞 rvf 2/27/2022
for param in "abcd": assert response.get(param) is not None作为替代方案。请注意,用两行写这篇文章被认为更像 Pythonic

答:

1赞 Shod 3/1/2022 #1
assert all(getattr(response, x) for x in ["a", "b", "c", "d"])
0赞 Christophe Brun 3/1/2022 #2

对于相同的测试,pytest 的参数化装饰器允许您编写单个测试更改参数。

与列表推导相比,代码的可读性得到了提高,因为测试更简单。此外,您的 Junit 或报告被拆分为每个属性的单个测试,突出显示问题所在:

enter image description here

另一个问题是,如果密钥不存在,则测试密钥不会引发,并且您的测试状态将为错误,而不是失败。如果不存在,则对对象使用该方法获取 None。NoneKeyErrorget

因此,我会以这种方式编写测试(假设可以是固定装置):response

import pytest

@pytest.fixture()
def response():
    return {"a": 1, "b": None}

@pytest.mark.parametrize("attribute", ('a', 'b', 'c', 'd'))
def test_attributes(attribute, response):
    assert response.get(attribute) is not None