我在conftest.py中有一个全局变量,并在测试中使用它。例如:
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
现在,我希望能够将api_version从cmd更改为测试其他api版本。因此,我以以下方式修改了conftest.py:
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)
但是,这并不像我预期的那样工作,因为所有导入都在安装之前执行,而test_foo import api_url = None 在 cmd_param cmd_param重新定义之前都会执行。然后编写get_api_url方法并从测试模块调用它:
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
但现在我也被迫改变了test_foo.py:
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
这是可行的,但解决方案看起来很尴尬。是否有更优雅的方法使用自定义cmd选项而不更改测试文件?
发布于 2017-06-22 14:35:53
注: pytest_namespace现在已被废弃,
pytest提供了一种在会话中使用一些全局变量的方法。这些变量也可以被固定装置使用。
这些变量是通过火钩来控制的。
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
发布于 2019-01-18 06:16:10
根据文档的说法,在4.0版中删除了pytest_namespace
:
可以使用pytest_configure
共享全局变量。
示例:
import pytest
def pytest_configure():
pytest.my_symbol = MySymbol()
发布于 2017-06-13 06:33:10
我不想搞乱全局变量。只需定义您的工具来返回一个值并在测试中使用该工具:类似@milo发布的内容,但要简单得多。
此外,您还定义了--api_version
CLI选项,但在您的夹具中访问了--mobile_api_ver
选项。此外,您的测试只是检查响应对象是否为None,而后者永远不会是None,因此即使响应为404状态,assert语句也将始终通过,请参见内联注释。
下面是一些可以工作的代码:
conftest.py含量
import pytest
def pytest_addoption(parser):
parser.addoption("--api_version", action="store", default="v25", help="By default: v25")
@pytest.fixture(scope='session')
def api_url(pytestconfig):
api_version = pytestconfig.getoption("--api_version").lower()
if api_version in ['v24', 'v25', 'v26', 'v27']:
return 'http://www.foobar.com/' + api_version
else:
raise ValueError('Unknown api version: ' + api_version)
test_foo.py含量
import pytest
import requests
@pytest.fixture
def data(api_url): # probably a good idea to rename your fixture to a api_response or change what fixture returns.
return requests.get(api_url)
def test_bar(data):
print(data.text)
# below you are not testing data, but merely checking that response object is not None
assert data is not None # this will always pass
# you probably want to test status code and response content
assert data.status_code == 200
assert data.json()
运行测试:pytest -vvv --api_version v24 test_foo.py
https://stackoverflow.com/questions/44441929
复制相似问题