I'm trying to define a string in pytest script using a function at module level (and not directly assigning value to a variable) which will be used in a fixture with scope='module'. The problem is that when using a function at module level, it's being evaluated during the pytest collect phase - and when running pytest on a folder with a couple of scripts, the fixture uses the last evaluated value.
Is there an other way to set the string at module level, per script?
This is what I have so far, which didn't do the job:
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
You can access the tested module in the fixture via the node
object in the request
fixture, as well as any variables or functions defined in that module:
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
provides you with the test node, and obj
is the module in the case of module level fixture, so you can just access the objects defined in the module via that variable.
To illustrate - if you run this:
$python -m pytest -v -s test_dir
you can see that the module specific value is used:
...
collected 2 items
test_dir/test_1.py::test_first test1var
PASSED
test_dir/test_2.py::test_first test2var
PASSED
If for some reason you need to save the module-specific string elsewhere (as stated in the comments), you have to save them per module, for example by using the module name as key:
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