Answer a question

I have a global variable in conftest.py and use it in tests. For example:

conftest.py

api_version = 'v25'
api_url = 'http://www.foobar.com/' + api_version

test_foo.py

from conftest import api_url
import requests

@pytest.fixture
def data():
    return requests.request("GET", api_url)

test_bar(data):
    assert data is not None

Now I want to be able to change api_version from cmd for testing other api version. So I modified conftest.py in the following way:

conftest.py

api_url = None

def pytest_addoption(parser):
    parser.addoption("--api_version", action="store", default="v25", help="By default: v25")

@pytest.fixture(autouse=True, scope='session')
def cmd_param(pytestconfig):
    api_version = pytestconfig.getoption("--mobile_api_ver").lower()
    global api_url
    if api_version in ['v24', 'v25', 'v26', 'v27']:
        api_url = 'http://www.foobar.com/' + api_version
    else:
        raise ValueError('Unknown api version: ' + api_version)

But this doesn't work as I expected because all imports execute before fixtures and test_foo import api_url = None before cmd_param fixture redefines this. Then i write get_api_url method and call it from test module:

conftest.py

api_url = None

def pytest_addoption(parser):
    parser.addoption("--api_version", action="store", default="v25", help="By default: v25")

@pytest.fixture(autouse=True, scope='session')
def cmd_param(pytestconfig):
    api_version = pytestconfig.getoption("--mobile_api_ver").lower()
    global api_url
    if api_version in ['v24', 'v25', 'v26', 'v27']:
        api_url = 'http://www.foobar.com/' + api_version
    else:
        raise ValueError('Unknown api version: ' + api_version)

def get_api_url():
    return api_url

But now I was forced to change test_foo.py too:

test_foo.py

from conftest import get_api_url
import requests

@pytest.fixture
def data():

    return requests.request("GET", get_api_url())

test_bar(data):
    assert data is not None

It works, but solution looks awkward. Is there a more elegant way to use custom cmd options without changing test files?

Answers

Note: pytest_namespace is deprecated now

pytest provides a way to use some global variables within the session. These variables can be used by fixtures as well.

These variables are controlled via pytest hooks.

import pytest

def pytest_namespace():
    return {'my_global_variable': 0}

@pytest.fixture
def data():
    pytest.my_global_variable = 100

def test(data):
    print pytest.my_global_variable
Logo

Python社区为您提供最前沿的新闻资讯和知识内容

更多推荐