Introduction
In modern software development, it is crucial to write robust and reliable tests to ensure the quality of your applications. One essential aspect of testing is dealing with dependencies, such as databases or external services. Testcontainers is an excellent Java library that provides lightweight, disposable containers for running dependencies during tests. In this tutorial, we will explore how to use Testcontainers to set up a GenericContainer and a PostgreSQL container for your Java tests.
What is TestContainers ?
Testcontainers is an open source framework for running lightweight instances of Container Images as part of your Tests.
By utilizing Testcontainers, the need to set up complex environments to test services becomes obsolete. You can define your test dependencies as code, effortlessly execute your tests, and watch as containers are dynamically created and disposed of. With Testcontainers’ broad language and testing framework support, all that’s required is Docker to streamline your testing process.
Setting up Testcontainers
To get started with Testcontainers, you need to include the testcontainers library as a dependency in your Java project.
Firstly, we recommend including the Bill of Materials to hook a specific version of TestContainers for all your libraries:
<dependencyManagement> <dependencies> <dependency> <groupId>org.testcontainers</groupId> <artifactId>testcontainers-bom</artifactId> <version>1.20.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
Then, include the core dependency as well in your pom.xml:
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<scope>test</scope>
</dependency>
Additionally, include JUnit Test library to annotate your Tests. Check the following article to learn more about JUnit configuration: JUnit 5 Made Easy
Example: GenericContainer
The GenericContainer class allows you to start a Docker container with a specified image. Let’s start with a simple example of running an httpd web server using Testcontainers.
@Testcontainers
public class GenericContainerTest {
private static final int HTTP_PORT = 80;
@Container
private static final GenericContainer<?> container = new GenericContainer<>("httpd:latest")
.withExposedPorts(HTTP_PORT);
@Test
public void testHttpdServer() throws Exception {
// Get the host and port of the running container
String host = container.getHost();
int port = container.getMappedPort(HTTP_PORT);
// Create the URL for the HTTP request
URL url = new URL("http://" + host + ":" + port + "/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// Send an HTTP GET request
connection.setRequestMethod("GET");
connection.connect();
// Verify the response code is 200 (OK)
int responseCode = connection.getResponseCode();
System.out.println("Response code:"+responseCode);
Assertions.assertEquals(200, responseCode);
}
}
In this code snippet:
- The
@Testcontainersannotation enables Testcontainers support for the test class. - The
@Containerannotation defines a static fieldcontainerthat represents the GenericContainer instance. - The
GenericContaineris created with the image name “httpd:latest” and exposes the HTTP_PORT. - Then, we open an HTTP connection and send an HTTP GET request to the container.
- Finally, we verify the response code using
Assertions.assertEquals()to ensure it is 200 (OK).
This code demonstrates the usage of Testcontainers to start a GenericContainer running an Apache HTTP server, perform an HTTP request, and verify the response code.

Another TestExample: A PostgreSQL Container
Besides the GenericContainer there are several pre-built API to Test Services such as Databases, Brokers or Identity Servers. As an example, we will show here how to kickstart and Test a PostgreSQL container with PostgreSQLContainer.
Firstly, we need to add to our project the dependency for PostgreSQL TestContainer and a suitable Driver for PostgreSQL:
<dependency> <groupId>org.testcontainers</groupId> <artifactId>postgresql</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>42.3.1</version> <scope>test</scope> </dependency>
Finally, here is our JUnit 5 Test which starts a PostgreSQL Database and executes a SELECT on the current Data when the Container is running:
@Testcontainers
public class PostgreSQLTest {
@Container
private static final PostgreSQLContainer<?> postgresContainer = new PostgreSQLContainer<>("postgres:latest");
private Connection connection;
@BeforeAll
public static void setUp() {
postgresContainer.start();
}
@BeforeEach
public void connectToDatabase() throws Exception {
String jdbcUrl = postgresContainer.getJdbcUrl();
String username = postgresContainer.getUsername();
String password = postgresContainer.getPassword();
connection = DriverManager.getConnection(jdbcUrl, username, password);
}
@AfterEach
public void closeConnection() throws Exception {
connection.close();
}
@Test
public void testCurrentDateNotNull() throws Exception {
// Execute a query to retrieve the current date from the database
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("SELECT CURRENT_DATE");
// Verify that the result set is not null
assertNotNull(resultSet);
// Move the cursor to the first row
resultSet.next();
// Retrieve the current date value from the result set
LocalDate currentDate = resultSet.getObject(1, LocalDate.class);
System.out.println("Date is " + currentDate);
// Verify that the current date is not null
assertNotNull(currentDate);
}
}
As you can see, the code is much leaner as we reference the org.testcontainers.containers.PostgreSQLContainer which provides details about the JDBC Connection so that we can run a simple Test with it.
Run the above Test in your IDE and verify that the current Data is not null:

Conclusion
In this tutorial, we explored how to use Testcontainers to set up a GenericContainer and a PostgreSQL container for your Java tests. We learned how to include Testcontainers as a dependency, start and stop containers, and perform tests using the containerized dependencies. Testcontainers is a powerful library that simplifies testing by providing disposable containers for your dependencies, enabling you to write more reliable and isolated tests.
By utilizing Testcontainers in your Java tests, you can ensure that your applications are thoroughly tested against real dependencies, leading to more robust and reliable software.
Source code for this article: https://github.com/fmarchioni/mastertheboss/tree/master/test/testcontainer