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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34466027/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 15:01:49  来源:igfitidea点击:

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

pythontestingpytest

提问by Aviv Cohn

I recently discovered pytest. It seems great. However, I feel the documentation could be better.

我最近发现pytest。看起来很棒。但是,我觉得文档可能会更好。

I'm trying to understand what conftest.pyfiles are meant to be used for.

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

In my (currently small) test suite I have one conftest.pyfile at the project root. I use it to define the fixtures that I inject into my tests.

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

I have two questions:

我有两个问题:

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

More generally, how would you define the purpose and correct use of conftest.pyfile(s) in a py.test test suite?

更一般地说,您将如何定义conftest.pypy.test 测试套件中文件的用途和正确使用?

采纳答案by Simone Zandara

Is this the correct use of conftest.py?

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

Yes it is. Fixtures are a potential and common use of 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.pymight be useless and it would slow down testing if such fixtures are not used by all tests.

是的。Fixtures 是conftest.py. 您将定义的夹具将在您的测试套件中的所有测试之间共享。然而,在根中定义夹具conftest.py可能没有用,如果所有测试都没有使用这些夹具,它会减慢测试速度。

Does it have other uses?

它还有其他用途吗?

Yes it does.

是的,它确实。

  • 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.pyis 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 here. 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.pyin your root path, you will have pytestrecognizing your application modules without specifying PYTHONPATH. In the background, py.test modifies your sys.pathby including all submodules which are found from the root path.

  • Fixtures:为测试使用的静态数据定义夹具。除非另有说明,否则套件中的所有测试都可以访问此数据。这可能是数据以及将传递给所有测试的模块的助手。

  • 外部插件加载conftest.py用于导入外部插件或模块。通过定义以下全局变量,pytest 将加载模块并使其可用于测试。插件通常是在您的项目或测试中可能需要的其他模块中定义的文件。您还可以按照此处的说明加载一组预定义的插件。

    pytest_plugins = "someapp.someplugin"

  • Hooks:您可以指定设置和拆卸方法等挂钩,以改进您的测试。有关一组可用的钩子,请阅读此处。例子:

    def pytest_runtest_setup(item):
         """ called before ``pytest_runtest_call(item). """
         #do some stuff`
    
  • 测试根路径:这是一个隐藏的功能。通过conftest.py在您的根路径中定义,您将pytest无需指定PYTHONPATH. 在后台, py.testsys.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.pyfiles have directory scope. Therefore, creating targeted fixtures and helpers is good practice.

是的,如果您的测试结构有些复杂,强烈建议您这样做。conftest.py文件具有目录范围。因此,创建有针对性的装置和助手是一种很好的做法。

When would I want to do that? Examples will be appreciated.

我什么时候想要这样做?示例将不胜感激。

Several cases could fit:

几种情况可能适合:

Creating a set of tools or hooksfor a particular group of tests.

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

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

Loading a set of fixturesfor some tests but not for others.

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

root/mod/conftest.py

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

将打印“其他一些东西”。

Overridinghooks inherited from the root conftest.py.

覆盖从根继承的钩子conftest.py

root/mod/conftest.py

root/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.pyhere.

您可以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? Or should I simply put them in a helpers.py module and import and use it in my test modules?

如果我需要从不同模块中的许多测试中调用普通的辅助函数怎么办 - 如果我将它们放在 conftest.py 中,它们是否对我可用?或者我应该简单地将它们放在 helpers.py 模块中并导入并在我的测试模块中使用它?

You can use conftest.pyto define your helpers. However, you should follow common practice. Helpers can be used as fixtures at least in pytest. For example in my tests I have a mock redis helper which I inject into my tests this way.

您可以使用conftest.py来定义您的助手。但是,您应该遵循常规做法。至少在pytest. 例如,在我的测试中,我有一个模拟 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. NOTEthat you could potentially name redis.pyas conftest.pyif your module rediscontains more tests. However, that practice is discouraged because of ambiguity.

这将是一个测试模块,您可以在测试中自由导入。请注意,您可能会命名redis.pyconftest.py好像您的模块redis包含更多测试。但是,由于模棱两可,不鼓励这种做法。

If you want to use conftest.py, you can simply put that helper in your root conftest.pyand 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__.pyto your helper

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

root/tests/helper/__init__.py

root/tests/helper/__init__.py

from .redis import MockRedis

Or simply adding the helper module to your PYTHONPATH.

或者简单地将 helper 模块添加到您的PYTHONPATH.

回答by Furious Duck

In a wide meaning conftest.py is a local per-directory plugin. 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. 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 是一个本地的每个目录插件。在这里定义目录特定的钩子和装置。在我的情况下,有一个包含项目特定测试目录的根目录。一些常见的魔法驻扎在'root' conftest.py 中。项目特定 - 在他们自己的。在 conftest.py 中存储设备看不出有什么不好,除非它们没有被广泛使用(在这种情况下,我更喜欢直接在测试文件中定义它们)

回答by lmiguelvargasf

I use the conftest.pyfile 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 pytestbefore, and sometimes after, the actual test functions. The code in the fixture can do whatever you want it to. 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 是一个pytest在实际测试函数之前运行的函数,有时在实际测试函数之后运行。夹具中的代码可以为所欲为。例如,夹具可用于获取要处理的测试的数据集,或者夹具也可用于在运行测试之前使系统进入已知状态。

Can I have more than one conftest.pyfile? When would I want to do that?

我可以拥有多个conftest.py文件吗?我什么时候想要这样做?

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.pyfile somewhere centrally located for all of the tests. 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.

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

Second, yes, you can have other conftest.pyfiles in subdirectories of the top tests directory. If you do, fixtures defined in these lower-level conftest.pyfiles will be available to tests in that directory and subdirectories.

其次,是的,您可以conftest.py在顶级测试目录的子目录中拥有其他文件。如果这样做,这些低级conftest.py文件中定义的装置将可用于该目录和子目录中的测试。

Finally, putting fixtures in the conftest.pyfile at the test root will make them available in all test files.

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