这是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`
测试根路径:这是一个隐藏功能。通过conftest.py
在根路径中进行定义,pytest
无需指定即可识别应用程序模块PYTHONPATH
。py.test在后台sys.path
通过包含从根路径找到的所有子模块来修改您的文件。
我可以有多个conftest.py文件吗?
是的,您可以,如果测试结构有些复杂,强烈建议您这样做。conftest.py
文件具有目录范围。因此,创建有针对性的装置和助手是一个好习惯。
我什么时候要这么做?示例将不胜感激。
几种情况可能适合:
为一组特定的测试创建一组工具或挂钩。
root / 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"
加载一组夹具用于某些测试,但不用于其他测试。
root / mod / conftest.py
@pytest.fixture()
def fixture():
return "some stuff"
root / mod2 / conftest.py
@pytest.fixture()
def fixture():
return "some other stuff"
root / mod2 / test.py
def test(fixture):
print(fixture)
将打印“其他一些东西”。
覆盖从根继承的钩子conftest.py
。
root / mod / conftest.py
def pytest_runtest_setup(item):
print("I am mod")
#do some stuff
root / conftest.py
def pytest_runtest_setup(item):
print("I am root")
#do some stuff
通过在内部运行任何测试root/mod
,仅打印“ I am mod”。
您可以conftest.py
在此处了解更多信息。
编辑:
如果我需要从不同模块中的多个测试中调用普通的辅助函数,该怎么办-如果将它们放在conftest.py中,它们将对我可用吗?还是我应该将它们放在helpers.py模块中,然后在测试模块中导入并使用它?
您可以conftest.py
用来定义您的助手。但是,您应该遵循常规做法。辅助工具至少可以在中用作固定装置pytest
。例如,在我的测试中,我有一个模拟的redis帮助器,可以通过这种方式将其注入到我的测试中。
根目录/helper/redis/redis.py
@pytest.fixture
def mock_redis():
return MockRedis()
根/测试/材料/ conftest.py
pytest_plugin="helper.redis.redis"
根/测试/材料/ test.py
def test(mock_redis):
print(mock_redis.get('stuff'))
这将是一个测试模块,您可以自由地将其导入测试中。注意,您可能会命名redis.py
,conftest.py
好像您的模块redis
包含更多测试一样。但是,由于模棱两可,不鼓励这种做法。
如果要使用conftest.py
,只需将该帮助程序放在根目录中conftest.py
,并在需要时将其注入。
root / tests / conftest.py
@pytest.fixture
def mock_redis():
return MockRedis()
根/测试/材料/ test.py
def test(mock_redis):
print(mock_redis.get(stuff))
您可以做的另一件事是编写一个可安装的插件。在那种情况下,您的助手可以写在任何地方,但是需要定义一个要安装在您的和其他潜在测试框架中的入口点。看到这个。
如果您不想使用固定装置,则当然可以定义一个简单的帮助器,并在需要的地方使用普通的旧导入。
root /测试/helper/redis.py
class MockRedis():
# stuff
根/测试/材料/ test.py
from helper.redis import MockRedis
def test():
print(MockRedis().get(stuff))
但是,由于模块不在测试的子文件夹中,因此此处可能存在路径问题。您应该能够克服这(未测试)通过添加__init__.py
到您的帮助
root / tests / helper / __ init__.py
from .redis import MockRedis
或者只是将helper模块添加到您的中PYTHONPATH
。
It seems great. However, I feel the documentation could be better.