testcontainers-java
Testcontainers is a Java library that supports JUnit tests, providing lightweight, throwaway instances of common databases, Selenium web browsers, or anything else that can run in a Docker container.
Top Related Projects
✅ The 5th major version of the programmer-friendly testing framework for Java and the JVM
Most popular Mocking framework for unit tests written in Java
Java DSL for easy testing of REST services
A tool for mocking HTTP services
Cucumber for the JVM
Quick Overview
Testcontainers is a Java library that supports JUnit tests, providing lightweight, throwaway instances of common databases, Selenium web browsers, or anything else that can run in a Docker container. It facilitates the creation of integration tests by allowing developers to use real dependencies instead of mocks, ensuring more reliable and realistic test scenarios.
Pros
- Simplifies integration testing by providing easy-to-use, disposable containers
- Supports a wide range of databases and services out of the box
- Integrates seamlessly with popular testing frameworks like JUnit and TestNG
- Improves test reliability by using real dependencies instead of mocks
Cons
- Requires Docker to be installed and running on the test machine
- Can potentially slow down test execution compared to using mocks
- May consume more system resources due to running actual containers
- Learning curve for developers new to container-based testing
Code Examples
- Starting a PostgreSQL database container:
@Testcontainers
class PostgreSQLTest {
@Container
private static final PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:13");
@Test
void testPostgresConnection() {
try (Connection conn = DriverManager.getConnection(postgres.getJdbcUrl(), postgres.getUsername(), postgres.getPassword())) {
// Perform database operations
}
}
}
- Using a custom Dockerfile:
@Testcontainers
class CustomDockerfileTest {
@Container
private static final GenericContainer<?> customContainer = new GenericContainer<>(
new ImageFromDockerfile()
.withDockerfile(Paths.get("./Dockerfile"))
);
@Test
void testCustomContainer() {
// Test using the custom container
}
}
- Running a web browser for Selenium tests:
@Testcontainers
class SeleniumTest {
@Container
private static final BrowserWebDriverContainer<?> chrome = new BrowserWebDriverContainer<>()
.withCapabilities(new ChromeOptions());
@Test
void testSelenium() {
RemoteWebDriver driver = chrome.getWebDriver();
driver.get("https://example.com");
// Perform Selenium tests
}
}
Getting Started
To use Testcontainers in your project, add the following dependency to your pom.xml
(for Maven):
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>1.17.3</version>
<scope>test</scope>
</dependency>
For Gradle, add this to your build.gradle
:
testImplementation 'org.testcontainers:testcontainers:1.17.3'
Make sure you have Docker installed and running on your machine. Then, you can start using Testcontainers in your test classes by adding the @Testcontainers
annotation and declaring container instances with the @Container
annotation.
Competitor Comparisons
✅ The 5th major version of the programmer-friendly testing framework for Java and the JVM
Pros of JUnit5
- Comprehensive testing framework with extensive features for Java developers
- Excellent integration with IDEs and build tools
- Supports parallel test execution out of the box
Cons of JUnit5
- Limited scope for testing external dependencies and services
- Requires additional setup for complex integration tests involving databases or external systems
Code Comparison
JUnit5:
@Test
void testExample() {
assertEquals(2, 1 + 1);
}
Testcontainers:
@Container
PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:14");
@Test
void testWithPostgres() {
// Use postgres.getJdbcUrl() to connect to the database
}
Summary
JUnit5 is a powerful testing framework for Java applications, offering a wide range of features for unit and integration testing. It excels in providing a robust foundation for writing and executing tests, with strong IDE and build tool support.
Testcontainers, on the other hand, focuses on simplifying integration testing by providing lightweight, throwaway instances of databases, message brokers, and other services. It complements testing frameworks like JUnit5 by addressing the challenges of testing with external dependencies.
While JUnit5 is more general-purpose and suitable for various testing scenarios, Testcontainers shines in situations where tests require interaction with real services or databases. The combination of both tools can lead to a comprehensive testing strategy for Java applications.
Most popular Mocking framework for unit tests written in Java
Pros of Mockito
- Lightweight and easy to set up, requiring minimal configuration
- Focuses on mocking objects, making it ideal for unit testing
- Extensive API for verifying method calls and stubbing return values
Cons of Mockito
- Limited to mocking Java objects, not suitable for integration testing
- Cannot simulate complex external dependencies like databases or APIs
- Mocks may not accurately represent real-world behavior in all scenarios
Code Comparison
Mockito:
@Test
public void testUserService() {
UserRepository mockRepo = mock(UserRepository.class);
when(mockRepo.findById(1L)).thenReturn(new User("John"));
UserService service = new UserService(mockRepo);
assertEquals("John", service.getUserName(1L));
}
Testcontainers:
@Container
PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:13");
@Test
public void testUserService() {
UserRepository repo = new UserRepository(postgres.getJdbcUrl());
UserService service = new UserService(repo);
assertEquals("John", service.getUserName(1L));
}
The Mockito example shows mocking a repository, while Testcontainers spins up a real PostgreSQL database for testing. Mockito is simpler but less realistic, whereas Testcontainers provides a more accurate testing environment at the cost of increased complexity and resource usage.
Java DSL for easy testing of REST services
Pros of Rest Assured
- Specifically designed for testing RESTful APIs, providing a domain-specific language for HTTP requests
- Offers built-in JSON and XML parsing capabilities
- Integrates well with existing test frameworks like JUnit and TestNG
Cons of Rest Assured
- Limited to API testing, while Testcontainers provides a broader testing scope
- Lacks containerization features for creating isolated test environments
- May require additional setup for complex scenarios involving database or external service dependencies
Code Comparison
Rest Assured:
given()
.param("key", "value")
.when()
.get("/api/resource")
.then()
.statusCode(200)
.body("field", equalTo("expected"));
Testcontainers:
@Container
PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:13");
@Test
void testWithPostgres() {
String jdbcUrl = postgres.getJdbcUrl();
// Use jdbcUrl to connect and perform database operations
}
While Rest Assured focuses on API request/response testing, Testcontainers enables testing with containerized dependencies. Rest Assured is more suitable for pure API testing, whereas Testcontainers shines in scenarios requiring isolated environments for databases, message queues, or other services. The choice between them depends on the specific testing needs of the project.
A tool for mocking HTTP services
Pros of WireMock
- Lightweight and easy to set up for mocking HTTP services
- Extensive request matching capabilities and response stubbing
- Can be run as a standalone process or embedded in tests
Cons of WireMock
- Limited to HTTP/HTTPS service mocking
- Less flexible for complex scenarios involving multiple services or databases
- May require more manual setup for each test case
Code Comparison
WireMock:
stubFor(get(urlEqualTo("/api/users"))
.willReturn(aResponse()
.withStatus(200)
.withHeader("Content-Type", "application/json")
.withBody("{\"users\": []}")));
Testcontainers:
@Container
PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:13");
@Test
void testWithPostgres() {
try (Connection conn = DriverManager.getConnection(postgres.getJdbcUrl(), postgres.getUsername(), postgres.getPassword())) {
// Run your test using the PostgreSQL container
}
}
WireMock excels at mocking HTTP services with a simple API, while Testcontainers provides a more comprehensive solution for testing with various types of dependencies, including databases and other services. WireMock is more focused and easier to use for HTTP mocking, but Testcontainers offers greater flexibility and coverage for complex testing scenarios involving multiple services or databases.
Cucumber for the JVM
Pros of Cucumber JVM
- Enables behavior-driven development (BDD) with human-readable test scenarios
- Supports multiple programming languages beyond Java
- Facilitates collaboration between technical and non-technical team members
Cons of Cucumber JVM
- Steeper learning curve for writing and maintaining Gherkin syntax
- Can lead to test duplication and maintenance overhead if not managed properly
- Less focused on container-based testing compared to Testcontainers
Code Comparison
Cucumber JVM example:
@Given("^I have (\\d+) cucumbers in my belly$")
public void i_have_cucumbers_in_my_belly(int cukes) {
belly.eat(cukes);
}
Testcontainers example:
@Test
public void testWithPostgres() {
try (PostgreSQLContainer postgres = new PostgreSQLContainer<>()) {
postgres.start();
// Use postgres for testing
}
}
While Cucumber JVM focuses on defining behavior in natural language, Testcontainers provides a more straightforward approach to managing containerized dependencies for testing. Cucumber JVM is better suited for BDD and collaboration, while Testcontainers excels in container-based integration testing.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Testcontainers
Testcontainers is a Java library that supports JUnit tests, providing lightweight, throwaway instances of common databases, Selenium web browsers, or anything else that can run in a Docker container.
Read the documentation here
License
See LICENSE.
Copyright
Copyright (c) 2015 - 2021 Richard North and other authors.
MS SQL Server module is (c) 2017 - 2021 G DATA Software AG and other authors.
Hashicorp Vault module is (c) 2017 - 2021 Capital One Services, LLC and other authors.
See contributors for all contributors.
Top Related Projects
✅ The 5th major version of the programmer-friendly testing framework for Java and the JVM
Most popular Mocking framework for unit tests written in Java
Java DSL for easy testing of REST services
A tool for mocking HTTP services
Cucumber for the JVM
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot