Sharing containers
Typically a suite of tests are comprised of multiple test classes to better organize different test scenarios. Consider the following test classes:
@MicroShedTest
public class MyTestA {
@Container
public static ApplicationContainer app = new ApplicationContainer()
.withAppContextRoot("/myservice");
// ...
}
@MicroShedTest
public class MyTestB {
@Container
public static ApplicationContainer app = new ApplicationContainer()
.withAppContextRoot("/myservice");
// ...
}
Since each test class has its own @Container annotated field, a new container will be started for each class. Having a fresh start of
a container on each test class may be intended behavior, but in many cases it is not necessary and adds a significant amount of time spent
starting/stopping containers before/after each test class.
The @SharedContainerConfig annotation
If multiple test classes can share the same container instances, they can offload their @Container annotated fields to a separate class
that implements SharedContainerConfiguration like so:
public class AppContainerConfig implements SharedContainerConfiguration {
@Container
public static ApplicationContainer app = new ApplicationContainer()
.withAppContextRoot("/myservice");
}
@MicroShedTest
@SharedContainerConfig(AppContainerConfig.class)
public class MyTestA {
// ...
}
@MicroShedTest
@SharedContainerConfig(AppContainerConfig.class)
public class MyTestB {
// ...
}
By default, shared containers will be started in parallel before the first test class that uses the @SharedContainerConfig starts. The
containers will be stopped automatically when all tests have completed.
Customizing the start process for SharedContainerConfiguration
By default, shared containers are stared in parallel in order to save time. However, this may not be possible in all instances. For example, containers may have strict start order dependencies. There are two primary approaches to customizing the start process.
Using Testcontainer dependsOn API
The Testcontainers API has a built-in dependency mechanism which can be used to declare dependencies among multiple containers.
@Container
public static GenericContainer<?> mongo = new GenericContainer<>("mongo:3.4")
.withNetworkAliases("testmongo");
@Container
public static ApplicationContainer app = new ApplicationContainer()
.dependsOn(mongo)
// ...
Since the app container dependsOn the mongo container, when MicroShed Testing starts the containers, the Testcontainers library will
ensure that the mongo container starts sucessfully before the app container start is initiated.
Fully custom start process
In some cases the start procedure may need to be customized beyond simple start ordering. For these cases, the SharedContainerConfiguration.startContainers() method can be overridden. For example:
public class AppContainerConfig implements SharedContainerConfiguration {
@Container
public static GenericContainer<?> mongo = new GenericContainer<>("mongo:3.4")
// ...
@Container
public static ApplicationContainer app = new ApplicationContainer()
// ...
@Override
public void startContainers() {
mongo.start();
app.start();
}
}