简体   繁体   English

在pytest中,conftest.py文件有什么用?

[英]In pytest, what is the use of conftest.py files?

I'm trying to understand what conftest.py files are meant to be used for.我试图了解conftest.py文件的用途。

In my (currently small) test suite I have one conftest.py file at the project root.在我的(目前很小的)测试套件中,我在项目根目录下有一个conftest.py文件。 I use it to define the fixtures that I inject into my tests.我用它来定义我注入到我的测试中的固定装置。

I have two questions:我有两个问题:

  1. Is this the correct use of conftest.py ?这是conftest.py的正确用法吗? Does it have other uses?它还有其他用途吗?
  2. Can I have more than one conftest.py file?我可以拥有多个conftest.py文件吗? When would I want to do that?我什么时候想这样做? Examples will be appreciated.示例将不胜感激。

More generally, how would you define the purpose and correct use of conftest.py file(s) in a pytest test suite?更一般地说,您将如何在 pytest 测试套件中定义conftest.py文件的目的和正确使用?

Is this the correct use of conftest.py?这是 conftest.py 的正确用法吗?

Yes it is.是的。 Fixtures are a potential and common use of conftest.py .夹具是conftest.py的潜在和常见用途。 The fixtures that you will define will be shared among all tests in your test suite.您将定义的固定装置将在您的测试套件中的所有测试之间共享。 However, defining fixtures in the root conftest.py might be useless and it would slow down testing if such fixtures are not used by all tests.但是,在根conftest.py中定义固定装置可能没有用,如果所有测试都没有使用这些固定装置,它会减慢测试速度。

Does it have other uses?它还有其他用途吗?

Yes it does.是的,它确实。

  • Fixtures : Define fixtures for static data used by tests. Fixtures :为测试使用的静态数据定义 fixtures。 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.外部插件加载conftest.py用于导入外部插件或模块。 By defining the following global variable, pytest will load the module and make it available for its test.通过定义以下全局变量,pytest 将加载模块并使其可用于测试。 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 .通过在您的根路径中定义conftest.py ,您将让pytest识别您的应用程序模块而无需指定PYTHONPATH In the background, py.test modifies your sys.path by including all submodules which are found from the root path.在后台,py.test 通过包含从根路径找到的所有子模块来修改您的sys.path

Can I have more than one conftest.py file?我可以拥有多个 conftest.py 文件吗?

Yes you can and it is strongly recommended if your test structure is somewhat complex.是的,如果您的测试结构有些复杂,强烈建议您这样做。 conftest.py files have directory scope. conftest.py文件具有目录范围。 Therefore, creating targeted fixtures and helpers is good practice.因此,创建有针对性的固定装置和助手是一种很好的做法。

When would I want to do that?我什么时候想这样做? Examples will be appreciated.示例将不胜感激。

Several cases could fit:几种情况可能适合:

Creating a set of tools or hooks for a particular group of tests.为一组特定的测试创建一组工具或挂钩

root/mod/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"

Loading a set of fixtures for some tests but not for others.为某些测试加载一组夹具,但不为其他测试加载。

root/mod/conftest.py根/mod/conftest.py

@pytest.fixture()
def fixture():
    return "some stuff"

root/mod2/conftest.py根/mod2/conftest.py

@pytest.fixture()
def fixture():
    return "some other stuff"

root/mod2/test.py根/mod2/test.py

def test(fixture):
    print(fixture)

Will print "some other stuff".将打印“其他一些东西”。

Overriding hooks inherited from the root conftest.py .覆盖从根conftest.py继承的挂钩。

root/mod/conftest.py根/mod/conftest.py

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

root/conftest.py根目录/conftest.py

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

By running any test inside root/mod , only "I am mod" is printed.通过在root/mod中运行任何测试,只会打印“我是 mod”。

You can read more about conftest.py here .您可以在此处阅读有关conftest.py的更多信息。

EDIT:编辑:

What if I need plain-old helper functions to be called from a number of tests in different modules - will they be available to me if I put them in a conftest.py?如果我需要从不同模块中的多个测试中调用普通的旧辅助函数怎么办——如果我将它们放在 conftest.py 中,它们对我可用吗? Or should I simply put them in a helpers.py module and import and use it in my test modules?或者我应该简单地将它们放在 helpers.py 模块中并导入并在我的测试模块中使用它?

You can use conftest.py to define your helpers.您可以使用conftest.py来定义您的助手。 However, you should follow common practice.但是,您应该遵循惯例。 Helpers can be used as fixtures at least in pytest .至少在pytest中,助手可以用作固定装置。 For example in my tests I have a mock redis helper which I inject into my tests this way.例如,在我的测试中,我有一个模拟的 redis 助手,我以这种方式将其注入到我的测试中。

root/helper/redis/redis.py根/助手/redis/redis.py

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

root/tests/stuff/conftest.py根/测试/东西/conftest.py

pytest_plugin="helper.redis.redis"

root/tests/stuff/test.py根/测试/东西/test.py

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

This will be a test module that you can freely import in your tests.这将是一个测试模块,您可以在测试中自由导入。 NOTE that you could potentially name redis.py as conftest.py if your module redis contains more tests.注意,如果您的模块redis包含更多测试,您可能redis.py命名为conftest.py However, that practice is discouraged because of ambiguity.但是,由于含糊不清,不鼓励这种做法。

If you want to use conftest.py , you can simply put that helper in your root conftest.py and inject it when needed.如果你想使用conftest.py ,你可以简单地把这个助手放在你的根conftest.py中,并在需要时注入它。

root/tests/conftest.py根/测试/conftest.py

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

root/tests/stuff/test.py根/测试/东西/test.py

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

Another thing you can do is to write an installable plugin.您可以做的另一件事是编写一个可安装的插件。 In that case your helper can be written anywhere but it needs to define an entry point to be installed in your and other potential test frameworks.在那种情况下,您的助手可以写在任何地方,但它需要定义一个入口点以安装在您和其他潜在的测试框架中。 See this .看到这个

If you don't want to use fixtures, you could of course define a simple helper and just use the plain old import wherever it is needed.如果你不想使用固定装置,你当然可以定义一个简单的助手,并在需要的地方使用普通的旧导入。

root/tests/helper/redis.py根/测试/助手/redis.py

class MockRedis():
    # stuff

root/tests/stuff/test.py根/测试/东西/test.py

from helper.redis import MockRedis

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

However, here you might have problems with the path since the module is not in a child folder of the test.但是,由于模块不在测试的子文件夹中,因此路径可能会出现问题。 You should be able to overcome this (not tested) by adding an __init__.py to your helper你应该能够通过向你的助手添加一个__init__.py来克服这个问题(未经测试)

root/tests/helper/ init .py根/测试/助手/初始化.py

from .redis import MockRedis

Or simply adding the helper module to your PYTHONPATH .或者简单地将帮助程序模块添加到您的PYTHONPATH

In a wide meaning conftest.py is a local per-directory plugin.从广义上讲, conftest.py是一个本地目录插件。 Here you define directory-specific hooks and fixtures.在这里您可以定义目录特定的挂钩和固定装置。 In my case a have a root directory containing project specific tests directories.在我的例子中,有一个包含项目特定测试目录的根目录。 Some common magic is stationed in 'root' conftest.py .一些常见的魔法驻留在“root” conftest.py中。 Project specific - in their own ones.项目特定 - 在他们自己的项目中。 Can't see anything bad in storing fixtures in conftest.py unless they are not used widely (In that case I prefer to define them in test files directly)conftest.py中存储固定装置看不出有什么不好,除非它们没有被广泛使用(在那种情况下,我更喜欢直接在测试文件中定义它们)

I use the conftest.py file to define the fixtures that I inject into my tests, is this the correct use of conftest.py ?我使用conftest.py文件来定义我注入测试的装置,这是conftest.py的正确用法吗?

Yes , a fixture is usually used to get data ready for multiple tests.的,夹具通常用于为多个测试准备好数据。

Does it have other uses?它还有其他用途吗?

Yes , a fixture is a function that is run by pytest before, and sometimes after, the actual test functions.的,夹具是pytest在实际测试功能之前,有时在实际测试功能之后运行的功能。 The code in the fixture can do whatever you want it to. fixture 中的代码可以做任何你想做的事。 For instance, a fixture can be used to get a data set for the tests to work on, or a fixture can also be used to get a system into a known state before running a test.例如,fixture 可用于获取要进行的测试的数据集,或者 fixture 也可用于在运行测试之前使系统进入已知状态。

Can I have more than one conftest.py file?我可以拥有多个conftest.py文件吗? When would I want to do that?我什么时候想这样做?

First, it is possible to put fixtures into individual test files.首先,可以将固定装置放入单独的测试文件中。 However, to share fixtures among multiple test files, you need to use a conftest.py file somewhere centrally located for all of the tests.但是,要在多个测试文件之间共享 fixture,您需要在所有测试的中心位置使用conftest.py文件。 Fixtures can be shared by any test.夹具可以由任何测试共享。 They can be put in individual test files if you want the fixture to only be used by tests in that file.如果您希望夹具仅供该文件中的测试使用,则可以将它们放在单独的测试文件中。

Second, yes , you can have other conftest.py files in subdirectories of the top tests directory.其次,的,您可以在顶级测试目录的子目录中包含其他conftest.py文件。 If you do, fixtures defined in these lower-level conftest.py files will be available to tests in that directory and subdirectories.如果这样做,这些较低级别的conftest.py文件中定义的固定装置将可用于该目录和子目录中的测试。

Finally, putting fixtures in the conftest.py file at the test root will make them available in all test files.最后,将 fixture 放入测试根目录下的conftest.py文件中将使它们在所有测试文件中可用。

Here are the official docs about using conftest.py to share fixtures :以下是关于使用conftest.py 共享 fixtures的官方文档:

conftest.py : sharing fixtures across multiple files conftest.py :跨多个文件共享固定装置

The conftest.py file serves as a means of providing fixtures for an entire directory. conftest.py文件用作为整个目录提供固定装置的方法。 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). conftest.py中定义的夹具可以被该包中的任何测试使用,而无需导入它们(pytest 会自动发现它们)。

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.您可以有多个包含测试的嵌套目录/包,每个目录都可以有自己的conftest.py和自己的装置,添加到父目录中的conftest.py文件提供的那些。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM