Python unittest cannot access local environment variables in PyCharm

Viewed 713

This one really is stumping me. When I set an API key as an environment variable and then try to run a test with unittest that uses this API key, the test cannot access the API key. I don't want to set the environment variable in the test itself because the value is secret and I don't want it to be accidentally tracked by my VCS.

$ export API_KEY=hunter2
$ python -m unittest discover tests

    ERROR: setUpClass (tests_system.TestInit)

----------------------------------------------------------------------

Traceback (most recent call last):

  File "/home/travis/build/jamesbrunet/callhub-python-wrapper/callhub/auth.py", line 23, in __init__

    self.api_key = os.environ["API_KEY"]

  File "/home/travis/virtualenv/python3.5.6/lib/python3.5/os.py", line 725, in __getitem__

    raise KeyError(key) from None

KeyError: 'API_KEY'

The interesting thing is that if I just run a single test file with python test-file.py it executes successfully and can access the API key. I only get this issue if I use python -m unittest discover <directory of test file>. Unfortunately, I need to use the latter command to discover all the test files in the directory.

The docs for unittest don't reference environment variables so I'm a bit at a loss to what's going on here.

Edit: I did some additional testing on my local machine and the scope of this issue seems limited to running these commands in PyCharm and Travis. Both of those use virtual environments. Perhaps this is related to @AndrewAllaire's comment on this post?

1 Answers

I have not yet resolved this mystery with unittest discover, but in case you are a wary future traveller from google and a knight in shining armour did not appear to save the day, this janky workaround will do the trick:

python -m unittest tests.file_1
python -m unittest tests.file_2
python -m unittest tests.file_n

If using coveralls to monitor your test coverage, you can execute your tests like this and they will execute properly and show your combined code coverage:

  coverage run --parallel-mode --source=sourcedir -m unittest tests.file_1
  coverage run --parallel-mode --source=sourcedir -m unittest tests.file_2
  coverage run --parallel-mode --source=sourcedir -m unittest tests.file_n
  coverage combine

This isn't great, so I've got my fingers crossed we'll get a solution from someone who has more experience with python-unittest.

Related