chalice
chalice copied to clipboard
Environment variables producing errors during testing
Hello, firstly I'd like to thank you for Chalice ! It's really easy to use and it worked very well to develop my API.
I use environment variables from .chalice/config.json
in my app and it works fine for local and deployment.
But now that I want to write tests for my app, those environment variables produce errors.
I tried following the documentation about testing with environment variables (https://aws.github.io/chalice/topics/testing.html#environment-variables) but to no avail.
Here is the problematic code in question from tests/test_app.py
where 'dev' is the stage name with all environment variables.
from chalice.test import Client
from app import app
def test_myPath():
with Client(app, stage_name='dev') as client:
response = client.http.get('/myPath')
assert response.status_code == 200
Then when I run :
py.test tests/test_app.py
I get :
================================================================================================================= ERRORS =================================================================================================================
___________________________________________________________________________________________________ ERROR collecting tests/test_app.py ___________________________________________________________________________________________________
tests\test_app.py:5: in <module>
from app import app
app.py:21: in <module>
MY_URL = os.environ["MY_URL"]
C:\Python310\lib\os.py:679: in __getitem__
raise KeyError(key) from None
E KeyError: 'MY_URL'
I checked by printing print(os.environ)
from tests/test_app.py
and the environment variables from .chalice/config.json
aren't there.
I am running into this issue as well...
I discovered a few things by looking at the relevant test client code:
https://github.com/aws/chalice/blob/a87dd3fd30a441206e99cd1e05e826c1b30315d4/chalice/test.py#L34-L46
-
Any errors loading the config are silently ignored
-
The config file
.chalice/config.json
is loaded relative to theproject_dir
(e.g.runtime
), which defaults to the current directory. This means that if you're running your tests outside of that directory, the config file won't get loaded. You can work around this by:- Putting your
test_*.py
files in theruntime
directory, and runningpytest
from there (hack, not recommended) - Instantiating
Client(app, project_dir=runtime_dir)
, whereruntime_dir
is something likePath(__file__).parent.parent / "runtime"
- Putting your
-
The configuration is only used for
client.http
andclient.lambda_
. That means if you're readingos.environ
outside of@app.route
/@app.lambda_function
(or code they execute), the environment variables won't be set.
tests\test_app.py:5: in <module> from app import app app.py:21: in <module> MY_URL = os.environ["MY_URL"] C:\Python310\lib\os.py:679: in __getitem__ raise KeyError(key) from None E KeyError: 'MY_URL'
This looks like MY_URL
is a module-level variable, is that correct? I've run into similar issues; as it turns out, environment variables are only set in the lambda function's scope when using the test client (if you think about it, it makes sense: Before you can initialize the test client, you need to import the app
variable from the app
module so that module-level code will be evaluated, including global variables). If you move this module-level variable into the lambda function, it should work.
You probably figured it out already @Maxim-Durand. For me I had to do two things to get my tests working with my fake env vars:
- Set the Chalice test client's stage to
local
. I don't have that configured, but I needed something that was dev - In my conftest.py file. before I do
from app import app
, I set all the env vars for testing. My app loads secret manager at start up, so we did this so the import only triggers the mock secret manager instead of the real one