您的测试方案可能看起来像这样。
首先我建议创建一个用于各种方法测试的夹具。夹具设置你的类的一个实例用于测试,而不是在测试本身中创建实例。以这种方式保持任务分离有助于使您的测试更健壮,更易于阅读。
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。
您需要做的另一件事是确保任何.get
调用Requests
被拦截。这很重要,因为它允许您的测试在没有互联网连接的情况下运行,并确保它们不会因连接不良而失败,这不是您要测试的事情。
通过使用pytest
的monkeypatch 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)
这个看上去复杂,直到你明白发生了什么:我们只是做了一些嘲笑JSON对象(通过字典来表示)与预先确定的用户ID和地址。修补版本的Requests.get
只需返回一个类型为MockedReq
的对象 - 当请求其id时,将使用相应的嘲讽.json()
方法。
注意Requests
只会在实际使用上面的测试夹具修补,例如:
def test_something(patched_requests):
# use patched Requests.get
任何测试不使用patched_requests
作为输入参数,将不使用补丁版本。
另外请注意,您可以在测试本身中使用monkeypatch Requests
,但我建议单独执行此操作。如果您使用请求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
另外:问计资源被认为是题外话了所以,这里是我用来学习'pytest':[link](https://www.youtube.com/watch?v=l32bsaIDoWk&list=PLeo1K3hjS3utzQYDNRNluzqJqpMXx6hHu)[link](https://www.youtube.com/watch? v = UPanUFVFfzY)[link](https://www.youtube.com/watch?v=k99HS HQDsi4)。 –
谢谢@RickTeachey指出错误和资源。 –