My company’s application uses test containers for multiple images, plus flyway to setup schemas, etc. Our test suite is robust but long running. So I’m looking for ways to speed up the test suite execution. This is primarily for devs running the test suite on our local machines, vs something for the CI/CD where the overall execution time is less annoying.
To clarify, our suite takes ~5mins to run, so it’s not like catastrophically bad. But I’m trying to cut that down.
One idea I have is related to the use of testcontainers. Starting the suite takes 45-60 secs, so eliminating this overhead will be very beneficial.
My thought is using local Docker containers for local development. Rather than creating the whole container from scratch when starting the suite, we could set everything up via Docker Compose or something like that, and use those containers for the test. This would be controlled by an environment variable, so this could be optionally turned on.
We’re using the @Testcontainers framework integration, and I don’t see any way to conditionally control the instantiation of testcontainers. I’m hoping there is some solution out there.
2
Answers
I recognize 2 questions in this one, I’ll try to answer both:
About Hybrid running:
As far as I know, TestContainers doesn’t support this out of the box.
You could however work around this by using Spring Profiles. Have 1 profile (for the build server), where the containers are started by TestContainers, and one where you setup the properties to connect with your prestarted containers.
About Speeding up tests:
I see you are using Flyway for migrations. If you use TestContainers (and an empty database), those scripts will run each time, which might be timeconsuming. You could commit a container into a new image with those data/migrations already completed. I described that in this answer: https://stackoverflow.com/a/72265528/2082699
If you manually control the container lifecycle, rather than using the
@Testcontainers
integration, this is possible. You can check if a service is already available on a known port and if not, you start a Testcontainers-based container instead and configure your SUT accordingly.Furthermore, as others have mentioned, you can use the
withReuse(true)
feature and also enable reuse in your~/.testcontainers.properties
:This will make containers survive the JVM process lifecycle.