I've re-created the question with a new simpler fake-setup.
I have a framework that needs a command lane variable from pytest. This variable is called environment but when I attempt to access that variable I get a AttributeError: 'module' object has no attribute 'config'.
Here is my tests setup:
I know py.test loads in this order:
I think I'm running into an issue where when I load the inner conftest.py I attempt to import the framework. When I import the framework it attempts to access the py.test variable. This variable, even though pytest has seen it in the pytest_addoption() sections of my outer-conftest.py, isn't ready to be used in pytest.
Contents of outer contest:
# content of conftest.py
import pytest
def pytest_addoption(parser):
print("First")
parser.addoption("--cmdopt", action="store", default="type1",
help="my option: type1 or type2")
@pytest.fixture
def cmdopt(request):
return request.config.getoption("cmdopt")
Contents of framework.py:
import pytest
class Environment:
@staticmethod
def env():
'''Determine which environment we are operating in,
if it fails - we assume dca
'''
return pytest.config.getoption('cmdopt')
class Users:
__pool = Environment.env()
Contents of inner conftest.py:
import pytest
from testing.framework import Environment
Contents of test_sample.py:
# content of test_sample.py
def test_answer(cmdopt):
if cmdopt == "type1":
print ("first")
elif cmdopt == "type2":
print ("second")
assert 0 # to see what was printed
I run the following command in the testing/ folder: py.test -q --cmdopt=type2
I receive the following error:
First
Second
Traceback (most recent call last):
File "/usr/local/lib/python3.4/dist-packages/_pytest/config.py", line 513, in getconftestmodules
return self._path2confmods[path]
KeyError: local('/home/damonp/Repos/stuff/<my-name-redacted>/testing/tests')
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.4/dist-packages/_pytest/config.py", line 537, in importconftest
return self._conftestpath2mod[conftestpath]
KeyError: local('/home/damonp/Repos/stuff/<my-name-redacted>/testing/tests/conftest.py')
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.4/dist-packages/_pytest/config.py", line 543, in importconftest
mod = conftestpath.pyimport()
File "/usr/local/lib/python3.4/dist-packages/py/_path/local.py", line 641, in pyimport
__import__(modname)
File "/home/damonp/Repos/stuff/<my-name-redacted>/testing/tests/conftest.py", line 5, in <module>
from testing.framework import Environment
File "/home/damonp/Repos/stuff/<my-name-redacted>/testing/framework.py", line 14, in <module>
class Users:
File "/home/damonp/Repos/stuff/<my-name-redacted>/testing/framework.py", line 15, in Users
__pool = Environment.env()
File "/home/damonp/Repos/stuff/<my-name-redacted>/testing/framework.py", line 11, in env
return pytest.config.getoption('cmdopt')
AttributeError: 'module' object has no attribute 'config'
ERROR: could not load /home/damonp/Repos/stuff/<my-name-redacted>/testing/tests/conftest.py
Is there a good way to use an external framework that relies on a pytest command line variable?
Ideally you would have fixtures that give you objects from your framework, for example a User(s) instance.
These fixtures can receive the cmdopt
fixture, and could then pass that value to an init method or factory function.
e.g.
@pytest.fixture(scope="function")
def user(cmdarg):
return Users(cmdarg, ...)
And then in your test,
def test_something(user):
# do something with user object
You can just add variable to module framework.py, import framework module to outer conftest.py and set this variable under cmdopt method.
Code in framework.py:
import pytest
cmdopt = None
class Environment:
@staticmethod
def env():
'''Determine which environment we are operating in,
if it fails - we assume dca
'''
return pytest.config.getoption('cmdopt')
class Users:
__pool = Environment.env()
Code in outer conftest.py:
# content of conftest.py
import pytest
from . import framework
def pytest_addoption(parser):
print("First")
parser.addoption("--cmdopt", action="store", default="type1",
help="my option: type1 or type2")
@pytest.fixture
def cmdopt(request):
framework.cmdopt = request.config.getoption("cmdopt")
return framework.cmdopt
The second thing you can do is to add variable to Environment class and operate on it. If you need some more logic while getting or setting this variable you can always use @property and setter inside Environment class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With