I've been running tests for aws sam lambda functions using pytest inside a docker container. This works, however I notice pytest runs all tests twice. I have setup a simplified example here.
I build and invoke the container by running:
sam build -t template_pytest.yaml && sam local invoke -e test_lambda.py
which results in the following output:
Invoking Container created from dockerpytestinteraction:latest
Building image.................
Using local image: dockerpytestinteraction:rapid-x86_64.
START RequestId: b265e3b7-73c9-410d-a66c-c7e609fda97d Version: $LATEST
============================= test session starts ==============================
platform linux -- Python 3.11.6, pytest-7.4.4, pluggy-1.3.0
rootdir: /var/task
collected 1 item
test_lambda.py . [100%]
============================== 1 passed in 0.03s ===============================
02 Jan 2024 22:08:48,347 [ERROR] (rapid) Init failed error=Runtime exited without providing a reason InvokeID=
============================= test session starts ==============================
platform linux -- Python 3.11.6, pytest-7.4.4, pluggy-1.3.0
rootdir: /var/task
collected 1 item
test_lambda.py . [100%]
============================== 1 passed in 0.02s ===============================
END RequestId: 22600007-3ac4-4b48-80a4-fe11d1592f4b
REPORT RequestId: 22600007-3ac4-4b48-80a4-fe11d1592f4b Init Duration: 1.11 ms Duration: 1946.25 ms Billed Duration: 1947 ms Memory Size: 10240 MB Max Memory Used: 10240 MB
I've tried eliminating as many variables as possible by creating the simplest scenario to reproduce the issue I can think of. I am expecting pytest to run a single time within Docker.
It is in your Dockerfile ENTRYPOINT which is run on every build and then you are running it locally. You can prevent this by removing the ENTRYPOINT from pytestDockerfile - the AWS parent image already has one.
Effectively what is happening is you are setting your ENTRYPOINT in pytestDockerfile to:
So now anything passed via -e will be run as an argument to ENTRYPOINT.
Removing ENTRYPOINT will cease this behavior, CMD can be overridden so it should not execute twice, if it does simply remove the CMD from Dockerfile. Since your ENTRYPOINT is no longer pytest remember to pass the CMD the parent image is expecting which is "test_lambda.handler" not test_lambda.py
This pytestDockerfile should work.
You can find out more on how to setup the Dockerfile at https://docs.aws.amazon.com/lambda/latest/dg/python-image.html#python-image-instructions