在pytest中,conftest.py文件有什么用? [英] In pytest, what is the use of conftest.py files?

查看:39
本文介绍了在pytest中,conftest.py文件有什么用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近发现了 pytest.看起来很棒.不过,我觉得文档可能会更好.

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

我想了解 conftest.py 文件的用途.

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. I use it to define the fixtures that I inject into my tests.

我有两个问题:

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

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

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

推荐答案

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

Is this the correct use of conftest.py?

是的.Fixtures 是 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.py might be useless and it would slow down testing if such fixtures are not used by all tests.

它还有其他用途吗?

是的.

  • Fixtures:为测试使用的静态数据定义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.

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

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:您可以指定设置和拆卸方法等钩子,以改进您的测试.有关一组可用的钩子,请阅读 钩子链接.示例:

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`

  • 测试根路径:这是一个隐藏的功能.通过在您的根路径中定义 conftest.py,您将让 pytest 识别您的应用程序模块,而无需指定 PYTHONPATH.在后台,py.test 通过包含从根路径找到的所有子模块来修改您的 sys.path.

  • 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 文件吗?

    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. Therefore, creating targeted fixtures and helpers is good practice.

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

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

    适合多种情况:

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

    Creating a set of tools or hooks for a particular group of tests.

    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 fixtures for some tests but not for others.

    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)
    

    将打印一些其他的东西".

    Will print "some other stuff".

    覆盖从根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 中运行任何测试,只有我是 mod"已打印.

    By running any test inside root/mod, only "I am mod" is printed.

    您可以在这里阅读更多关于conftest.py的信息一>.

    You can read more about conftest.py here.

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

    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 来定义您的助手.但是,您应该遵循常规做法.至少在 pytest 中,助手可以用作夹具.例如,在我的测试中,我有一个模拟 redis 助手,我以这种方式将其注入到我的测试中.

    You can use conftest.py to 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.

    root/helper/redis/redis.py

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

    root/tests/stuff/conftest.py

    pytest_plugin="helper.redis.redis"
    

    root/tests/stuff/test.py

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

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

    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. However, that practice is discouraged because of ambiguity.

    如果你想使用 conftest.py,你可以简单地把这个 helper 放在你的根目录 conftest.py 并在需要时注入它.

    If you want to use conftest.py, you can simply put that helper in your root conftest.py and inject it when needed.

    root/tests/conftest.py

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

    root/tests/stuff/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

    class MockRedis():
        # stuff
    

    root/tests/stuff/test.py

    from helper.redis import MockRedis
    
    def test():
        print(MockRedis().get(stuff))
    

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

    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

    root/tests/helper/init.py

    root/tests/helper/init.py

    from .redis import MockRedis
    

    或者只是将辅助模块添加到您的 PYTHONPATH.

    Or simply adding the helper module to your PYTHONPATH.

    这篇关于在pytest中,conftest.py文件有什么用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆