繁体   English   中英

在非根 conftest.py 中使用 pytest_addoptions

[英]Using pytest_addoptions in a non-root conftest.py

我有一个具有以下结构的项目:

Project/
|
+-- src/
|   |
|   +-- proj/
|       |
|       +-- __init__.py
|       +-- code.py
|       +-- tests/
|           |
|           +-- __init__.py
|           +-- conftest.py
|           +-- test_code.py
+-- doc/
+-- pytest.ini
+-- setup.py

可导入包proj位于src目录下。 测试与它一起安装在proj.tests子包中。 代码、测试本身和安装都可以正常工作。 但是,我无法将选项传递给测试。

我有一个选项--plots ,它在conftest.py (在Project/src/proj/tests/ )中定义,它在根文件夹中创建一个.plots/文件夹并在那里放置一些图形调试:

# conftest.py
def pytest_addoption(parser):
    parser.addoption("--plots", action="store_true", default=False)

我想有两种不同的方式来运行这个测试:

  1. 第一个是从命令行,在Project目录中:

     $ pytest --plots

    这立即失败

     usage: pytest [options] [file_or_dir] [file_or_dir] [...] pytest: error: unrecognized arguments: --plots inifile: /.../Project/pytest.ini rootdir: /.../Project

    如果我添加包目录,运行正常:

     $ pytest src/proj --plots ... rootdir: /.../Project, inifile: pytest.ini ...

    如果我指定测试子目录,它也很顺利:

     $ pytest src/proj/tests --plots ... rootdir: /.../Project, inifile: pytest.ini ...
  2. 第二种方式是运行包本身的test功能。 test函数在Project/src/proj/__init__.py如下:

     # __init__.py def test(*args, **kwargs): from pytest import main cmd = ['--pyargs', 'proj.tests'] cmd.extend(args) return main(cmd, **kwargs)

    该函数旨在像这样安装Project后运行:

     >>> import proj >>> proj.test()

    一般来说,这工作正常,但如果我这样做

     >>> proj.test('--plots')

    我像往常一样得到同样的错误:

     usage: [options] [file_or_dir] [file_or_dir] [...] : error: unrecognized arguments: --plots inifile: None rootdir: /some/other/folder

    对于这个测试,我运行python setup.py develop然后cd 'd to /some/other/folder` 以确保一切安装正确。

我的目标是在传入--plots命令行选项时让两个选项都能正常工作。 似乎我找到了选项 #1 的解决方法,即手动将其中一个包传递给pytest ,但我什至不完全理解它是如何工作的(为什么我可以传入src/projsrc/proj/tests ?)。

所以问题是,如何让 pytest 持续运行我的测试包,以便选择正确的conftest.py 我愿意考虑任何合理的替代方案,使我能够让--plots选项在源(在Project的 shell 中运行)版本和proj.test()版本中proj.test()


作为参考,这是我的pytest.ini文件:

# pytest.ini

[pytest]
testpaths = src/proj/tests
confcutdir = src/proj/tests

它似乎没有任何区别。

我在 Python 2.7、3.3、3.4、3.5、3.6 和 3.7(在 anaconda 中)上运行 pytest 3.8.0。 在所有版本中,结果都是可重现的。

引用自pytest_addoption文档

注意:由于pytest 在启动期间发现插件的方式,此功能应仅在位于测试根目录的插件或conftest.py文件中实现。

...

请注意, pytest在工具启动时不会在更深的嵌套子目录中找到conftest.py文件。 conftest.py文件保存在顶级测试或项目根目录中通常是个好主意。

当你调用pytestProject目录, pytest将其识别为根目录,所以addoptionProject/src/proj/tests/conftest.py被忽略。

如果您描述的项目结构是pytest_addopts ,我pytest_addopts钩子 impl 移动到单独的插件模块; 这可以位于项目目录中的任何位置,例如Project/src/proj/tests/plugin_plots.py 现在,如果你打电话

$ pytest -p src.proj.tests.plugin_plots

addoption hook impl 将被执行并且参数将被正确添加。

(您可能需要调整sys.path才能正确加载自定义插件模块,例如使用PYTHONPATH=. pytest -ppython -m pytest -p ,或以可编辑模式安装项目等)

为了不每次都输入-p参数,请将其保留在pytest.ini ,例如

# pytest.ini
[pytest]
addopts=-p src.proj.tests.plugin_plots

编辑:

以编程方式运行测试时,请增强 args 列表:

def test(*args, **kwargs):
    from pytest import main
    cmd = ['-p', 'proj.tests.plugin_plots', '--pyargs', 'proj.tests']
    cmd.extend(args)
    return main(cmd, **kwargs)

应该工作得很好。

暂无
暂无

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

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