我试图为测试单个api端点的几个测试场景定义init数据。我想这样做,这样我就不必为测试的多次迭代生成锅炉板代码,只有数据不同。我似乎无法使用内置的pytest灯具来解决这个问题。这基本上就是我想要做的事情:
在tests / conftext.py中:
import pytest
@pytest.fixture(scope="module")
def data_for_a():
return "a_data"
@pytest.fixture(scope="module")
def data_for_b():
return "b_data"
在tests / tests.py
中import pytest
# this works
def test_a(data_for_a):
assert "a_data" == data_for_a
# but I want to do this and it fails:
scenarios = [
{ "name": "a", "data": data_for_a },
{ "name": "b", "data": data_for_b },
]
for scenario in scenarios:
print(scenario.name, scenario.data)
# desired output:
# "a a_data"
# "b b_data"
我收到NameError: name 'data_for_a' is not defined
个例外。我已经尝试了各种方法来实现这一点,但似乎无法将夹具作为参数传递给测试方法 - 所以要么定义一堆样板测试,要么有一堆if /单个测试中的else语句并明确传递每个fixture。我不喜欢这些选项中的任何一个。目前我似乎只需构建自己的辅助模块来获取此测试数据,但我更倾向于使用内置机制。有没有办法做到这一点?
答案 0 :(得分:1)
您可以从conftest.py导入,如下所示:
from conftest import data_for_a, data_for_b
或
from conftest import *
允许您引用该函数,而不将其作为参数传递给测试函数。
修改强> 请注意,根据Here is an image of how I want the image to appear on the screen
,通常不建议这样做如果你有conftest.py文件,这些文件不在python包目录中(即包含 __ init __。py 的文件),那么“import conftest”可能不明确,因为可能还有其他的混乱。 py文件以及PYTHONPATH或sys.path。因此,项目要么将conftest.py置于包范围内,要么永远不会从conftest.py文件中导入任何内容,这是很好的做法。
答案 1 :(得分:0)
自您发布以来已经有一段时间了,所以在您发布的时候,pytest
内置这个功能的可能性很小。
我相信你所寻找的是pytest_generate_tests
。您可以在conftest.py模块中定义它(放在包含要运行的测试的目录中),在通过pytest运行任何测试之前自动解析。此功能可用于参数化' [sic]您的测试功能或您的灯具动态,允许您动态定义您希望测试/灯具迭代的输入集。
我已经包含了一个例子。请考虑以下目录结构:
tests
|
+-- examples.py
+-- test_examples.py
+-- conftest.py
现在让我们看看每个文件......
# examples.py
# -----------
example_1 = {
"friendship": 0.0,
"totes": 0.0,
}
example_2 = {
"friendship": 0.0,
"totes": 0.0,
}
dont_use_me = {
"friendship": 1.0,
"totes": 1.0,
}
...
# test_examples.py
# ----------------
def test_answer(pydict_fixture):
for k,v in pydict_fixture.items():
assert v==0.0
...
# conftest.py
# -----------
from os.path import join, dirname, abspath
import imp
import re
def pytest_generate_tests(metafunc):
this_dir = dirname(abspath(metafunc.module.__file__))
#
if 'pydict_fixture' in metafunc.fixturenames:
examples_file= join(this_dir, "examples.py")
examples_module = imp.load_source('examples', examples_file)
examples_regex = re.compile("example")
examples = []
for name, val in examples_module.__dict__.iteritems():
if examples_regex.search(name):
examples.append(val)
metafunc.parametrize('pydict_fixture', examples)
在这个特定的例子中,我想在一个单独的文件中管理测试用例。所以,我写了一个pytest_generate_tests
函数,在运行任何测试之前,解析examples.py
,创建一个字典列表,其名称包括单词' example&#39 ;和,强制test_answer
在列表中的每个字典上运行。因此,test_answer
将被调用两次,一次在example_1
上,一次在example_2
上。两项测试都将通过。
这是它的快速简短。最重要的是输入列表是在pytest_generate_tests
内动态确定的,测试在列表中的每个项目上运行一次。
但是,为了在我对此处所写内容的描述中完整,我的pytest_generate_tests
函数实际上为每个测试函数创建了一个输入列表(由pytest
表示#metafunc
中预定义的pytest_generate_tests
变量使用虚pydict_fixture
,并在examples.py
目录中查找metafunc
文件驻留!因此,可能会扩展为对一堆不同的examples.py
文件运行一系列不同的测试。