针对多个后端运行pytest测试?

时间:2018-06-04 10:03:18

标签: python api plugins mocking pytest

我为与Github API交互的代码库构建了一系列测试(使用pytest)(包括调用它和接收webhook)。

目前,这些测试是针对github的半现实模拟运行的:对github的调用是通过Sentry's Responses拦截并运行假github / git实现(我需要的位),也可以进行交互直接来自测试案例。需要触发的任何webhook都使用Werkzeug's test client回调到用作webhook端点的WSGI应用程序。

这很好用,快速(足够)并且是一个很好的默认值,但是我想选择对github本身运行这些相同的测试,这就是我难倒的地方:我需要切换当前的实现被测系统(直接“库”访问代码库和模拟github)与不同的(API访问“外部”运行代码库和实际github),我不太清楚如何继续。

我尝试使用pytest_generate_tests通过插件切换夹具实现(codebase&amp; github),但我不知道这是否会起作用,到目前为止我尝试加载一个通过pytest -p <package_name>在pytest中作为插件的本地文件尚未取得很大成功。

我想知道我是否朝着正确的方向前进,在这种情况下,如果有人可以帮助在pytest中使用“本地”插件(不是通过setuptools而不是基于conftest.py来安装)。 / p>

不确定是否有任何相关性,但我在CPython 3.6上运行pytest 3.6.0,请求2.18.4,响应0.9.0和Werkzeug 0.14.1。

1 个答案:

答案 0 :(得分:0)

有几种方法可以解决这个问题。我默认运行的是运行你的模拟测试,然后当出现命令行标志时,测试两者模拟和真实版本。

首先是更容易的部分,添加一个命令行选项:

def pytest_addoption(parser):
    parser.addoption('--github', action='store_true',
                 help='Also test against real github')

现在这可以通过pytestconfig fixture作为pytestconfig.getoption('github')获得,通常也是间接可用的,例如通过请求夹具request.config.getoption('github')

现在你需要使用这个参数化任何需要与github API交互的测试,以便它们可以与mock和真实实例一起运行。在不知道你的代码的情况下,Werkzeug客户端听起来好点:将它变成一个夹具然后可以参数化以返回真正的客户端或你提到的测试客户端:

@pytest.fixture
def werkzeug_client(werkzeug_client_type):
    if werkzeug_client_type == 'real':
        return create_the_real_client()
    else:
        return create_the_mock_client()

def pytest_generate_tests(metafunc):
    if 'werkzeug_client_type' in metafunc.fixturenames:
        types = ['mock']
        if metafunc.config.getoption('github'):
            types.append('real')
        metafunc.parametrize('werkzeug_client_type', types)

现在,如果您将测试编写为:

def test_foo(werkzeug_client):
     assert werkzeug_client.whatever()

使用pytest --github调用时,您将正常进行一项测试,并进行两次测试。

(请注意,挂钩必须位于conftest.py文件中,而夹具可以放在任何位置。请注意,pytest_addoption挂钩实际上只应在顶级conftest文件中使用,以避免混淆时间钩子是由pytest使用的,当没有。所以你应该把所有这些代码放在一个顶级conftest.py文件中。)