我试图理解conftest.py文件的用途。

在我的测试套件(目前很小)中,我在项目根目录下有一个conftest.py文件。我使用它来定义注入到测试中的fixture。

我有两个问题:

这是conftest.py的正确用法吗?它还有其他用途吗? 我可以有多个conftest.py文件吗?我想什么时候做呢?例子将不胜感激。

更一般地说,如何在pytest测试套件中定义conftest.py文件的目的和正确使用?


从广义上讲,conftest.py是一个本地每个目录的插件。这里定义了特定于目录的钩子和fixture。在我的例子中,有一个根目录包含项目特定的测试目录。一些常见的魔法位于“根”conftest.py中。具体项目-在他们自己的。在conftest.py中存储fixture不会有什么不好,除非它们没有被广泛使用(在这种情况下,我更喜欢直接在测试文件中定义它们)


这是conftest.py的正确用法吗?

是的。fixture是conftest.py的一种潜在且常见的用途。的 您将定义的fixture将在测试套件中的所有测试之间共享。但是,在根目录conftest.py中定义fixture可能毫无用处,如果不是所有测试都使用这些fixture,则会降低测试速度。

它还有其他用途吗?

是的。

Fixtures: Define fixtures for static data used by tests. This data can be accessed by all tests in the suite unless specified otherwise. This could be data as well as helpers of modules which will be passed to all tests. External plugin loading: conftest.py is used to import external plugins or modules. By defining the following global variable, pytest will load the module and make it available for its test. Plugins are generally files defined in your project or other modules which might be needed in your tests. You can also load a set of predefined plugins as explained here. pytest_plugins = "someapp.someplugin" Hooks: You can specify hooks such as setup and teardown methods and much more to improve your tests. For a set of available hooks, read Hooks link. Example: def pytest_runtest_setup(item): """ called before ``pytest_runtest_call(item). """ #do some stuff` Test root path: This is a bit of a hidden feature. By defining conftest.py in your root path, you will have pytest recognizing your application modules without specifying PYTHONPATH. In the background, py.test modifies your sys.path by including all submodules which are found from the root path.

我可以有多个conftest.py文件吗?

是的,你可以,如果你的测试结构有点复杂,强烈建议你这样做。conf .py文件具有目录作用域。因此,创建目标fixture和helper是很好的实践。

我想什么时候做呢?例子将不胜感激。

以下几种情况适合:

为特定的测试组创建一组工具或钩子。

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"

为某些测试加载一组fixture,但不为其他测试加载。

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

根/ conftest.py

def pytest_runtest_setup(item):
    print("I am root")
    #do some stuff

通过在root/mod内部运行任何测试,只打印“I am mod”。

你可以在这里阅读更多关于conftest.py的信息。

编辑:

如果我需要从一个数字调用普通的老助手函数怎么办 不同模块的测试-如果我把它们放在 它们在一个conftest.py中?或者我应该简单地把它们放在help .py文件中 模块和导入并在我的测试模块中使用它?

您可以使用conftest.py来定义您的helper。但是,您应该遵循惯例。至少在pytest中,helper可以用作fixture。例如,在我的测试中,我有一个模拟的redis助手,我以这种方式将它注入到我的测试中。

root /助手/ redis / redis . py

@pytest.fixture
def mock_redis():
    return MockRedis()

root/tests/stuff/conftest.py

pytest_plugin="helper.redis.redis"

根/测试/东西/测试.py

def test(mock_redis):
    print(mock_redis.get('stuff'))

这将是一个您可以在测试中自由导入的测试模块。注意,如果你的模块redis包含更多的测试,你可能会将redis.py命名为conftest.py。但是,由于模糊性,不鼓励这种做法。

如果您想使用conftest.py,您可以简单地将该帮助器放在根目录conftest.py中,并在需要时注入它。

root /测试/ conftest . py

@pytest.fixture
def mock_redis():
    return MockRedis()

根/测试/东西/测试.py

def test(mock_redis):
    print(mock_redis.get(stuff))

你可以做的另一件事是编写一个可安装的插件。在这种情况下,您的帮助程序可以在任何地方编写,但它需要定义一个入口点,以便安装在您的和其他潜在的测试框架中。看到这个。

如果不想使用fixture,当然可以定义一个简单的helper,并在需要的地方使用普通的导入。

root /测试/助手/ redis . py

class MockRedis():
    # stuff

根/测试/东西/测试.py

from helper.redis import MockRedis

def test():
    print(MockRedis().get(stuff))

但是,这里您可能会遇到路径问题,因为模块不在测试的子文件夹中。你应该能够通过向你的helper添加__init__.py来克服这个问题(未测试)

root /测试/助手/ init . py

from .redis import MockRedis

或者简单地将帮助模块添加到PYTHONPATH中。


我使用conftest.py文件来定义注入到测试中的fixture,这是conftest.py的正确使用吗?

是的,fixture通常用于为多个测试准备数据。

它还有其他用途吗?

是的,fixture是pytest以前或有时运行的函数 之后,实际测试功能。fixture中的代码可以执行任何操作 希望如此。例如,可以使用fixture获取要进行测试的数据集,或者还可以使用fixture在运行测试之前将系统置于已知状态。

我可以有多个conftest.py文件吗?我想什么时候做呢?

首先,可以将fixture放入单独的测试文件中。但是,要在多个测试文件之间共享fixture,您需要为所有测试使用位于中心位置的conftest.py文件。任何测试都可以共享fixture。如果希望fixture仅供该文件中的测试使用,则可以将它们放在单独的测试文件中。

第二,是的,您可以在top tests目录的子目录中有其他conftest.py文件。如果这样做,在这些较低级的conftest.py文件中定义的fixture将可用于该目录及其子目录中的测试。

最后,将fixture放在conftest.py文件的测试根目录下,将使它们在所有测试文件中可用。


下面是关于使用conftest.py共享fixture的官方文档:

conftest.py: sharing fixtures across multiple files The conftest.py file serves as a means of providing fixtures for an entire directory. Fixtures defined in a conftest.py can be used by any test in that package without needing to import them (pytest will automatically discover them). You can have multiple nested directories/packages containing your tests, and each directory can have its own conftest.py with its own fixtures, adding on to the ones provided by the conftest.py files in parent directories.