lan*_*pta 6 python tdd pytest python-3.x
我是初学者在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
Run Code Online (Sandbox Code Playgroud)
有人可以帮我解决这个问题,你也可以建议我学习pytest的最佳资源是什么?TIA
Ric*_*ica 11
您的测试方案可能看起来像这样.
首先,我建议创建一个用于各种方法测试的夹具.fixture将设置一个类的实例,以便在测试中使用,而不是在测试中创建实例.以这种方式保持任务分离有助于使您的测试更健壮,更易于阅读.
from my_package import MyClass
import pytest
@pytest.fixture
def a_test_object():
return MyClass()
Run Code Online (Sandbox Code Playgroud)
您可以将测试对象传递给一系列方法测试:
def test_something(a_test_object):
# do the test
Run Code Online (Sandbox Code Playgroud)
但是,如果您的测试对象在安装过程中需要一些资源(例如连接,数据库,文件等),则可以模拟它以避免为测试设置资源.有关如何执行此操作的一些有用信息,请参阅此演讲.
顺便说一句:如果您需要测试夹具中创建的用户定义对象的几种不同状态,则需要对夹具进行参数化.这是一个复杂的主题,但文档非常清楚地解释了夹具参数化.
您需要做的另一件事是确保拦截任何.get呼叫Requests.这很重要,因为它允许您的测试在没有Internet连接的情况下运行,并确保它们不会因连接错误而失败,这不是您尝试测试的内容.
您可以拦截Requests.get通过使用猴补丁功能的pytest.所需要的只是包括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)
Run Code Online (Sandbox Code Playgroud)
在您了解正在发生的事情之前,这看起来很复杂:我们只是使用预先确定的用户ID和地址制作了一些模拟的json对象(由字典表示).修补版本Requests.get只返回一个类型的对象MockedReq- 在.json()请求其id时使用相应的mocked 方法.
请注意,Requests只会在实际使用上述灯具的测试中打补丁,例如:
def test_something(patched_requests):
# use patched Requests.get
Run Code Online (Sandbox Code Playgroud)
任何不用patched_requests作输入参数的测试都不会使用修补版本.
另请注意,您可以Requests在测试中进行monkeypatch ,但我建议您单独进行.如果您正在使用请求API的其他部分,您可能还需要对它们进行monkeypatch.保持所有这些东西分开往往比在测试中包含它更容易理解.
接下来写下各种方法测试.您需要针对方法的每个方面进行不同的测试.换句话说,您通常会为方法成功的实例编写不同的测试,而另一个测试则在测试失败时进行测试.
首先,我们使用几个测试用例测试方法成功.
@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
Run Code Online (Sandbox Code Playgroud)
接下来,我们可以BadId使用该with pytest.raises功能测试是否引发异常.请注意,由于引发了异常,因此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)
Run Code Online (Sandbox Code Playgroud)
正如我的评论中所述,这里还有一些额外的资源可以帮助您了解有关pytest的更多信息:
| 归档时间: |
|
| 查看次数: |
5274 次 |
| 最近记录: |