pytest 如何以及在哪里找到固定装置

Posted

技术标签:

【中文标题】pytest 如何以及在哪里找到固定装置【英文标题】:How and where does py.test find fixtures 【发布时间】:2012-11-18 11:34:30 【问题描述】:

py.test 在哪里以及如何查找固定装置?我在同一个文件夹中的 2 个文件中有相同的代码。当我删除conftest.py时,找不到运行test_conf.py的cmdopt(也在同一个文件夹中。为什么没有搜索到sonoftest.py?

# content of test_sample.py
def test_answer(cmdopt):
    if cmdopt == "type1":
        print ("first")
    elif cmdopt == "type2":
        print ("second")
    assert 0 # to see what was printed

conftest.py 的内容

import pytest

def pytest_addoption(parser):
    parser.addoption("--cmdopt", action="store", default="type1",
        help="my option: type1 or type2")

@pytest.fixture
def cmdopt(request):
    return request.config.getoption("--cmdopt")

sonoftest.py 的内容

import pytest

def pytest_addoption(parser):
    parser.addoption("--cmdopt", action="store", default="type1",
        help="my option: type1 or type2")

@pytest.fixture
def cmdopt(request):
    return request.config.getoption("--cmdopt")

文档说

http://pytest.org/latest/fixture.html#fixture-function

    pytest 因为 test_ 前缀而找到了 test_ehlo。测试函数需要一个名为 smtp 的函数参数。配套的夹具 函数是通过查找一个名为 smtp。 smtp() 被调用来创建一个实例。 test_ehlo() 被调用并在测试函数的最后一行失败。

【问题讨论】:

【参考方案1】:

py.test 将导入conftest.py 和所有匹配python_files 模式的Python 文件,默认为test_*.py。如果您有一个测试夹具,您需要从conftest.py 或依赖它的测试文件中包含或导入它:

from sonoftest import pytest_addoption, cmdopt

【讨论】:

由于某种原因,如果您使用 Pycharm,它会检测到夹具的导入未使用(至少在 2021.2.3 版本中)。无论如何,如果您删除夹具导入,它将停止工作。【参考方案2】:

这里是 py.test 查找固定装置(和测试)的顺序和位置(取自 here):

py.test 在工具启动时通过以下方式加载插件模块:

    通过加载所有内置插件

    通过加载通过 setuptools 入口点注册的所有插件。

    通过预先扫描-p name 选项的命令行并在实际命令行解析之前加载指定的插件。

    通过加载命令行调用推断的所有conftest.py 文件(测试文件及其所有父目录)。注意 conftest.py 子目录中的文件默认不加载 工具启动。

    通过递归加载由conftest.py 文件中的 pytest_plugins 变量指定的所有插件

【讨论】:

【参考方案3】:

我遇到了同样的问题,花了很多时间寻找一个简单的解决方案,这个例子是为其他和我有类似情况的人准备的。

conftest.py:
import pytest

pytest_plugins = [
 "some_package.sonoftest"
]

def pytest_addoption(parser):
  parser.addoption("--cmdopt", action="store", default="type1",
      help="my option: type1 or type2")

@pytest.fixture
def cmdopt(request):
  return request.config.getoption("--cmdopt")
some_package/sonoftest.py:
import pytest

@pytest.fixture
def sono_cmdopt(request):
  return request.config.getoption("--cmdopt")
some_package/test_sample.py
def test_answer1(cmdopt):
  if cmdopt == "type1":
      print ("first")
  elif cmdopt == "type2":
      print ("second")
  assert 0 # to see what was printed

def test_answer2(sono_cmdopt):
  if sono_cmdopt == "type1":
      print ("first")
  elif sono_cmdopt == "type2":
      print ("second")
  assert 0 # to see what was printed

您可以在此处找到类似的示例:https://github.com/pytest-dev/pytest/issues/3039#issuecomment-464489204 和其他这里https://***.com/a/54736376/6655459

来自官方 pytest 文档的描述:https://docs.pytest.org/en/latest/reference.html?highlight=pytest_plugins#pytest-plugins

请注意,在 some_package.test_sample" 需要有__init__.py 文件供pytest 加载插件使用

【讨论】:

以上是关于pytest 如何以及在哪里找到固定装置的主要内容,如果未能解决你的问题,请参考以下文章

加载 Doctrine 固定装置时如何在控制台中禁用查询日志记录?

如何在 rails (4.1.5) 中创建固定装置(对于 Devise 用户)作为 yml.erb?

基于fixture的自动pytest.mark装饰

如何从 Play 框架中的 YAML 固定装置加载(静态嵌套)枚举值?

不使用固定装置的 Django 1.10 种子数据库

如何从现有数据库数据生成 Symfony 固定装置 YAML?