0
# JUnit Integration
1
2
Seamless integration with JUnit 5 test framework providing automatic container lifecycle management through annotations and test conditions for Docker-enabled environments.
3
4
## Capabilities
5
6
### @Testcontainers Annotation
7
8
Class-level annotation enabling automatic container lifecycle management for all container fields annotated with @Container.
9
10
```java { .api }
11
/**
12
* Enables Testcontainers functionality for a test class
13
*/
14
@Testcontainers
15
public @interface Testcontainers {
16
/** Disable tests when Docker is not available */
17
boolean disabledWithoutDocker() default false;
18
19
/** Enable parallel execution of tests */
20
boolean parallel() default false;
21
}
22
```
23
24
**Usage Examples:**
25
26
```java
27
import org.testcontainers.junit.jupiter.Testcontainers;
28
import org.testcontainers.junit.jupiter.Container;
29
import org.testcontainers.containers.GenericContainer;
30
31
@Testcontainers
32
class MyIntegrationTest {
33
34
@Container
35
static GenericContainer<?> redis = new GenericContainer<>("redis:6-alpine")
36
.withExposedPorts(6379);
37
38
@Test
39
void testWithRedis() {
40
// Redis container is automatically started before this test
41
String host = redis.getHost();
42
Integer port = redis.getMappedPort(6379);
43
// ... test logic
44
}
45
}
46
```
47
48
### @Container Annotation
49
50
Field-level annotation marking container instances for automatic lifecycle management by the Testcontainers JUnit extension.
51
52
```java { .api }
53
/**
54
* Marks a container field for automatic lifecycle management
55
*/
56
@Container
57
public @interface Container {
58
}
59
```
60
61
**Static vs Instance Containers:**
62
63
```java
64
@Testcontainers
65
class ContainerLifecycleTest {
66
67
// Static containers are shared across all test methods
68
@Container
69
static GenericContainer<?> sharedPostgres = new GenericContainer<>("postgres:13")
70
.withExposedPorts(5432)
71
.withEnv("POSTGRES_PASSWORD", "test");
72
73
// Instance containers are created/destroyed for each test method
74
@Container
75
GenericContainer<?> perTestRedis = new GenericContainer<>("redis:6-alpine")
76
.withExposedPorts(6379);
77
78
@Test
79
void firstTest() {
80
// Both containers available
81
// sharedPostgres was started once for all tests
82
// perTestRedis started fresh for this test
83
}
84
85
@Test
86
void secondTest() {
87
// sharedPostgres is the same instance as firstTest
88
// perTestRedis is a new instance for this test
89
}
90
}
91
```
92
93
### @EnabledIfDockerAvailable Annotation
94
95
Conditional test annotation that enables tests only when Docker is available and accessible.
96
97
```java { .api }
98
/**
99
* Conditionally enables tests when Docker is available
100
*/
101
@EnabledIfDockerAvailable
102
public @interface EnabledIfDockerAvailable {
103
}
104
```
105
106
**Usage Examples:**
107
108
```java
109
import org.testcontainers.junit.jupiter.EnabledIfDockerAvailable;
110
111
@EnabledIfDockerAvailable
112
@Test
113
void testRequiringDocker() {
114
// This test only runs if Docker is available
115
try (GenericContainer<?> container = new GenericContainer<>("nginx:alpine")) {
116
container.start();
117
// ... test logic
118
}
119
}
120
121
@EnabledIfDockerAvailable
122
@Testcontainers
123
class DockerDependentTests {
124
// Entire test class only runs if Docker is available
125
126
@Container
127
static GenericContainer<?> nginx = new GenericContainer<>("nginx:alpine");
128
129
@Test
130
void test1() { /* ... */ }
131
132
@Test
133
void test2() { /* ... */ }
134
}
135
```
136
137
### Combined Usage Patterns
138
139
Integration of annotations for robust test setups with proper error handling and conditional execution.
140
141
**Usage Examples:**
142
143
```java
144
import org.testcontainers.junit.jupiter.*;
145
import org.testcontainers.containers.GenericContainer;
146
import org.testcontainers.containers.Network;
147
import org.junit.jupiter.api.*;
148
149
@Testcontainers
150
@EnabledIfDockerAvailable
151
class CompleteIntegrationTest {
152
153
static Network network = Network.newNetwork();
154
155
@Container
156
static GenericContainer<?> database = new GenericContainer<>("postgres:13")
157
.withNetwork(network)
158
.withNetworkAliases("db")
159
.withExposedPorts(5432)
160
.withEnv("POSTGRES_PASSWORD", "test");
161
162
@Container
163
static GenericContainer<?> app = new GenericContainer<>("myapp:latest")
164
.withNetwork(network)
165
.withExposedPorts(8080)
166
.withEnv("DB_HOST", "db")
167
.dependsOn(database);
168
169
@Test
170
void testApplicationWithDatabase() {
171
String appUrl = "http://" + app.getHost() + ":" + app.getMappedPort(8080);
172
// ... integration test logic
173
}
174
175
@AfterAll
176
static void cleanup() {
177
network.close();
178
}
179
}
180
```
181
182
## Types
183
184
```java { .api }
185
/**
186
* Exception thrown when Docker is not available but required for test execution
187
*/
188
public class TestcontainersConfigurationException extends RuntimeException {
189
public TestcontainersConfigurationException(String message);
190
public TestcontainersConfigurationException(String message, Throwable cause);
191
}
192
```