【发布时间】:2015-04-14 12:28:02
【问题描述】:
测试函数我需要传递参数并查看输出是否与预期输出匹配。
当函数的响应只是一个可以在测试函数内部定义的小数组或单行字符串时,这很容易,但是假设我测试的函数修改了一个可能很大的配置文件。或者,如果我明确定义它,结果数组是 4 行长。我在哪里存储它,以便我的测试保持干净且易于维护?
现在,如果那是字符串,我只需在 .py 测试附近放置一个文件,然后在测试中执行 open() :
def test_if_it_works():
with open('expected_asnwer_from_some_function.txt') as res_file:
expected_data = res_file.read()
input_data = ... # Maybe loaded from a file as well
assert expected_data == if_it_works(input_data)
我发现这种方法存在许多问题,例如保持此文件为最新的问题。它看起来也很糟糕。 我可以让事情变得更好,把它移到固定装置上:
@pytest.fixture
def expected_data()
with open('expected_asnwer_from_some_function.txt') as res_file:
expected_data = res_file.read()
return expected_data
@pytest.fixture
def input_data()
return '1,2,3,4'
def test_if_it_works(input_data, expected_data):
assert expected_data == if_it_works(input_data)
这只是将问题转移到另一个地方,通常我需要测试函数在空输入、单个项目或多个项目的输入的情况下是否有效,因此我应该创建一个包含所有三个案例或多个夹具的大夹具。最后代码变得相当混乱。
如果一个函数需要一个复杂的字典作为输入,或者返回同样庞大的字典,测试代码就会变得丑陋:
@pytest.fixture
def input_data():
# It's just an example
return {['one_value': 3, 'one_value': 3, 'one_value': 3,
'anotherky': 3, 'somedata': 'somestring'],
['login': 3, 'ip_address': 32, 'value': 53,
'one_value': 3], ['one_vae': 3, 'password': 13, 'lue': 3]}
很难阅读使用此类固定装置的测试并使其保持最新状态。
更新
搜索了一段时间后,我找到了一个库,它解决了部分问题,而不是大的配置文件,我有大的 HTML 响应。我是betamax。
为了方便使用,我创建了一个夹具:
from betamax import Betamax
@pytest.fixture
def session(request):
session = requests.Session()
recorder = Betamax(session)
recorder.use_cassette(os.path.join(os.path.dirname(__file__), 'fixtures', request.function.__name__)
recorder.start()
request.addfinalizer(recorder.stop)
return session
所以现在在我的测试中,我只使用session 固定装置,我发出的每个请求都会自动序列化到fixtures/test_name.json 文件,所以下次我执行测试而不是执行真正的 HTTP 请求库时,会从文件系统:
def test_if_response_is_ok(session):
r = session.get("http://google.com")
这非常方便,因为为了使这些装置保持最新状态,我只需要清理 fixtures 文件夹并重新运行我的测试。
【问题讨论】:
-
从开发者的角度来看,有TC故障,需要调试。他有一个测试用例的名字,所以他去这个名字的功能。如果你把预期的数据分开保存,你就会强迫他来回跳来比较它。只要您可以将测试输入和预期输入保留在测试用例中或尽可能靠近它,恕我直言。
-
@m.wasowski 那么您的建议是什么?将大块数据保留在测试函数的主体中?例如,如果它是二进制的怎么办?..
-
无论如何,二进制读起来不太好,所以情况不同。我只是说,在测试中保持数据就近使用至少与 DRY 一样重要。这一切都取决于具体情况。当然我建议你缩进你的数据......你写的这个
return真的很难看,很难理解。