将夹具传递给PyTest中的辅助函数?

Con*_*tle 5 python pytest

我的功能需要在测试套件中使用固定装置。这只是一个小的帮助函数,可以帮助生成完整的URL。

def gen_url(endpoint):
    return "{}/{}".format(api_url, endpoint)
Run Code Online (Sandbox Code Playgroud)

我有一个固定装置,conftest.py它返回URL:

@pytest.fixture(params=["http://www.example.com"])
def api_url(request):
    return request.param

@pytest.fixture(params=["MySecretKey"])
def api_key(request):
    return request.param
Run Code Online (Sandbox Code Playgroud)

最后,在我的测试函数中,我需要调用我的gen_url

def test_call_action_url(key_key):
    url = gen_url("player")
    # url should equal: 'http://www.example.com/player'
    # Do rest of test here...
Run Code Online (Sandbox Code Playgroud)

但是,当我执行此操作时,它会引发错误,指出api_urlgen_url调用时未定义。如果添加api_url为第二个参数,则需要将其作为第二个参数传递。那不是我想做的。

是否可以添加api_url第二个参数gen_url而不需要从测试中传递它?为什么不能像api_key我的test_*函数那样使用它?

the*_*man 8

如果您制作gen_url一个装置,它可以在api_url不显式传递它的情况下发出请求:

@pytest.fixture
def gen_url(api_url):
    def _gen_url(endpoint):
        return '{}/{}'.format(api_url, endpoint)
    return _gen_url


def test_call_action_url(api_key, gen_url):
    url = gen_url('player')
    # ...
Run Code Online (Sandbox Code Playgroud)

另外,如果api_key仅用于发出请求,TestClient 类可以封装它,因此测试方法只需要客户端:

try:
    from urllib.parse import urljoin  # Python 3
except ImportError:
    from urlparse import urljoin  # Python 2

import requests

@pytest.fixture
def client(api_url, api_key):
    class TestClient(requests.Session):
        def request(self, method, url, *args, **kwargs):
            url = urljoin(api_url, api_key)
            return super(TestClient, self).request(method, url, *args, **kwargs)

    # Presuming API key is passed as Authorization header
    return TestClient(headers={'Authorization': api_key})


def test_call_action_url(client):
    response = client.get('player')  # requests <api_url>/player
    # ...
Run Code Online (Sandbox Code Playgroud)


San*_*nju -2

您的代码存在多个问题,除非您将其用作测试参数,否则固定装置在您的测试代码中不可见,否则您不会将固定装置(api_urlapi_key)同时传递给您的测试函数,然后传递给您的辅助函数。这是修改后的代码(未经测试)

def gen_url(api_url, endpoint):
   return "{}/{}".format(api_url, endpoint)

def test_call_action_url(api_url, api_key):
   url = gen_url(api_url, "player")
   # url should equal: 'http://www.example.com/player'
   # Do rest of test here with api_key here...
Run Code Online (Sandbox Code Playgroud)