如何在模块级别的 pytest 脚本中定义要在夹具中使用的值?
How to define a value in a pytest script at module level to be used in a fixture?
我正在尝试在 pytest 脚本中使用模块级别的函数(而不是直接为变量赋值)定义一个字符串,该字符串将在范围为 'module' 的夹具中使用。
问题是,当在模块级别使用函数时,它会在 pytest 收集阶段进行评估 - 当 运行 pytest 在具有几个脚本的文件夹上时,fixture 使用最后评估的值。
是否有其他方法可以根据脚本在模块级别设置字符串?
这是我目前所拥有的,但没有完成任务:
my_script1.py:
import env_var as env
env.set_my_string('This string will be used in the module fixture')
test_first():
# Do stuff
conf_test.py:
import pytest
import env_var as env
@pytest.fixture(scope='module', autouse=True)
def script_handler():
txt = env.get_my_string()
# Use txt
yield
env_var.py:
_tmp_str = ''
def set_my_string(in_str)
_tmp_str = in_str
def get_my_string():
return _tmp_str
您可以通过 request
fixture 中的 node
对象访问 fixture 中的测试模块,以及该模块中定义的任何变量或函数:
test_1.py
my_env = "test1var"
test_first():
pass
test_2.py
my_env = "test2var"
test_first():
pass
conftest.py
@pytest.fixture(scope='module', autouse=True)
def script_handler(request):
txt = request.node.obj.my_var
print(txt)
yield
request.node
为您提供测试节点,而 obj
是模块级夹具的模块,因此您可以通过该变量访问模块中定义的对象。
为了说明 - 如果你运行这个:
$python -m pytest -v -s test_dir
您可以看到使用了模块特定值:
...
collected 2 items
test_dir/test_1.py::test_first test1var
PASSED
test_dir/test_2.py::test_first test2var
PASSED
如果出于某种原因你需要在别处保存模块特定的字符串(如评论中所述),你必须按模块保存它们,例如使用模块名称作为键:
env_var.py
my_vars = {}
def set_my_string(name, var):
my_vars[name] = var
def get_my_string(name):
return my_vars.get(name, "some_default")
test_1.py
from env_var import set_my_string
set_my_string(__name__, "test1var")
def test_first():
pass
conftest.py
import pytest
from env_var import get_my_string
@pytest.fixture(scope='module', autouse=True)
def script_handler(request):
module_name = request.node.obj.__name__
print(get_my_string(module_name))
yield
除了MrBean Bremen 的出色回答,我还找到了另一个解决方案:
在脚本文件中添加一个夹具,returns sting - 然后在 conf_test.py 文件中使用 request.getfixturevalue() 函数。
my_script1.py:
import pytest
@pytest.fixture(scope='module')
def my_var:
return 'This string will be used in the module fixture'
test_first():
# Do stuff
conf_test.py:
import pytest
@pytest.fixture(scope='module', autouse=True)
def script_handler():
txt = request.getfixturevalue('my_var')
# Use txt
yield
我正在尝试在 pytest 脚本中使用模块级别的函数(而不是直接为变量赋值)定义一个字符串,该字符串将在范围为 'module' 的夹具中使用。 问题是,当在模块级别使用函数时,它会在 pytest 收集阶段进行评估 - 当 运行 pytest 在具有几个脚本的文件夹上时,fixture 使用最后评估的值。
是否有其他方法可以根据脚本在模块级别设置字符串?
这是我目前所拥有的,但没有完成任务:
my_script1.py:
import env_var as env
env.set_my_string('This string will be used in the module fixture')
test_first():
# Do stuff
conf_test.py:
import pytest
import env_var as env
@pytest.fixture(scope='module', autouse=True)
def script_handler():
txt = env.get_my_string()
# Use txt
yield
env_var.py:
_tmp_str = ''
def set_my_string(in_str)
_tmp_str = in_str
def get_my_string():
return _tmp_str
您可以通过 request
fixture 中的 node
对象访问 fixture 中的测试模块,以及该模块中定义的任何变量或函数:
test_1.py
my_env = "test1var"
test_first():
pass
test_2.py
my_env = "test2var"
test_first():
pass
conftest.py
@pytest.fixture(scope='module', autouse=True)
def script_handler(request):
txt = request.node.obj.my_var
print(txt)
yield
request.node
为您提供测试节点,而 obj
是模块级夹具的模块,因此您可以通过该变量访问模块中定义的对象。
为了说明 - 如果你运行这个:
$python -m pytest -v -s test_dir
您可以看到使用了模块特定值:
...
collected 2 items
test_dir/test_1.py::test_first test1var
PASSED
test_dir/test_2.py::test_first test2var
PASSED
如果出于某种原因你需要在别处保存模块特定的字符串(如评论中所述),你必须按模块保存它们,例如使用模块名称作为键:
env_var.py
my_vars = {}
def set_my_string(name, var):
my_vars[name] = var
def get_my_string(name):
return my_vars.get(name, "some_default")
test_1.py
from env_var import set_my_string
set_my_string(__name__, "test1var")
def test_first():
pass
conftest.py
import pytest
from env_var import get_my_string
@pytest.fixture(scope='module', autouse=True)
def script_handler(request):
module_name = request.node.obj.__name__
print(get_my_string(module_name))
yield
除了MrBean Bremen 的出色回答,我还找到了另一个解决方案: 在脚本文件中添加一个夹具,returns sting - 然后在 conf_test.py 文件中使用 request.getfixturevalue() 函数。
my_script1.py:
import pytest
@pytest.fixture(scope='module')
def my_var:
return 'This string will be used in the module fixture'
test_first():
# Do stuff
conf_test.py:
import pytest
@pytest.fixture(scope='module', autouse=True)
def script_handler():
txt = request.getfixturevalue('my_var')
# Use txt
yield