Testcontainers makes testing with Databases easy
Testcontainers makes testing code against a database ridiculously easy.
My current project has a requirement to interact with different database types. In the past this would have been a pain to test against; perhaps requiring some centrally managed databases that developers access. Even with local servers there are issues of state, resource usage and other factors that make writing reliable tests hard.
However, Testcontainers leverages containerization through Docker and take the pain away. Using a fairly fluent Java API, its possible to start a Docker container from a given image, wait for it to startup, allow you to interact with it, and dispose of it when you’re done. There are special APIs for a range of containerized services, including the JdbcContainer
which provides a nice interface for accessing databases hosted in containers.
On our project, this allowed for the creation of isolated, repeatable, automated tests which exercised the database code. These could be run by any developer at any time, without any central management to worry about. This was big efficiency improvement over the manual testing that happened before.
Using Testcontainers is quite straightforward.
Containers can be started can be started via a Junit4 Rule…
public class MyTest {
@Rule
public MySQLContainer mysql = new MySQLContainer();
@Test
public void test() {
String jdbcUrl = mysql.getJdbcUrl();
...
}
}
…or managed as resources…
public class MyTest {
@Test
public void test() {
try (MySQLContainer mysql = new MySQLContainer()) {
mysql.start();
String jdbcUrl = mysql.getJdbcUrl();
...
}
}
}
The latter is useful for integration with other test tools like JGiven for creating BDD-style acceptance tests, where the complexity of database management can be hidden away from the test code.
public class DatabaseGivenState extends Stage<DatabaseGivenState> {
@ProvidedStageStage
public MySQLContainer mysql;
@BeforeScenario
public void before() {
mysql = new MySQLContainer();
mysql.start();
}
@AfterScenario
public void after() {
mysql.stop();
}
}
However, don’t forget to include the JDBC drivers for your database on your class path, otherwise Testcontainers won’t be able to tell if the container has come up or not!