我试图理解conftest.py文件是用来做什么的。
conftest.py
在我的(目前较小)测试套件中,我在项目根目录下有一个conftest.py文件。我使用它来定义注入到测试中的fixture。
我有两个问题:
更一般地说,你将如何定义pytest测试套件中conftest.py文件的目的和正确使用?
广义上,conftest.py是一个本地每个目录的插件。这里定义了特定于目录的钩子和fixture。在我的例子中,有一个根目录包含项目特定的测试目录。一些常见的魔法位于`根` conftest.py中。具体项目-在他们自己的。在conftest.py中存储fixture不会看到任何不好的东西,除非它们没有被广泛使用(在这种情况下,我更喜欢直接在测试文件中定义它们)
这是conftest.py的正确用法吗?
是的。fixture是conftest.py的一个潜在且常见的用途。的 您将定义的fixture将在测试套件中的所有测试之间共享。然而,在根conftest.py中定义fixture可能是无用的,如果不是所有测试都使用这些fixture,则会降低测试速度
它还有其他用途吗?
是的。
固定装置:为测试使用的静态数据定义fixture。除非另有指定,否则套件中的所有测试都可以访问此数据。这可以是数据,也可以是将传递给所有测试的模块的帮助程序。
外部插件加载: 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。
pytest
PYTHONPATH
sys.path
我可以有多个conftest.py文件吗?
是的,你可以,如果你的测试结构有点复杂,强烈建议你这样做。conftest.py文件具有目录作用域。因此,创建目标fixture和helper是很好的实践。
我想什么时候做呢?例子将不胜感激。
以下几种情况适合:
为特定的测试组创建一组工具或钩子。
根/国防部/ 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"
为某些测试加载一组固定装置,但不为其他测试加载。
@pytest.fixture() def fixture(): return "some stuff"
根/ mod2 / conftest.py
@pytest.fixture() def fixture(): return "some other stuff"
根/ mod2 / test.py
def test(fixture): print(fixture)
将打印“一些其他的东西”。
压倒一切的钩子继承自根conftest.py。
def pytest_runtest_setup(item): print("I am mod") #do some stuff
根/ conftest.py
def pytest_runtest_setup(item): print("I am root") #do some stuff
通过在root/mod中运行任何测试,只有“;I am mod"是印刷的。
root/mod
你可以阅读更多关于conftest.py 在这里。
编辑:
如果我需要普通的旧helper函数从一个数字调用 不同模块的测试-如果我把它们放在 它们在一个conftest.py中?或者我应该简单地把它们放在help .py文件中 模块和导入并在我的测试模块中使用它?< / p >
你可以使用conftest.py来定义你的helper。但是,您应该遵循惯例。至少在pytest中,helper可以作为fixture使用。例如,在我的测试中,我有一个模拟的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包含更多的测试,你可以潜在地将redis.py命名为conftest.py。但是,由于模糊性,不鼓励这种做法。
redis
redis.py
如果你想使用conftest.py,你可以简单地把这个帮助器放在你的根conftest.py中,并在需要时注入它。
根/测试/ conftest.py
def test(mock_redis): print(mock_redis.get(stuff))
你可以做的另一件事是编写一个可安装的插件。在这种情况下,您的帮助程序可以在任何地方编写,但它需要定义一个入口点,以便安装在您的和其他潜在的测试框架中。看到这。
如果不想使用fixture,当然可以定义一个简单的helper,并在需要的地方使用普通的导入。
根/测试/帮助/ redis.py
class MockRedis(): # stuff
from helper.redis import MockRedis def test(): print(MockRedis().get(stuff))
但是,这里您可能会遇到路径问题,因为模块不在测试的子文件夹中。你应该能够通过向你的helper添加__init__.py来克服这个问题(未测试)
__init__.py
根/测试/帮助/ < >强init.py < / >强
from .redis import MockRedis
或者简单地将helper模块添加到PYTHONPATH中。
我使用conftest.py文件来定义注入到测试中的fixture,这是conftest.py的正确使用吗?
是的,一个fixture通常用于为多个测试准备数据。
是的, fixture是以前和有时由pytest运行的函数 之后,实际测试功能。fixture中的代码可以执行任何操作 希望如此。例如,可以使用fixture获取要进行测试的数据集,或者还可以使用fixture在运行测试之前将系统置于已知状态
我可以有多个conftest.py文件吗?我想什么时候做呢?
首先,可以将fixture放入单独的测试文件中。然而,要在多个测试文件之间共享fixture,您需要在所有测试的中心位置使用conftest.py文件。任何测试都可以共享fixture。如果希望fixture仅供该文件中的测试使用,则可以将它们放在单独的测试文件中。
第二,是的,你可以在顶级测试目录的子目录中有其他conftest.py文件。如果这样做,在这些较低级的conftest.py文件中定义的fixture将可用于该目录和子目录中的测试。
最后,将fixture放在测试根的conftest.py文件中,将使它们在所有测试文件中可用。
下面是关于使用共享固定装置的官方文档:
conftest.py:跨多个文件共享fixture conftest.py文件作为一种为整个目录提供fixture的方法。conftest.py中定义的fixture可以被该包中的任何测试使用,而不需要导入它们(pytest将自动发现它们)。 你可以有多个包含测试的嵌套目录/包,并且每个目录都可以有自己的conftest.py和自己的fixture,添加到父目录中conftest.py文件提供的fixture。
conftest.py:跨多个文件共享fixture
conftest.py文件作为一种为整个目录提供fixture的方法。conftest.py中定义的fixture可以被该包中的任何测试使用,而不需要导入它们(pytest将自动发现它们)。
你可以有多个包含测试的嵌套目录/包,并且每个目录都可以有自己的conftest.py和自己的fixture,添加到父目录中conftest.py文件提供的fixture。