By: Cristian Greco
Back in 2016 I was working on a Java project, which enabled the sale of air time for a large-ish UK TV channel. It integrated with all sorts of infrastructure. Queues, databases, you name it.
Like any self respecting development team, we were hot on testing and TDD, so we weren’t about to just batch migrate millions of records from one database to another without having at least something in place to give us confidence it worked and something to point at if it didn’t.
To test against a real database, say PostgreSQL, you only really had 3 options:
- Download, install and setup PostgreSQL on your local machine. Start it before running the tests. Document it. Repeat for everyone in the team. Repeat in CI environment. “Upgrade PostgreSQL you say? 3 months.”
- Pray that some poor soul created an “in-memory” version of your database, which you can integrate as a library. Pray that the last commit to this project wasn’t 4 years ago. Pray that it works with your database driver. Pray that it still works when you deploy.
var postgresNotPostgres = Mockito.mock(PostgreSQLClient.class)
.
It was around this time that Docker was getting popular. A colleague of mine showed it to me and my mind was blown. I was able to run infrastructure from all these different vendors on my laptop, within seconds. No setup required, just one shell command.
We were running into more and more issues with option 2 as PostgresSQL kept changing, and we were growing tired of throwing GitHub issues into the abyss. It was at this time we found testcontainers-java. A library that leveraged the versatility of Docker, and integrated into our testing processes. You could once again run your unit tests with read dependencies with the “run” button in your IDE.
A couple years later I grew tired of writing boilerplate and found a NodeJS role, how exciting it was! No more types to hold me back as I wrote my 10 line microservices. But the testing situation was dire, it was the same as before I discovered Testcontainers. Everything was mocked, brittle, and gave a false sense of confidence. What could I do?
Today, development continues on testcontainers-node, and after more than 600 commits from 50+ authors over 5+ years, it has grown from 10 downloads per week in 2018, to over 150,000 downloads per week in 2023. Code coverage is over 90%, and the median time to close an issue is 3 days! (I’m not just closing them I promise).
(Downloads per week. NodeJS developers take their holidays seriously!)
Usage couldn’t be simpler. It’s basically a haiku:
import { GenericContainer } from "testcontainers" const container = new GenericContainer("<image>"); await container.start();
I love working on this project and engaging with the OSS community, and I am thrilled that I can now do this as a core maintainer of the project through AtomicJar. Some of the next steps coming up for testcontainers-node will be aligning the feature sets and documentation between the different versions of the Testcontainers libraries, to bring you a more consistent experience across languages. Just recently for example, we added the much used HttpWaitStrategy
and StartupCheckStrategy
into testcontainers-node.
Being a Mac user, testing the build on a Windows machine has been a pain of mine for years. Every couple of months I’ll dust off my 2014 “gaming” rig and boot Windows to get an idea whether the changes we’re making even work. Who would’ve known the majority of developers work on Windows? Therefore another exciting (for me) change will be adding a suite of Windows agents to our build pipelines, which by leveraging Testcontainers Cloud will allow us to test and gain confidence that the changes we make work for everyone.
All this and more! I am excited for what the future holds for testcontainers-node.
If you have any questions about Testcontainers for NodeJS, please reach out to our Slack workspace, or start a discussion in the GitHub project.
Thank you for being a part of the Testcontainers community!