Our “Donor sign-up” functionality was finished and working a long time ago, several breaks ago, actually. As the page on testing states, if your code is working but you haven’t tested it, is it really working?.
Running pytest tests
from within savealife
reveals the ugly truth:
and looking at the traceback we see that a ValueError
was raised:
Right about now would be a good time to fix it.
If the error messages was formatted just a bit better it would make it more clear:
ValueError: Required parameter 'name' not set
Now it is much more clear that the NAME of the DynamoDB table was not set. And how are we setting it? Through an environment variable.
import json
import os
from unittest import mock
from chalice.test import Client
ENV = os.getenv("ENV", "dev")
first_name = os.getenv("WORKSHOP_NAME", "ivica") # replace with your own name of course
@mock.patch.dict(os.environ, {"TABLE_NAME": f"{first_name}-savealife-{ENV}"})
def test_donor_signup():
from app import app
json_payload = {
"first_name": "ivica",
"city": "Amsterdam",
"type": "A+",
"email": "ivica@server.com",
}
with Client(app) as client:
response = client.http.post(
"/donor/signup",
headers={"Content-Type": "application/json"},
body=json.dumps(json_payload),
)
assert response.status_code == 200
assert response.json_body.get("success")
We changed quite a bit in the test so let’s go through the changes one by one:
@mock.patch
line is where the first half of the magic happens: that is where we’re setting the value of the TABLE_NAME
variablefrom app import app
moved inside the function. We had to do it that way since
@mock.patch
must happen before the TABLE_NAME
environment variable is read in chalicelib/db.py
assert
statement was changed to expect a successful operationIt will work :)
Real DynamoDB table was used. Instead of emulating the cloud for our tests we embraced the cloud and used real resources. If you, for whatever reason, prefer to use local resources the possibility is there with LocalStack. Not every AWS service is supported but DynamoDB is supported quite well.
This workshop will not focus on setting up LocalStack or tests that use it. If you wish to do so you may need to:
docker-compose
to run LocalStack on your machinechalicelib/db.py
slightly so that the line boto3.resource("dynamodb").Table(TABLE_NAME)
becomes
boto3.resource("dynamodb", endpoint_url=LOCALSTACK_DYNAMO_ENDPOINT_HERE).Table(TABLE_NAME)