Avi*_*ohn 166 python testing pytest
我最近发现了pytest.看起来很棒.但是,我觉得文档可能更好.
我正在尝试了解哪些conftest.py文件的用途.
在我(当前很小的)测试套件中,我conftest.py在项目根目录中有一个文件.我用它来定义我注入测试的灯具.
我有两个问题:
conftest.py吗?它有其他用途吗?conftest.py文件吗?我什么时候想这样做?将举例说明.更一般地说,您如何conftest.py在py.test测试套件中定义文件的目的和正确使用?
Sim*_*ara 222
这是conftest.py的正确用法吗?
是的.固定装置是潜在的和常见的用途conftest.py.您将定义的灯具将在测试套件中的所有测试中共享.但是,在根中定义夹具conftest.py可能没用,如果所有测试都没有使用这样的夹具,它会减慢测试速度.
它有其他用途吗?
是的,它确实.
夹具:定义测试使用的静态数据的夹具.除非另有说明,否则可以通过套件中的所有测试访问此数据.这可能是数据以及将传递给所有测试的模块的帮助程序.
外部插件加载:conftest.py用于导入外部插件或模块.通过定义以下全局变量,pytest将加载模块并使其可用于其测试.插件通常是项目中定义的文件或测试中可能需要的其他模块.为解释您也可以加载一组预定义的插件在这里.
pytest_plugins = "someapp.someplugin"
挂钩:您可以指定挂钩,例如设置和拆卸方法等等,以改善您的测试.有关一组可用的挂钩,请阅读此处.例:
def pytest_runtest_setup(item):
""" called before ``pytest_runtest_call(item). """
#do some stuff`
Run Code Online (Sandbox Code Playgroud)测试根路径:这是一个隐藏的功能.通过conftest.py在根路径中定义,您将pytest无需指定即可识别应用程序模块PYTHONPATH.在后台,py.test sys.path通过包含从根路径找到的所有子模块来修改您的.
我可以拥有多个conftest.py文件吗?
是的,你可以,强烈建议你的测试结构有点复杂.conftest.py文件有目录范围.因此,创建有针对性的固定装置和助手是很好的做法.
我什么时候想这样做?将举例说明.
有几种情况可以适合:
为特定测试组创建一组工具或挂钩.
根/ MOD/conftest.py
def pytest_runtest_setup(item):
print("I am mod")
#do some stuff
test root/mod2/test.py will NOT produce "I am mod"
Run Code Online (Sandbox Code Playgroud)
为某些测试加载一组灯具但不为其他测试加载.
根/ MOD/conftest.py
@pytest.fixture()
def fixture():
return "some stuff"
Run Code Online (Sandbox Code Playgroud)
根/ MOD2/conftest.py
@pytest.fixture()
def fixture():
return "some other stuff"
Run Code Online (Sandbox Code Playgroud)
根/ MOD2/test.py
def test(fixture):
print(fixture)
Run Code Online (Sandbox Code Playgroud)
将打印"其他一些东西".
覆盖从根继承的覆盖conftest.py.
根/ MOD/conftest.py
def pytest_runtest_setup(item):
print("I am mod")
#do some stuff
Run Code Online (Sandbox Code Playgroud)
根/ conftest.py
def pytest_runtest_setup(item):
print("I am root")
#do some stuff
Run Code Online (Sandbox Code Playgroud)
通过在里面运行任何测试root/mod,只打印"我是mod".
你可以conftest.py 在这里阅读更多信息.
编辑:
如果我需要从不同模块中的多个测试中调用普通的帮助函数,如果我将它们放在conftest.py中,它们是否可用?或者我应该简单地将它们放在helpers.py模块中并导入并在我的测试模块中使用它?
您可以使用它conftest.py来定义帮助程序.但是,你应该遵循惯例.辅助工具至少可以用作固定装置pytest.例如,在我的测试中,我有一个模拟redis帮助器,我以这种方式注入我的测试.
根/辅助/ redis的/ redis.py
@pytest.fixture
def mock_redis():
return MockRedis()
Run Code Online (Sandbox Code Playgroud)
根/测试/材料/ conftest.py
pytest_plugin="helper.redis.redis"
Run Code Online (Sandbox Code Playgroud)
根/测试/材料/ test.py
def test(mock_redis):
print(mock_redis.get('stuff'))
Run Code Online (Sandbox Code Playgroud)
这将是一个测试模块,您可以在测试中自由导入.请注意,您可能会命名redis.py,就conftest.py好像您的模块redis包含更多测试一样.但是,由于含糊不清,不鼓励这种做法.
如果您想使用conftest.py,可以简单地将该帮助器放在根目录中conftest.py,并在需要时将其注入.
根/测试/ conftest.py
@pytest.fixture
def mock_redis():
return MockRedis()
Run Code Online (Sandbox Code Playgroud)
根/测试/材料/ test.py
def test(mock_redis):
print(mock_redis.get(stuff))
Run Code Online (Sandbox Code Playgroud)
你可以做的另一件事是编写一个可安装的插件.在这种情况下,您的助手可以在任何地方编写,但需要定义一个入口点,以便安装在您和其他潜在的测试框架中.看到这个.
如果你不想使用灯具,你当然可以定义一个简单的帮手,只需在任何需要的地方使用普通的旧导入.
根/测试器/辅助/ redis.py
class MockRedis():
# stuff
Run Code Online (Sandbox Code Playgroud)
根/测试/材料/ test.py
from helper.redis import MockRedis
def test():
print(MockRedis().get(stuff))
Run Code Online (Sandbox Code Playgroud)
但是,在这里您可能会遇到路径问题,因为模块不在测试的子文件夹中.您应该能够通过向__init__.py助手添加一个来克服此问题(未经测试)
根/测试器/辅助/ __ init__.py
from .redis import MockRedis
Run Code Online (Sandbox Code Playgroud)
或者只是将助手模块添加到您的PYTHONPATH.
Fed*_*Baù 17
添加这个答案是因为有一些关于文档中缺少信息的评论,我猜这是第一次问这个问题时回来的,但现在已经得到了很好的解释和记录。
来自conftest.py:在多个文件之间共享固定装置直到页面底部(实际上与固定装置或设置pytest相关的任何内容都可以应用于conftest.py)与conftest.py
因此,通过快速扫描文档,这些是主要功能(但不包括在内):
conftest.py模块化树状层次结构中每个可用的固定装置conftest.py 可以覆盖父级conftest.py(但不能相反)请参阅此third-party plugins现在在接受的答案上,它说测试根路径::这是一个隐藏的功能。通过定义...但就目前而言,最好的方法是添加pythonpath到pytest.ini项目的根目录(实际的项目根目录,而不是project/tests)中,请参阅:pythonpath并为您完成所有操作,并且功能更强大
看起来像
[pytest]
pythonpath = src1 src2
Run Code Online (Sandbox Code Playgroud)
最后,我在这里放置了pytest 文档中关于 范围边界的许多图表之一,可以像这样可视化:
Mar*_*sen 11
以下是有关使用conftest.py 共享固定装置的官方文档:
conftest.py:跨多个文件共享灯具该
conftest.py文件充当为整个目录提供固定装置的一种方式。a 中定义的夹具conftest.py可以被该包中的任何测试使用,而无需导入它们(pytest 将自动发现它们)。您可以有多个包含测试的嵌套目录/包,每个目录都可以有自己的
conftest.py固定装置,添加到conftest.py父目录中的文件提供的固定装置中。
Fur*_*uck 10
从广义上讲,conftest.py是一个本地的每个目录插件.在这里,您可以定义特定于目录的挂钩和夹具.在我的情况下,有一个包含项目特定测试目录的根目录.一些常见的魔法驻留在'root'conftest.py中.具体项目 - 在他们自己的.在conftest.py中存储装置时看不到任何坏处,除非它们没有被广泛使用(在这种情况下我更喜欢直接在测试文件中定义它们)
我使用该
conftest.py文件来定义我注入到我的测试中的灯具,这是正确使用的conftest.py吗?
是的,通常使用夹具来为多个测试准备数据.
它有其他用途吗?
是的,夹具是pytest在实际测试功能之前,有时在之后运行的功能.灯具中的代码可以做任何你想要的.例如,可以使用夹具来获取要运行的测试的数据集,或者也可以使用夹具在运行测试之前使系统进入已知状态.
我可以拥有多个
conftest.py文件吗?我什么时候想这样做?
首先,可以将灯具放入单独的测试文件中.但是,要在多个测试文件之间共享装置,您需要在conftest.py所有测试的中心位置使用文件.任何测试都可以共享灯具.如果您希望夹具仅由该文件中的测试使用,则可以将它们放入单独的测试文件中.
其次,是的,您可以conftest.py在顶级测试目录的子目录中包含其他文件.如果这样做,这些较低级别conftest.py文件中定义的fixture 将可用于该目录和子目录中的测试.
最后,将fixtures放在conftest.py测试根目录下的文件中将使它们在所有测试文件中可用.