or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/maven-org-testcontainers--junit-jupiter

JUnit Jupiter extension that enables automatic lifecycle management of Docker containers in JUnit 5 tests

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
mavenpkg:maven/org.testcontainers/junit-jupiter@1.21.x

To install, run

npx @tessl/cli install tessl/maven-org-testcontainers--junit-jupiter@1.21.0

0

# Testcontainers JUnit Jupiter

1

2

A JUnit Jupiter extension that enables automatic lifecycle management of Docker containers in JUnit 5 tests. The extension provides annotations to seamlessly integrate container-based testing into the JUnit Jupiter framework, supporting both static containers (shared between test methods) and instance containers (started/stopped per test method).

3

4

## Package Information

5

6

- **Package Name**: org.testcontainers:junit-jupiter

7

- **Package Type**: Maven

8

- **Language**: Java

9

- **Installation**:

10

- **Maven**:

11

```xml

12

<dependency>

13

<groupId>org.testcontainers</groupId>

14

<artifactId>junit-jupiter</artifactId>

15

<version>1.21.3</version>

16

<scope>test</scope>

17

</dependency>

18

```

19

- **Gradle**:

20

```gradle

21

testImplementation 'org.testcontainers:junit-jupiter:1.21.3'

22

```

23

24

## Core Imports

25

26

```java

27

import org.testcontainers.junit.jupiter.Testcontainers;

28

import org.testcontainers.junit.jupiter.Container;

29

import org.testcontainers.junit.jupiter.EnabledIfDockerAvailable;

30

```

31

32

## Basic Usage

33

34

```java

35

import org.testcontainers.containers.PostgreSQLContainer;

36

import org.testcontainers.containers.MySQLContainer;

37

import org.testcontainers.junit.jupiter.Container;

38

import org.testcontainers.junit.jupiter.Testcontainers;

39

import org.junit.jupiter.api.Test;

40

import static org.junit.jupiter.api.Assertions.assertTrue;

41

42

@Testcontainers

43

class MyTestcontainersTests {

44

45

// Shared between test methods - started once, stopped after all tests

46

@Container

47

private static final MySQLContainer<?> mysql = new MySQLContainer<>("mysql:8.0");

48

49

// Started before and stopped after each test method

50

@Container

51

private PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:13")

52

.withDatabaseName("testdb")

53

.withUsername("test")

54

.withPassword("test");

55

56

@Test

57

void testContainersAreRunning() {

58

assertTrue(mysql.isRunning());

59

assertTrue(postgres.isRunning());

60

}

61

}

62

```

63

64

## Architecture

65

66

The JUnit Jupiter extension integrates with JUnit 5's extension model through several key components:

67

68

- **Annotation Processing**: Scans test classes for `@Container` annotated fields and manages their lifecycle

69

- **Extension Hooks**: Implements JUnit's `BeforeAllCallback`, `AfterAllCallback`, `BeforeEachCallback`, `AfterEachCallback`, and `ExecutionCondition` for precise container lifecycle control

70

- **Conditional Execution**: Provides execution conditions to skip or disable tests when Docker is unavailable

71

- **Parallel Support**: Enables parallel container startup for improved test performance when configured

72

- **Lifecycle Integration**: Connects with `TestLifecycleAware` containers to provide test context information

73

74

## Capabilities

75

76

### Container Lifecycle Management

77

78

Automatically manages Docker container startup and shutdown through the `@Testcontainers` annotation and `@Container` field annotation.

79

80

```java { .api }

81

@Target(ElementType.TYPE)

82

@Retention(RetentionPolicy.RUNTIME)

83

@ExtendWith(TestcontainersExtension.class)

84

@Inherited

85

public @interface Testcontainers {

86

/**

87

* Whether tests should be disabled (rather than failing) when Docker is not available.

88

* @return if the tests should be disabled when Docker is not available

89

*/

90

boolean disabledWithoutDocker() default false;

91

92

/**

93

* Whether containers should start in parallel.

94

* @return if the containers should start in parallel

95

*/

96

boolean parallel() default false;

97

}

98

99

@Target({ ElementType.FIELD, ElementType.ANNOTATION_TYPE })

100

@Retention(RetentionPolicy.RUNTIME)

101

public @interface Container {

102

}

103

```

104

105

**Container Lifecycle Rules:**

106

- **Static fields** with `@Container`: Shared between all test methods in the class. Started once before any test method executes, stopped after the last test method completes.

107

- **Instance fields** with `@Container`: Restarted for each individual test method. Started before each test method, stopped after each test method.

108

- **Container Requirements**: Fields annotated with `@Container` must implement `org.testcontainers.lifecycle.Startable` interface.

109

110

**Usage Examples:**

111

112

```java

113

@Testcontainers

114

class ContainerLifecycleExample {

115

116

// Shared container - expensive to start, reused across tests

117

@Container

118

static final PostgreSQLContainer<?> sharedPostgres =

119

new PostgreSQLContainer<>("postgres:13");

120

121

// Per-test container - fresh instance for each test

122

@Container

123

RedisContainer redis = new RedisContainer("redis:6-alpine");

124

125

@Test

126

void testWithFreshRedis() {

127

// redis container is started fresh for this test

128

String redisUrl = redis.getRedisURI();

129

// ... test logic

130

}

131

132

@Test

133

void testWithSharedPostgres() {

134

// sharedPostgres container was started once and is reused

135

String jdbcUrl = sharedPostgres.getJdbcUrl();

136

// ... test logic

137

}

138

}

139

```

140

141

### Conditional Test Execution

142

143

Provides Docker availability detection and conditional test execution capabilities.

144

145

```java { .api }

146

@Target({ ElementType.TYPE, ElementType.METHOD })

147

@Retention(RetentionPolicy.RUNTIME)

148

@Documented

149

@ExtendWith(EnabledIfDockerAvailableCondition.class)

150

public @interface EnabledIfDockerAvailable {

151

}

152

```

153

154

**Docker Availability Options:**

155

156

1. **Fail when Docker unavailable** (default behavior):

157

```java

158

@Testcontainers

159

class MyTests {

160

// Tests will fail if Docker is not available

161

}

162

```

163

164

2. **Disable tests when Docker unavailable**:

165

```java

166

@Testcontainers(disabledWithoutDocker = true)

167

class MyTests {

168

// Tests will be skipped if Docker is not available

169

}

170

```

171

172

3. **Method-level Docker requirement**:

173

```java

174

class MyTests {

175

176

@Test

177

@EnabledIfDockerAvailable

178

void testRequiringDocker() {

179

// This test only runs if Docker is available

180

}

181

182

@Test

183

void testNotRequiringDocker() {

184

// This test always runs

185

}

186

}

187

```

188

189

### Extension Integration

190

191

The extension integrates with JUnit Jupiter's lifecycle and provides access to the underlying extension functionality.

192

193

```java { .api }

194

public class TestcontainersExtension

195

implements BeforeEachCallback, BeforeAllCallback, AfterEachCallback, AfterAllCallback, ExecutionCondition {

196

197

/**

198

* Check if Docker is available on the system

199

* @return true if Docker client can be created and accessed

200

*/

201

public boolean isDockerAvailable();

202

}

203

```

204

205

**Parallel Container Startup:**

206

207

```java

208

@Testcontainers(parallel = true)

209

class ParallelStartupExample {

210

211

@Container

212

static final PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:13");

213

214

@Container

215

static final MySQLContainer<?> mysql = new MySQLContainer<>("mysql:8.0");

216

217

@Container

218

static final RedisContainer redis = new RedisContainer("redis:6-alpine");

219

220

// All three containers will start in parallel, reducing total startup time

221

}

222

```

223

224

**Test Lifecycle Integration:**

225

226

For containers implementing `org.testcontainers.lifecycle.TestLifecycleAware`, the extension provides test context:

227

228

```java

229

// Container receives test lifecycle callbacks

230

public class MyCustomContainer extends GenericContainer<MyCustomContainer>

231

implements TestLifecycleAware {

232

233

@Override

234

public void beforeTest(TestDescription description) {

235

// Called before each test method

236

// description provides test ID and filesystem-friendly name

237

}

238

239

@Override

240

public void afterTest(TestDescription description, Optional<Throwable> throwable) {

241

// Called after each test method

242

// throwable contains test failure information if test failed

243

}

244

}

245

```

246

247

## Error Handling

248

249

**Common Configuration Errors:**

250

251

- **`ExtensionConfigurationException`**: Thrown when `@Container` field does not implement `Startable` interface

252

- **`ExtensionConfigurationException`**: Thrown when `@Container` field is null (containers must be initialized)

253

- **`ExtensionConfigurationException`**: Thrown when `@Testcontainers` annotation is not found on class hierarchy

254

255

**Docker Availability Handling:**

256

257

- When `disabledWithoutDocker = false` (default): Tests fail with Docker connection errors if Docker is unavailable

258

- When `disabledWithoutDocker = true`: Tests are marked as disabled/skipped if Docker is unavailable

259

- `@EnabledIfDockerAvailable`: Individual tests/classes are skipped if Docker is unavailable

260

261

## Integration Requirements

262

263

**JUnit Jupiter**: Requires JUnit Jupiter 5.x (junit-jupiter-api dependency)

264

**Testcontainers Core**: Depends on org.testcontainers:testcontainers core library

265

**Docker**: Requires Docker daemon running and accessible to the test process

266

267

**Inheritance Support**: The `@Testcontainers` annotation is `@Inherited`, so subclasses automatically inherit the extension behavior from parent test classes.