测试函数我需要传递参数并查看输出是否与预期输出匹配。
当函数的响应只是一个可以在测试函数内部定义的小数组或单行字符串时,这很容易,但假设我测试的函数修改了一个可能很大的配置文件。或者,如果我明确定义它,结果数组是 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)
这只是将问题转移到另一个地方,通常我需要测试在空输入、单个项目或多个项目输入的情况下功能是否有效,因此我应该创建一个包含所有三个案例或多个 fixture 的大 fixture 。最后代码变得相当困惑。
如果一个函数需要一个复杂的字典作为输入,或者返回同样庞大的字典,测试代码就会变得丑陋:
@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 .
为了方便使用,我创建了一个 fixture :
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
fixture ,我发出的每个请求都会自动序列化到 fixtures/test_name.json
文件中,所以下次我执行测试而不是做一个真正的 HTTP 请求库从文件系统加载它:
def test_if_response_is_ok(session):
r = session.get("http://google.com")
这非常方便,因为为了使这些装置保持最新状态,我只需要清理 fixtures
文件夹并重新运行我的测试。
最佳答案
我曾经遇到过类似的问题,我必须根据预期文件测试配置文件。我就是这样解决的:
在相同位置创建一个与您的测试模块同名的文件夹。将所有预期的文件放入该文件夹中。
test_foo/ expected_config_1.ini expected_config_2.ini test_foo.py
创建一个 fixture ,负责将该文件夹的内容移动到一个临时文件中。我确实使用了
tmpdir
固定装置。from __future__ import unicode_literals from distutils import dir_util from pytest import fixture import os @fixture def datadir(tmpdir, request): ''' Fixture responsible for searching a folder with the same name of test module and, if available, moving all contents to a temporary directory so tests can use them freely. ''' filename = request.module.__file__ test_dir, _ = os.path.splitext(filename) if os.path.isdir(test_dir): dir_util.copy_tree(test_dir, bytes(tmpdir)) return tmpdir
重要提示:如果您使用的是 Python 3,请将
dir_util.copy_tree(test_dir, bytes(tmpdir))
替换为dir_util.copy_tree(test_dir, str( tmpdir))
.使用你的新 fixture 。
def test_foo(datadir): expected_config_1 = datadir.join('expected_config_1.ini') expected_config_2 = datadir.join('expected_config_2.ini')
请记住:datadir
与 tmpdir
fixture 相同,此外还可以处理放置在名为 test 模块的文件夹中的预期文件。
关于python - Pytest 在哪里存储预期数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29627341/