Time flies when you’re in a great company, and because the Testcontainers community is the greatest ever, things snuck up on us!
First of all, we’d like to sincerely thank every single one of you for being a part of the community making integration testing better! All contributions, whether it’s code, documentation updates, finding and reporting tricky issues, or spreading the word about how you use Testcontainers help to move the project further, and we’re truly grateful for your trust, recognition, and support!
Together we make Testcontainers the best it can be and we’re honoured to share today’s milestone with you!
Our boy is growing so fast!
🎉🎉🎉 Today is Testcontainers’ 7th birthday, as its Open Source journey started from the first commit of Richard on the 12th April 2015! “It will only take a few months and then it will be finished” he thought back then, and, 7 years later, it becomes harder and harder to find a company where Testcontainers isn’t used, the project is being actively developed, more language versions are being released, and there is so much more ahead!
Open source projects don’t become successful by trying to be popular. Open source projects become successful by solving a known and widespread problem, putting emphasis on quality of code, ease of use, and accessibility of documentation.
Testcontainers isn’t an exception, its success is the result of solving the challenges of integration testing for many developers, and building a great community that never misses a chance to recommend the library to their friends and colleagues.
Today, Testcontainers is still growing, and it is growing FAST.
Remember Ryuk, our fancy named watchdog container that is being used by most of the Testcontainers-powered builds? (while we are at it… don’t disable Ryuk! 😛) We had a look at its Docker Hub downloads, and apparently you folks are running a lot of builds! 😃 It’s been downloaded more than 55 million times since we published it two years ago. But how is it growing today? Just last week it had more than 1 million downloads. Per week. That’s a few builds per second. We are all engineers here and know how caching works, so the real number is unknown, but hey! We don’t mind even if it is 1M/week 🤓.
No surprise that Testcontainers Java implementation remains the most popular one, but how popular is it? Well, this popular:
And, before you say “this +50% in March must be some ephemeral CIs downloading it over and over”, have a look at this chart of unique IPs (hint: public CIs have a fixed range of IPs):
We are honored to serve so many amazing developers across the world and are looking forward to letting even more developers enjoy easy and fast integration testing!
Also, besides the growing raw download numbers Testcontainers is getting excellent feedback from thought leadership giants in the industry. The latest release of the Technology Radar by Thoughtworks puts Testcontainers into the great company of technologies you should adopt.
And since we couldn’t say it better ourselves, here’s what they think of it:
It’s a useful default option for creating a reliable environment for running tests.
<…>
Our teams have consistently found this library of programmable, lightweight and disposable containers to make functional tests more reliable.
https://www.thoughtworks.com/en-us/radar/languages-and-frameworks/testcontainers
We decided to celebrate this growth and fantastic feedback with a fresh release that brings a lot of exciting stuff. But before we talk about the release, please allow us to talk about the most noticeable change in Testcontainers… ever.
New Look, Who Dis?
Not many brand designs survive multiple years, and Testcontainers’ design has never changed… since the inception 7 years ago… until today. Don’t worry, the cube is here to stay, we love it at least as much as you do 🙂 But, now that the Testcontainers team is beyond just a few developers spending their evenings writing code, we are excited to present you with the same Testcontainers but a completely new, polished look!
As you can see, the cube received better, fresh colors. And guess what? We managed to fix a bug… in the design! This is fascinating how we received more than 5,000 issue reports on GitHub, and none of them were talking about the wrong perspective of the cube! Anyway, it’s not unusual for us to fix bugs even before you, our dear users, spot them, and our amazing designers picked up this habit, too!
It works well anywhere, be it our website, docs (our next target for polishing ;)), or… stickers and other swag *wink* *wink*.
The new look is modern and exciting, but under the hood Testcontainers remains your reliable solution for integration tests. Here’s what is coming in the release today.
Testcontainers 1.17.0
More than 50 releases and thousands of commits later we’re happy to present the testcontainers-java 1.17.0 release, which comes with many exciting features. At this stage, every Testcontainers release is the result of efforts by the whole community: maintainers, contributors, database and other software vendors, and more!
We were happy to have Elastic, Couchbase, HiveMQ, Neo4J, CockroachDB, and others contributing to this release and making their databases easier to test with Testcontainers.
And, while we are heads down building Testcontainers Cloud and making it publicly available, we of course got some time to improve the core of the library and even did some serious optimizations here and there!
New HiveMQ module
We are very happy to welcome the HiveMQ module, which was previously published separately, into the main repository, allowing you to test your HiveMQ applications with ease and reliability. We enjoyed collaborating with them, and it led to general improvements along the way.
Using HiveMQ as part of your integration tests is as simple as a couple of lines of Java code:
var hivemq = new HiveMQContainer("hivemq/hivemq-ce:2021.3"); hivemq.start(); … var client = Mqtt5Client.builder() .serverPort(hivemq.getMqttPort()) .serverHost(hivemq.getHost()) .buildBlocking(); client.connect();
Having a module is incredibly important as it helps with both the best practices from the integration tests point of view and from the HiveMQ side offering straightforward configuration for all the features and capabilities of this MQTT broker.
One can even test extensions and the module will take care of packing them automatically:
var hiveMQExtension = HiveMQExtension.builder() .id("extension-1") .name("my-extension") .version("1.0") .mainClass(MyExtension.class) .build(); var hivemq = new HiveMQContainer("hivemq/hivemq-ce:2021.3") .withExtension(hiveMQExtension);
Check out the docs to learn more about its many features!
Performance optimizations to Ruyk
We’re always working on making tests faster and more lightweight! In this release we’re happy to show a smarter and lazier implementation that takes into account the details of your test run.
If you’re running containers in the reusable mode which removes the need to cleanup based on the lifecycle of your tests, Testcontainers won’t wait for Ruyk reporting for duty and it’ll make startup almost a full second faster.
If it doesn’t sound super impressive to you, it’s because the startup has already been pretty great. But, with reusable containers every hundred milliseconds counts, and we have saved quite a few of them. Just look at it yourself:
Before: Total time: 1.13763 s # Now, when Ryuk starts on demand only when something is registered for cleanup: Total time: 0.485227 s
That’s almost 60% faster!
But what it means for you? It means that you can have PostgreSQL or MongoDB fully ready for testing in ~900ms from the moment you press “run tests”, or Apache Kafka in 2.5 seconds.
For those of you who love screenshots of IDEs (we do! Unless that’s an issue report on GitHub 😅), here is an example of an end-to-end test that uses MySQL that finishes in less than two seconds, out of which only ~650ms were spent starting MySQL with Testcontainers, and the rest is the MySQL JDBC client initialization and executing the test query:
Even better automatic resources cleanup
Many Testcontainers users love the convenience Ryuk brings to Testcontainers: No matter what you do in your integration tests, Ryuk has got you covered and will clean up all Docker resources created by Testcontainers after your test run is finished.
But some users operate Testcontainers in environments which do not support our container-based Ryuk implementation. One of them is Podman – a popular alternative to Docker that provides Docker API compatibility but, due to its implementation details, does not support Ryuk yet.
Coming with this release, Testcontainers will use a JVM based resource-cleanup implementation when containerized Ryuk is disabled.
While the JVM based implementation might not be as robust as the Ryuk container based implementation in all circumstances, it is aimed at improving reliability and repeatability of your tests and that’s why we’re here after all!
Other improvements
As always, we included a number of quality-of-life improvements:
- an ability to create files inside containers from a
String
or bytes - a number of deprecations so you won’t need to argue with your colleagues whether you should be using
getHost()
orgetContainerIpAddress()
- Dropped OkHttp transport, so we no longer shade docker-java transports, but instead only depend on
docker-java-transport-zerodep
- updated
docker-java
to 3.2.13 which fixed a few issues (Good bye “group id '5361194532 is too big ( > 2097151 )
”!) - Removed the
INCUBATING
label from the CockroachDB module - Elasticsearch module now works OOTB with Elasticsearch 8, which is secure by default
- Added tracing headers to the Docker API calls we are making as our first step towards Test Observability
As always there are other improvements, bug-fixes, and other useful changes that you can marvel at in the release description. Otherwise, the binaries are, as always, in Maven Central. Update your projects and enjoy better tests!