A Year (or more) in Review
(for slides and everything else)
@bsideup
For example:
"Tests which interact with external systems/dependencies"
"I use the term integrated test to mean any test whose result (pass or fail) depends on the correctness of the implementation of more than one piece of non-trivial behavior." - J.B. Rainsberger
"A test that will pass or fail based on the correctness of another system." - Spotify
For example:
GenericContainer redis =
new GenericContainer("redis:3.0.2")
.withExposedPorts(6379);
redis.start();
// test my stuff
redis.stop();
@whichrich
@ashleymcnamara
@Testcontainers
class TestContainersClassIT extends Specification {
@Shared
GenericContainer genericContainer =
new GenericContainer("postgres:latest")
.withExposedPorts(5432)
.withEnv([
POSTGRES_USER: "foo"
POSTGRES_PASSWORD: "secret"
])
}
// Set up a redis container
@ClassRule
public static GenericContainer redis =
new GenericContainer("redis:3.0.2")
.withExposedPorts(6379);
@Testcontainers
class SomeTest {
@Container
private MySQLContainer mySQLContainer = new MySQLContainer();
@Test
void someTestMethod() {
String url = mySQLContainer.getJdbcUrl();
// create a connection and run test as normal
}
}
@Test
public void testUsage() throws Exception {
try (KafkaContainer kafka = new KafkaContainer()) {
kafka.start();
testKafkaFunctionality(kafka.getBootstrapServers());
}
}
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers-bom</artifactId>
<version>{{latest_version}}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
new DockerComposeContainer(new File("src/test/resources/compose-test.yml"))
.withExposedService("redis_1", REDIS_PORT, Wait.forListeningPort())
.withExposedService("db_1", 3306, Wait.forLogMessage(".*ready for connections.*\\s", 1))
.withTailChildContainers(true);
GenericContainer container = new GenericContainer()
.withCommand("sleep", "3000")
.withCopyFileToContainer(
MountableFile.forClasspathResource(
"/mappable-resource/"),
containerPath);
Testcontainers.exposeHostPorts(localServerPort);
final String rootUrl =
String.format("http://host.testcontainers.internal:%d/", localServerPort);
You can see an example test that could
have been written for it (without using Testcontainers):
<!--codeinclude-->
[Pre-Testcontainers test code]
(../examples/junit5/redis/src/test/java/quickstart/RedisBackedCacheIntTestStep0.java)
block:RedisBackedCacheIntTestStep0
<!--/codeinclude-->
GenericContainer container = new GenericContainer()
.dependsOn(postgresContainer, kafkaContainer);
new GenericContainer<>(imageName)
.withImagePullPolicy(PullPolicy.alwaysPull())
AgeBasedPullPolicy oneHour = new AgeBasedPullPolicy(
Duration.of(1L, ChronoUnit.HOURS)
);
new GenericContainer<>(imageName)
.withImagePullPolicy(oneHour)
public DockerComposeContainer environment =
new DockerComposeContainer(new File("src/test/resources/compose-test.yml"))
.withExposedService("redis_1", REDIS_PORT)
.withExposedService("db_1", 3306);
Optional<ContainerState> result = environment.getContainerByServiceName("db_1");
private GenericContainer myContainer = new GenericContainer("myImage:42.23") {{
withExposedPorts(4711);
if (System.getenv().get("INSIDE_CI") == null) {
org.testcontainers.Testcontainers.exposeHostPorts(8080);
}
}};
val redisContainer = GenericContainer<Nothing>("redis:3-alpine")
.apply {
withExposedPorts(6379)
}
TODO: add Safe Harbor Statement here