Python Pytest-多个测试可以共享相同的请求响应吗?

Python Pytest-多个测试可以共享相同的请求响应吗?,python,pytest,Python,Pytest,我有一个url对列表,我为它们创建了这个参数化测试: url_list = [ ['example1.com/x', 'example2.com/x'], ['example1.com/y', 'example2.com/y'], ['example1.com/z', 'example2.com/z'], ['example1.com/v', 'example2.com/v'], ['example1.com/w', 'example2.com/w'],

我有一个url对列表,我为它们创建了这个参数化测试:

url_list = [
    ['example1.com/x', 'example2.com/x'],
    ['example1.com/y', 'example2.com/y'],
    ['example1.com/z', 'example2.com/z'],
    ['example1.com/v', 'example2.com/v'],
    ['example1.com/w', 'example2.com/w'],
]

@pytest.mark.parametrize('url1, url2', url_list)
def test_urls(url1: str, url2: str):
    response1 = requests.get(url1)
    response2 = requests.get(url2)

    assert response1.status_code == response2.status_code

    body1 = response1.json()
    body2 = response2.json()

    for field in ['one', 'two', 'three']:
        assert body1[field] == body2[field]
问题是如果
'one'
的值不好,我们就不会测试
'two'
'twree'
的值

我在考虑添加另一个参数化,比如:

@pytest.mark.parametrize('field', ['one', 'two', 'three'])
@pytest.mark.parametrize('url1, url2', url_list)
def test_urls(url1: str, url2: str):
    response1 = requests.get(url1)
    response2 = requests.get(url2)

    assert response1.status_code == response2.status_code

    body1 = response1.json()
    body2 = response2.json()

    assert body1[field] == body2[field]
问题是同一请求将被执行多次

我可以使用全局变量来存储测试之间的请求响应,但这感觉很难看

pytest中有什么可以帮助我的吗

还是一种设计模式/一种蟒蛇式的方式


我已经使用python几年了,但这是我第一次使用pytest。

这可以通过以下方法解决:

夹具是在测试首次请求时创建的,并根据其范围销毁

普通装置有一个功能范围,但如果您想在同一文件中重用装置值,
scope=“module”
或scope=“class”可能是最合适的,但也可以使用其他选项


@pytest.夹具(scope=“模块”)
def response1():
生成请求。获取(url1)
@pytest.fixture(scope=“session”)
def response2():
生成请求。获取(url2)
def测试_响应1(响应1,响应2):
断言response1.status\u code==response2.status\u code
@pytest.mark.parametize(“字段”、[“一”、“二”、“三”])
def测试_响应2(字段、响应1、响应2):
body1=response1.json()
body2=response2.json()
断言body1[field]==body2[field]
要验证每个fixture只调用一次,可以使用
-s
运行pytest,并在每个fixture中打印一些值。即重写
响应1

@pytest.fixture(scope="module")
def response1():
    print("in response1")
    yield requests.get(url1) 
然后在测试上运行
pytest-s

编辑: 如果URL总是成对出现,我将按照以下方式重写代码:

url_pairs=[('url1a','url1b'),('url2a','url2b')]
@fixture(scope=“session”,params=url\u对)
def响应_对(请求):
url\u a,url\u b=request.param
生成requests.get(url\a),requests.get(url\b)
def测试响应1(响应对):
响应a,响应b=响应对
断言响应\u a.status\u code==响应\u b.status\u code
@pytest.mark.parametize(“字段”、[“一”、“二”、“三”])
def测试响应2(字段、响应对):
body_a=response_pairs[0].json()
body_b=response_pairs[1].json()
断言正文a[字段]==正文b[字段]

如果您的目标只是在断言失败时查看完整输出,那么您可以执行类似于
assert body1[field]==body2[field],f“{body1}!={body2}”的操作
,这样我就无法轻松查看字段
'one'
的哪些测试失败,例如,url1和url2来自一组对,我用魔杖在每一双鞋上做的动作urls@eternal_student我做的编辑是你想要的吗?我想是的。。。
test\u response1
test\u response2
是否都得到了所有对?每个url只会被调用一次?@eternal_学生tldr:是的。长回答:
request.get
对于每个url只调用一次,因此对于上面的示例,无论定义了多少个使用
response\u对的测试函数
<代码>响应\对将包含2个响应的元组
test_responses1
将被调用两次,每对url调用一次,而
test_responses2
将被调用6次,两对url分别与3个字段值相结合。我昨天尝试了您的示例,我感到惊喜。我认为固定装置就像发电机一样工作,两个测试调用同一个发电机。。。我越来越喜欢Pytest了!