currently I am writing some Webapp, but this time I want to learn how to write proper tests for it (using pytest) :)
A very common pattern I often see is to make the default configuration changeable using environment variables. Currently I am struggling how to test this properly.
I've prepared some demo:
./app
./app/conf.py
./conftest.py
./run.py
./tests
./tests/test_demo.py
My ./app/conf.py
looks like this:
from os import environ
DEMO = environ.get('DEMO', 'demo')
TEST = environ.get('TEST', 'test')
Launching the ./run.py
shows that the settings are indeed changeable:
from os import environ
environ['DEMO'] = 'not a demo'
environ['TEST'] = 'untested'
from app import conf
if __name__ == '__main__':
print(conf.DEMO)
print(conf.TEST)
It prints out not a demo
and untested
- as expected. Great. (Note that I set the environment variables before importing conf
).
Now to the tests: The ./conftest.py
is currently empty it just helps pytest to locate the modules inside the app folder.
The ./tests/test_demo.py
contains the following:
def test_conf_defaults():
from app import conf
assert conf.DEMO == 'demo'
assert conf.TEST == 'test'
def test_conf_changed(monkeypatch):
monkeypatch.setenv('DEMO', 'tested demo')
monkeypatch.setenv('TEST', 'demo test')
from app import conf
assert conf.DEMO == 'tested demo'
assert conf.TEST == 'demo test'
monkeypatch.undo()
If I run pytest now, test_conf_changed
fails with 'demo' == 'tested demo'
-> the monkeypatch function did not patch the environment.
If I swap both testing functions (so test_conf_changed
runs first), the test_conf_defaults
will fail with 'tested demo' == 'demo'
.
How I interpret it, is - the first time conf
gets imported it sticks there with it's initial settings..
How can I tell pytest to completely reimport conf
each test function, after setting up the environment variables?
I am stuck there for two days now - and slowly I doubt if testing is worth the hassle - please prove me wrong :)
Thanks for the hint, Evert (variables inside the conf module are set inside the global namespace, they stick around) - I think I got it now.
To test my code I have to explicitly reimport
conf
after setting the environment variables. Changing the code in./tests/test_demo.py
to this does the trick:Thank you.