Test Containers
Robust Integration Testing
- Source Codegil-air-may/test-containers
- StackPython / FastAPI / TestContiainers / GitHub Actions / Docker
I've put together a small project to show how to set up Testcontainers. This is an interesting topic because many teams struggle with improving code quality. Hopefully, this example can enhance your testing processes.
Checkout the tests/__init__.py file. It contains the special logic to spin up infrastructure containers straight from your codebase.
from testcontainers.mysql import MySqlContainerfrom testcontainers.redis import RedisContainerimport sqlalchemyfrom config import connectionsfrom scripts.database import seed_utilsfrom utils import execute_non_queryimport jsonmysql = MySqlContainer("mysql:5.7.17", port=3306)mysql.start()connections["MYSQL"] = mysql.get_connection_url()engine = sqlalchemy.create_engine(mysql.get_connection_url())seed_commands = seed_utils.get_seed_commands()for statement in seed_commands.split(";"):execute_non_query(engine, statement)redis_container = RedisContainer().__enter__()redis_client = redis_container.get_client()redis_conn = redis_client.get_connection_kwargs()redis_client.set(1,json.dumps({"tab_id": 1,"table_number": 1,"is_paid": 0,"items": '[{"name": "chicken_salad", "amount": 1}]',"from_day": "2024-05-18","created_at": "2024-05-18T20:36:42",},),)connections["REDIS"]["host"] = redis_conn["host"]connections["REDIS"]["port"] = redis_conn["port"]
You can achieve the same behavior using a more elaborate docker-compose.yml. I've also included a GH actions pipeline that works well with this demo.
Just to linger on the topic, "automate everything" should be your mantra for testing. Think of your app as an experiment and build processes that ensure quality results. A solid test suite sets up experiments that give you valuable insights into your system.
Critical logic definitely needs unit tests for specific scenarios, and integration tests should mirror your production environment as closely as possible. This is where Testcontainers shine!