gpt4 book ai didi

python pytest 用于测试请求和响应

转载 作者:行者123 更新时间:2023-12-01 21:24:25 26 4
gpt4 key购买 nike

我是在 python 中使用 pytest 的初学者,并尝试为以下方法编写测试用例,该方法在传递正确的 Id 时获取用户地址,否则会出现自定义错误 BadId。

    def get_user_info(id: str, host='127.0.0.1', port=3000 ) -> str:
uri = 'http://{}:{}/users/{}'.format(host,port,id)
result = Requests.get(uri).json()
address = result.get('user',{}).get('address',None)
if address:
return address
else:
raise BadId

有人可以帮我解决这个问题吗?您可以建议我学习 pytest 的最佳资源是什么吗? TIA

最佳答案

您的测试方案可能看起来像这样。

首先,我建议创建一个用于各种方法测试的 fixture 。该装置设置要在测试中使用的类的实例,而不是在测试本身中创建实例。以这种方式分隔任务有助于使您的测试更加健壮且更易于阅读。

from my_package import MyClass
import pytest

@pytest.fixture
def a_test_object():
return MyClass()

您可以将测试对象传递给您的一系列方法测试:

def test_something(a_test_object):
# do the test

但是,如果您的测试对象在设置过程中需要一些资源(例如连接、数据库、文件等),您可以模拟它以避免为测试设置资源。请参阅 this talk 以获取有关如何执行此操作的一些有用信息。

顺便说一句:如果您需要测试在您的装置中创建的用户定义对象的几种不同状态,您需要对您的装置进行参数化。这是一个有点复杂的主题,但是文档 explains fixture parametrization very clearly

您需要做的另一件事是确保拦截对 Requests 的任何 .get 调用。这很重要,因为它允许您的测试在没有互联网连接的情况下运行,并确保它们不会因连接不良而失败,而这不是您要测试的事情。

您可以使用pytestmonkeypatch feature来拦截Requests.get。所需要做的就是将 monkeypatch 作为测试方案函数的输入参数包含在内。

您可以使用另一个固定装置来完成此操作。它可能看起来像这样:

import Requests
import pytest

@pytest.fixture
def patched_requests(monkeypatch):
# store a reference to the old get method
old_get = Requests.get
def mocked_get(uri, *args, **kwargs):
'''A method replacing Requests.get
Returns either a mocked response object (with json method)
or the default response object if the uri doesn't match
one of those that have been supplied.
'''
_, id = uri.split('/users/', 1)
try:
# attempt to get the correct mocked json method
json = dict(
with_address1 = lambda: {'user': {'address': 123}},
with_address2 = lambda: {'user': {'address': 456}},
no_address = lambda: {'user': {}},
no_user = lambda: {},
)[id]
except KeyError:
# fall back to default behavior
obj = old_get(uri, *args, **kwargs)
else:
# create a mocked requests object
mock = type('MockedReq', (), {})()
# assign mocked json to requests.json
mock.json = json
# assign obj to mock
obj = mock
return obj
# finally, patch Requests.get with patched version
monkeypatch.setattr(Requests, 'get', mocked_get)

这看起来很复杂,直到你明白发生了什么:我们只是用预先确定的用户 ID 和地址制作了一些模拟的 json 对象(由字典表示)。 Requests.get 的修补版本仅返回一个 MockedReq 类型的对象,当其 id 为已请求。

请注意,Requests 只会在实际使用上述固定装置的测试中进行修补,例如:

def test_something(patched_requests):
# use patched Requests.get

任何不使用 patched_requests 作为输入参数的测试都不会使用修补版本。

另请注意,您可以在测试本身中对 Requests 进行 Monkeypatch,但我建议单独进行。如果您正在使用请求 API 的其他部分,您可能还需要对它们进行猴子补丁。将所有这些内容分开通常比将其包含在测试中更容易理解。

接下来编写各种方法测试。您需要对方法的每个方面进行不同的测试。换句话说,您通常会为方法成功的实例编写一个不同的测试,并在方法失败时编写另一个测试。

首先,我们通过几个测试用例测试方法是否成功。

@pytest.mark.parametrize('id, result', [
('with_address1', 123),
('with_address2', 456),
])
def test_get_user_info_success(patched_requests, a_test_object, id, result):
address = a_test_object.get_user_info(id)
assert address == result

接下来,我们可以使用 with pytest.raises 功能来测试是否引发 BadId 异常。请注意,由于引发了异常,因此测试函数没有 result 输入参数。

@pytest.mark.parametrize('id', [
'no_address',
'no_user',
])
def test_get_user_info_failure(patched_requests, a_test_object, id):
from my_package import BadId
with pytest.raises(BadId):
address = a_test_object.get_user_info(id)

正如我在评论中所发布的,这里还有一些其他资源可以帮助您了解有关 pytest 的更多信息:

link

link

另外请务必查看 Brian Okken's bookBruno Oliveira's book 。它们对于学习 pytest 都非常有帮助。

关于python pytest 用于测试请求和响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45910480/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com