Exploring Testcontainers: My Experience

Exploring Testcontainers: My Experience

Replicating your production environment during development and testing is extremely essential in software development. Gone are the days when in-memory databases like H2 were the go-to when it came to testing. Today, innovative tools like Testcontainers have come into the picture. With Testcontainers, tests are now simplified by harnessing the power of Docker, allowing you to effortlessly launch lightweight resources, and to test any module as long as it can be containerized. The introduction of Testcontainers has made it remarkably easy to mirror your production environment tools during testing.

What is Testcontainers?

The official Testcontainers website basically describes Testcontainers as “test dependencies as code”. All that is required is to define the required test dependencies as code and run the tests. The specified docker containers will automatically be created and deleted after running the tests, whether the tests failed or were successful. Convenient, isn’t it?

Interestingly, Testcontainers came into inception in 2015, shortly after Docker was created. It originally supported Java but, today, it supports all the major programming languages including Python, NodeJS, .NET, Go, and Ruby. Testcontainers offer a wide array of modules, covering everything from databases to message brokers, web servers to search engines, and many more.

It has numerous benefits. Some of these include:

  • Consistency in environments: As mentioned earlier in terms of replicating production environments, Testcontainers ensures that test environments closely resemble that of production. This reduces the likelihood of unexpected issues.

  • Ease of setup: It simplifies the process of setting up resources for testing, you just need to define your test dependencies.

  • Portability and easy cleanup: After all the tests are executed, Testcontainers handles the clean-up and removal of container resources.

Personally, I have used Testcontainers to spin up databases, both SQL and NoSQL, for testing. Testing applications, especially the data access layer, with an in-memory database does not guarantee that they will work the same way as in your production databases. This is a notable downside of using in-memory options because they can give a false sense of security that your application works in testing, hence it will work smoothly in production.

I can confidently say that using Testcontainers has transformed my testing experience, making it more bearable, because it is user-friendly and it does not take much to get started - all you need is a Docker environment, whether locally or in CI (Continuous Integration) environments. In a recent project with my team, we used Testcontainers to spin up a MongoDB container and run our integration and end-to-end tests against it. The process was so seamless and there was no need to think about the “what-ifs”.

In my experience, one of the best practices to consider when using Testcontainers is the reusability of its resources. You can reuse the docker containers across multiple tests, which would save you some execution time.

I know I have been going on about Testcontainers and its superpowers, but, just like any other technology, it has some pitfalls. One of the downsides of Testcontainers is that it can be resource-intensive. Since Testcontainers utilizes docker, it can consume a fair amount of machine resources. However, despite the disadvantages, the merits of using Testcontainers outweigh the pitfalls.

Testcontainers has become an industry standard and huge corporations such as Spotify, Uber, JetBrains, and Netflix have adopted its usage in their development process. It has a huge and active community, hence they are plethora of resources out there to get you started with it. However, I highly recommend that you start by visiting the official testcontainers website [https://testcontainers.com] before jumping on other resources.

Overall, Testcontainers allows teams to ship code with confidence because it enables developers to run tests with real dependencies and reduces the burden of cleaning up after tests, making it easier for developers to focus on other aspects of development. I strongly encourage you to start using Testcontainers, if you haven’t already, and let me know what you think.