55- [ Run Pylint Tool Locally] ( #run-pylint-tool-locally )
66- [ Run Black Tool Locally] ( #run-black-tool-locally )
77- [ Run mypy Tool Locally] ( #run-mypy-tool-locally )
8- - [ Run Unit Test] ( #running -unit-test )
8+ - [ Run Unit Test Locally ] ( #run -unit-test-locally )
99- [ Code Coverage] ( #code-coverage )
10+ - [ Run Integration Test Locally] ( #run-integration-test-locally )
1011
1112## Get Started
1213
@@ -45,7 +46,7 @@ To run Pylint on a specific file, follow the pattern `pylint <path_to_file>/<nam
4546
4647Example:
4748``` shell
48- pylint src/writer_kafka .py
49+ pylint src/event_gate_lambda .py
4950```
5051
5152## Run Black Tool Locally
@@ -68,7 +69,7 @@ To run Black on a specific file, follow the pattern `black <path_to_file>/<name_
6869
6970Example:
7071``` shell
71- black src/writer_kafka.py
72+ black src/writers/ writer_kafka.py
7273```
7374
7475### Expected Output
@@ -100,39 +101,39 @@ To run mypy on a specific file, follow the pattern `mypy <path_to_file>/<name_of
100101
101102Example:
102103``` shell
103- mypy src/writer_kafka .py
104+ mypy src/handlers/handler_token .py
104105```
105106
106- ## Running Unit Test
107+ ## Run Unit Test Locally
107108
108109Unit tests are written using pytest. To run the tests, use the following command:
109110
110111``` shell
111- pytest tests/
112+ pytest tests/unit/
112113```
113114
114- This will execute all tests located in the tests directory.
115+ This will execute all unit tests located in the tests/unit/ directory.
115116
116117### Focused / Selective Test Runs
117118Run a single test file:
118119``` shell
119- pytest tests/test_writer_kafka.py -q
120+ pytest tests/unit/writers/ test_writer_kafka.py
120121```
121122Filter by keyword expression:
122123``` shell
123- pytest -k kafka -q
124+ pytest -k kafka
124125```
125126Run a single test function (node id):
126127``` shell
127- pytest tests/test_event_gate_lambda .py::test_post_multiple_writer_failures -q
128+ pytest tests/unit/writers/test_writer_eventbridge .py::test_write_success
128129```
129130
130131## Code Coverage
131132
132133Code coverage is collected using the pytest-cov coverage tool. To run the tests and collect coverage information, use the following command:
133134
134135``` shell
135- pytest --cov=. -v tests/ --cov-fail-under=80 --cov-report=term-missing
136+ pytest --cov=. -v tests/unit/ --cov-fail-under=80 --cov-report=html
136137```
137138
138139This will execute all tests in the tests directory and generate a code coverage report with missing line details and enforce a minimum 80% threshold.
@@ -141,3 +142,63 @@ Open the HTML coverage report:
141142``` shell
142143open htmlcov/index.html
143144```
145+
146+ ## Run Integration Test Locally
147+
148+ Integration tests validate EventGate against real service dependencies using testcontainers-python.
149+
150+ ### Integration Test Approach
151+
152+ EventGate uses a ** direct invocation approach** for integration testing:
153+ - ** Lambda handler is called directly** in Python (not run in a container)
154+ - ** External dependencies run in Docker containers** : Kafka, PostgreSQL, LocalStack (EventBridge)
155+ - ** Mock JWT provider runs in-process** as a background thread (no container)
156+ - Test configuration is dynamically generated and injected via environment variables
157+
158+ ### Prerequisites
159+ - Docker running (Docker Desktop on macOS/Windows, or Docker Engine on Linux)
160+ - Python 3.13 with dependencies installed
161+
162+ ### Run Integration Tests
163+
164+ Containers start and stop automatically:
165+ ``` shell
166+ pytest tests/integration/ -v
167+ ```
168+
169+ With detailed logging:
170+ ``` shell
171+ pytest tests/integration/ -v --log-cli-level=INFO
172+ ```
173+
174+ ### Run Specific Integration Tests
175+
176+ Run a single test file:
177+ ``` shell
178+ pytest tests/integration/test_health_endpoint.py -v
179+ ```
180+
181+ Run a specific test function:
182+ ``` shell
183+ pytest tests/integration/test_topics_endpoint.py::TestPostEventEndpoint::test_post_event_with_valid_token_returns_202 -v
184+ ```
185+
186+ ### Troubleshooting
187+
188+ If containers fail to start, check Docker is running:
189+ ``` shell
190+ docker info
191+ ```
192+
193+ If image pulls fail with TLS or timeout errors, pre-pull the required images manually:
194+ ``` shell
195+ docker pull testcontainers/ryuk:0.8.1
196+ docker pull postgres:16
197+ docker pull confluentinc/cp-kafka:7.6.0
198+ docker pull localstack/localstack:latest
199+ ```
200+
201+ View container logs in pytest output by increasing log level:
202+ ``` shell
203+ pytest tests/integration/ -v --log-cli-level=DEBUG
204+ ```
0 commit comments