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'],
]
@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]
问题是如果 for 的值'one'
不好,我们就不会测试'two'
and的值'three'
。
我正在考虑添加另一个参数化,如下所示:
@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 中有什么可以帮助我的吗?
还是一种设计模式/一种pythonic方式?
我已经使用 python 几年了,但这是我第一次使用 pytest。
解决方案
这可以通过使用夹具范围来解决:
Fixtures 在测试首次请求时创建,并根据其范围销毁
普通夹具具有函数范围,但如果您想在同一个文件中重用夹具值,scope="module"
或者 scope="class" 可能是最合适的,但其他选项也是可能的。
@pytest.fixture(scope="module")
def response1():
yield requests.get(url1)
@pytest.fixture(scope="session")
def response2():
yield requests.get(url2)
def test_responses1(response1, response2):
assert response1.status_code == response2.status_code
@pytest.mark.parametrize("field", ["one", "two", "three"])
def test_responses2(field, response1, response2):
body1 = response1.json()
body2 = response2.json()
assert body1[field] == body2[field]
要验证每个夹具只被调用一次,您可以运行 pytest-s
并在每个夹具中打印一些值。IE。重写response1
:
@pytest.fixture(scope="module")
def response1():
print("in response1")
yield requests.get(url1)
然后运行pytest -s
你的测试
编辑:如果网址总是成对出现,我将按以下方式重写代码:
url_pairs = [('url1a', 'url1b'), ('url2a', 'url2b')]
@pytest.fixture(scope="session", params=url_pairs)
def response_pairs(request):
url_a, url_b = request.param
yield requests.get(url_a), requests.get(url_b)
def test_responses1(response_pairs):
response_a, response_b = response_pairs
assert response_a.status_code == response_b.status_code
@pytest.mark.parametrize("field", ["one", "two", "three"])
def test_responses2(field, response_pairs):
body_a = response_pairs[0].json()
body_b = response_pairs[1].json()
assert body_a[field] == body_b[field]
推荐阅读
- botframework - Bot 支持哪些所有语言的 Skype 频道?
- java - 无法模拟本地变量 - 获取指定密钥不存在(服务 Amazon S3)
- firebase - Custom events in Firebase
- java - 使用配置切换秒表功能
- vba - 将值复制到包含公式的工作表而不删除公式
- javascript - 如何为循环创建数组
- java - jar xf file.jar 在 Windows 10 中不起作用
- sed - how do edit complex xml file by sed
- airflow - Airflow - 尝试执行一组 Python 函数
- ios - Testflight installing issue