I have a script go.py
, which needs to run unit tests (with nose) on several different modules, each with their own virtual envs.
How can I activate each virtual env prior to testing, and deactivate it after?
i.e. I want to do this (pseudo-code):
for fn in functions_to_test:
activate(path_to_env)
run_test(fn)
deactivate()
Inside a virtual env, there is ./bin/activate_this.py
This does what I want. So in go.py
I say
import os
activate_this_file = os.path.join(env_dir,'bin/deactivate_this.py')
execfile(activate_this_file, dict(__file__=activate_this_file))
I've currently got run_test()
working using
suite_x = TestLoader().loadTestsFromName(test_module + ":" + test_class)
r = run(suite = suite_x, argv = [sys.argv[0], "--verbosity=0", "-s"])
This is the part that I can't figure out.
What's the deactivation equivalent of env/bin/activate_this.py
?
Each module will be uploaded to AWS by go.py
as a lambda function. (Where 'lambda function' has a specific meaning in an AWS context, and is not related to lambda x:foo(x)
)
I want go.py
to run unit tests on each lambda function, inside their respective virtual env (since they'll be executed in those virtual envs once deployed to AWS). Each lambda function uses different libraries, hence they have different virtual envs.
The activate_this.py
script is not meant to be used to switch virtual environments in the middle of a computation. It is meant to be used ASAP at the start of your process and not be touched ever again. If you look at the content of the script you'll see that it does not take care to record anything for a future deactivation. Once the activate_this.py
script is done, what the state of the interpreter was before the script started is lost. Moreover the documentation also warns (with emphasis added):
Also, this cannot undo the activation of other environments, or modules that have been imported. You shouldn’t try to, for instance, activate an environment before a web request; you should activate one environment as early as possible, and not do it again in that process.
Instead of the approach you were hoping to use, I'd have the orchestrator spawn the python interpreter (with subprocess
) that is specific to the virtual environment that needs to be used and pass to it the test runner ("nosetests", presumably) with the arguments needed for it to find the tests it needs to run in that environment.