Lets assume you want to test a function like this:
def foo():
something = os.environ.get("SOMETHING")
if something=="BAD":
raise Exception("BAM")
It is used in a little application like this:
def main():
try:
foo()
print("OK")
except:
print("SAD")
I can specify environment values on the command line that eventually get to foo
$ SOMETHING=BAD ./my_app
SAD
$ SOMETHING=ELSE ./my_app
OK
Now, I want to test the behaviour of foo, but I need to be careful not to change my environment settings, so I need to set and restore them, even should the test go bad.
That looks something like:
def test_foo_ok():
orig = os.environ.get("SOMETHING")
os.environ["SOMETHING"]="ELSE"
try:
foo()
finally:
if orig is None:
del os.environ["SOMETHING"]
else:
os.environ["SOMETHING"]=orig
def test_foo_bad():
orig = os.environ.get("SOMETHING")
os.environ["SOMETHING"]="BAD"
try:
with pytest.raises(Exception) as excinfo:
foo()
assert str(excinfo.value) == "BAM"
finally:
if orig is None:
del os.environ["SOMETHING"]
else:
os.environ["SOMETHING"]=orig
You could wrap the boilerplate in those into a decorator if you wanted. I'd call it something like @testwithenv
then the tests would look cleaner.
@testwithenv({"SOMETHING","ELSE"})
def test_foo_ok():
foo()
@testwithenv({"SOMETHING","BAD"})
def test_foo_bad():
with pytest.raises(Exception) as excinfo:
foo()
assert str(excinfo.value) == "BAM"