从另一个 pip 安装的包针对本地代码运行 py.test 测试

Ian*_*nce 5 python pytest

我正在构建一个包,它提供(1)固定接口和(2)可插入驱动程序。软件包的用户可以选择所需的驱动程序。我的包将至少包含一个驱动程序,但我希望其他开发人员能够实现和验证符合包接口的驱动程序。因此,我希望这些开发人员能够针对他们的驱动程序运行我的测试。

目前,我正在使用 py.test 的参数化装置将我的驱动程序注入到我的测试中:

# conftest.py
import my_pkg
import pytest

@pytest.fixture(params=[my_pkg.MyDriver])
def driver(request):
    return request.param
Run Code Online (Sandbox Code Playgroud)
# my_pkg/tests/conftest.py
import my_pkg
import pytest

@pytest.fixture
def my_interface(driver):
    return my_pkg.MyInterface(driver)
Run Code Online (Sandbox Code Playgroud)
# my_pkg/tests/test_my_interface.py
def test_that_it_does_the_right_thing(my_interface):
    assert my_interface.some_method() == "some return value"
Run Code Online (Sandbox Code Playgroud)

我以这种方式构建它,希望有人能够收集并针对他们的夹具版本运行我的测试driver。换句话说,他们的包看起来像这样:

# setup.py
from setuptools import setup

setup(
    # ...
    install_requires=["my-pkg"])
Run Code Online (Sandbox Code Playgroud)
# conftest.py
import their_pkg
import pytest

@pytest.fixture(params=[their_pkg.TheirDriver])
def driver(request):
    return request.param
Run Code Online (Sandbox Code Playgroud)

显然这还不足以让它工作,因为 py.test 似乎没有提供从外部包注入测试的选项。但这怎么可能呢?

这个问题在概念上似乎相似,但作者似乎完全在一个代码库中工作。我希望有一个完全独立的pip 安装包能够引用我的pip 安装包中包含的测试。)

Ian*_*nce 4

通过以下方式解决了这个问题:

  1. 实现自定义 py.test 收集器,从我的包中移植必要的测试套件,
  2. my_pkg.MyDriverSuite要求消费者在他们的测试文件之一中实例化我的自定义类,然后,
  3. 编写一个自定义 py.test 插件,使用pytest_pycollect_makeitem钩子拦截自定义实例并注入我的收集器。

(注意:这种方法避免了参数化夹具的使用。)


自定义收集器是迄今为止最棘手的部分,因为它需要大量挖掘 py.test 内部结构,并最终使用自定义会话重新实现核心 py.test 收集器的精简Session版本Configrootdir被设置为我的包的那个。