Pytest using os.environ - Ho, am I testing it correctly?

I am currently writing several Webapps, but this time I want to learn how to write correct tests for it (using pytest) :)

Very often I often see that you can change the default configuration using environment variables. I am currently struggling how to properly check this.

I have prepared a 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')

      

Running it ./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 not a demo

and untested

- as expected. Fine. (Note that I am setting environment variables before importing conf

).

Now to the tests: ./conftest.py

currently empty, it just helps pytest find modules inside the application folder.

./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, it test_conf_changed

fails 'demo' == 'tested demo'

-> monkeypatch function didn't fix the environment.

If I change both test functions (executed first test_conf_changed

), it test_conf_defaults

will fail 'tested demo' == 'demo'

.

The way I interpret it is - on first login conf

it will import it there with its original settings.

How can I tell pytest to completely reimport conf

each test function after setting environment variables?

I've been stuck there for two days - and I'm slowly doubting testing is worth it to prove I'm wrong :)

+3


source to share


1 answer


Thanks for the tip, Evert (variables inside the conf-module are set inside the global namespace, they stick). I think I got it now.

To test my code, I have to explicitly specify reimport conf

after setting environment variables. Changing the code in ./tests/test_demo.py

to this does the trick:



from importlib import reload

from app import conf


def test_conf_changed(monkeypatch):
    monkeypatch.setenv('DEMO', 'tested demo')
    monkeypatch.setenv('TEST', 'demo test')

    reload(conf)

    assert conf.DEMO == 'tested demo'
    assert conf.TEST == 'demo test'


def test_conf_defaults():

    reload(conf)

    assert conf.DEMO == 'demo'
    assert conf.TEST == 'test'

      

Thank.

+3


source







All Articles