Is this the correct use of conftest.py?
是的。fixture是conftest.py的一种潜在和常见的用法。这个
您将定义的fixture将在测试套件中的所有测试之间共享。但是,在根目录conftest.py中定义fixture可能是无用的,如果不是所有测试都使用这样的fixture,则会减慢测试速度。Does it have other uses?
是的。Fixtures:为测试使用的静态数据定义fixture。除非另有说明,否则套件中的所有测试都可以访问此数据。这可能是数据以及将传递给所有测试的模块的帮助程序。
外部插件加载:conftest.py用于导入外部插件或模块。通过定义以下全局变量,pytest将加载模块并使其可用于其测试。插件通常是在项目中定义的文件,或者是在测试中可能需要的其他模块。您还可以加载一组预定义的插件,如here所述。
pytest_plugins = "someapp.someplugin"
Hooks:您可以指定Hooks,例如setup和teardown方法,以及更多来改进测试。对于一组可用的钩子,请阅读here。示例:def pytest_runtest_setup(item):
""" called before ``pytest_runtest_call(item). """
#do some stuff`
测试根路径:这是一个隐藏的特性。通过在根路径中定义conftest.py,您将可以pytest识别应用程序模块,而无需指定PYTHONPATH。在后台,py.test通过包含从根路径找到的所有子模块来修改sys.path。Can I have more than one conftest.py file?
是的,如果您的测试结构有点复杂,那么强烈建议您这样做。conftest.py文件具有目录作用域。因此,创建有针对性的装置和助手是一个好的实践。When would I want to do that? Examples will be appreciated.
有几种情况适合:
为特定测试组创建一组工具或挂钩。
根目录/mod/conftest.pydef pytest_runtest_setup(item):
print("I am mod")
#do some stuff
test root/mod2/test.py will NOT produce "I am mod"
为某些测试加载一组fixture,但不为其他测试加载。
根目录/mod/[email protected]()
def fixture():
return "some stuff"
根目录/mod2/[email protected]()
def fixture():
return "some other stuff"
根目录/mod2/test.pydef test(fixture):
print(fixture)
会打印“一些其他的东西”。
重写从根继承的挂钩conftest.py。
根目录/mod/conftest.pydef pytest_runtest_setup(item):
print("I am mod")
#do some stuff
根目录/conftest.pydef pytest_runtest_setup(item):
print("I am root")
#do some stuff
通过在root/mod内运行任何测试,只打印“我是mod”。
您可以阅读有关conftest.pyhere的更多信息。
编辑: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助手,我用这种方式将它注入到我的测试中。
根/helper/redis/[email protected]
def mock_redis():
return MockRedis()
根目录/tests/stuff/conftest.pypytest_plugin="helper.redis.redis"
根目录/tests/stuff/test.pydef test(mock_redis):
print(mock_redis.get('stuff'))
这将是一个测试模块,您可以在测试中自由导入。注意如果模块redis包含更多测试,则可以将redis.py命名为conftest.py。然而,由于模棱两可,这种做法是不可取的。
如果要使用conftest.py,只需将该助手放在根目录conftest.py中,并在需要时注入它。
根目录/tests/[email protected]
def mock_redis():
return MockRedis()
根目录/tests/stuff/test.pydef test(mock_redis):
print(mock_redis.get(stuff))
你可以做的另一件事是编写一个可安装的插件。在这种情况下,您的助手可以在任何地方编写,但它需要定义一个入口点,以便安装在您和其他潜在的测试框架中。见this。
如果您不想使用fixture,您当然可以定义一个简单的helper,只要在需要的地方使用普通的旧导入。
根目录/tests/helper/redis.py
^{公关1三}$
根目录/tests/stuff/test.pyfrom helper.redis import MockRedis
def test():
print(MockRedis().get(stuff))
但是,由于模块不在测试的子文件夹中,您可能在这里遇到路径问题。您应该能够通过向助手添加__init__.py来克服这个问题(未测试)
根目录/tests/helper/\u init.pyfrom .redis import MockRedis
或者简单地将helper模块添加到PYTHONPATH。