0
# Configuration and Lifecycle
1
2
Suite configuration management through parameters and properties files, plus lifecycle hooks for suite setup and teardown operations with comprehensive parameter inheritance control.
3
4
## Capabilities
5
6
### Configuration Parameters
7
8
Specify configuration key-value pairs for test suite execution, enabling fine-grained control over JUnit Platform behavior and custom test configuration.
9
10
```java { .api }
11
/**
12
* Specifies configuration key-value pairs for the discovery request.
13
* Can be repeated to specify multiple parameters.
14
* Combined with parent configuration unless disabled by @DisableParentConfigurationParameters.
15
*
16
* @since 1.8
17
*/
18
@Retention(RetentionPolicy.RUNTIME)
19
@Target(ElementType.TYPE)
20
@Inherited
21
@Documented
22
@Repeatable(ConfigurationParameters.class)
23
@API(status = STABLE, since = "1.10")
24
public @interface ConfigurationParameter {
25
/**
26
* Configuration parameter key.
27
* @return key name; never null or blank
28
*/
29
String key();
30
31
/**
32
* Value to add for the specified key.
33
* @return parameter value for the key
34
*/
35
String value();
36
}
37
38
/**
39
* Container for multiple @ConfigurationParameter declarations.
40
* Automatically used when @ConfigurationParameter is repeated.
41
*
42
* @since 1.8
43
*/
44
@Retention(RetentionPolicy.RUNTIME)
45
@Target(ElementType.TYPE)
46
@Inherited
47
@Documented
48
@API(status = STABLE, since = "1.10")
49
public @interface ConfigurationParameters {
50
/**
51
* Array of configuration parameter declarations.
52
* @return configuration parameters to apply
53
*/
54
ConfigurationParameter[] value();
55
}
56
```
57
58
**Usage Examples:**
59
60
```java
61
// Single configuration parameter
62
@Suite
63
@SelectPackages("com.example")
64
@ConfigurationParameter(key = "junit.jupiter.execution.parallel.enabled", value = "true")
65
class ParallelSuite {
66
}
67
68
// Multiple configuration parameters
69
@Suite
70
@SelectPackages("com.example")
71
@ConfigurationParameter(key = "junit.jupiter.execution.parallel.enabled", value = "true")
72
@ConfigurationParameter(key = "junit.jupiter.execution.parallel.mode.default", value = "concurrent")
73
@ConfigurationParameter(key = "junit.jupiter.execution.parallel.config.strategy", value = "dynamic")
74
class AdvancedParallelSuite {
75
}
76
77
// Custom test configuration
78
@Suite
79
@SelectPackages("com.example")
80
@ConfigurationParameter(key = "test.database.url", value = "jdbc:h2:mem:testdb")
81
@ConfigurationParameter(key = "test.timeout.default", value = "30s")
82
@ConfigurationParameter(key = "test.environment", value = "integration")
83
class CustomConfigSuite {
84
}
85
```
86
87
### Configuration Parameter Resources
88
89
Load configuration parameters from properties files on the classpath, enabling externalized configuration management.
90
91
```java { .api }
92
/**
93
* Specifies properties file on classpath for configuration parameters.
94
* Uses standard Java properties format for key-value pairs.
95
* Can be repeated to load from multiple resource files.
96
*
97
* @since 1.11
98
*/
99
@Retention(RetentionPolicy.RUNTIME)
100
@Target(ElementType.TYPE)
101
@Inherited
102
@Documented
103
@Repeatable(ConfigurationParametersResources.class)
104
@API(status = EXPERIMENTAL, since = "1.11")
105
public @interface ConfigurationParametersResource {
106
/**
107
* Classpath location for properties file.
108
* @return classpath resource path; never null or blank
109
*/
110
String value();
111
}
112
113
/**
114
* Container for multiple @ConfigurationParametersResource declarations.
115
* Automatically used when @ConfigurationParametersResource is repeated.
116
*
117
* @since 1.11
118
*/
119
@Retention(RetentionPolicy.RUNTIME)
120
@Target(ElementType.TYPE)
121
@Inherited
122
@Documented
123
@API(status = EXPERIMENTAL, since = "1.11")
124
public @interface ConfigurationParametersResources {
125
/**
126
* Array of configuration parameter resource declarations.
127
* @return resource declarations to load
128
*/
129
ConfigurationParametersResource[] value();
130
}
131
```
132
133
**Usage Examples:**
134
135
```java
136
// Single properties file
137
@Suite
138
@SelectPackages("com.example")
139
@ConfigurationParametersResource("test-config.properties")
140
class ResourceConfigSuite {
141
}
142
143
// Multiple properties files
144
@Suite
145
@SelectPackages("com.example")
146
@ConfigurationParametersResource("common-test-config.properties")
147
@ConfigurationParametersResource("integration-test-config.properties")
148
class MultiResourceConfigSuite {
149
}
150
151
// Environment-specific configuration
152
@Suite
153
@SelectPackages("com.example")
154
@ConfigurationParametersResource("test-config-${test.env:local}.properties")
155
class EnvironmentConfigSuite {
156
}
157
```
158
159
### Configuration Parameter Inheritance Control
160
161
Control how suite configuration parameters are inherited from parent discovery requests.
162
163
```java { .api }
164
/**
165
* Disables parent configuration parameters for the test suite.
166
* By default, suites use both explicit configuration parameters and
167
* configuration parameters from the parent discovery request.
168
* This annotation disables the latter, using only explicit parameters.
169
*
170
* Affects both @ConfigurationParameter and @ConfigurationParametersResource.
171
*
172
* @since 1.8
173
*/
174
@Retention(RetentionPolicy.RUNTIME)
175
@Target(ElementType.TYPE)
176
@Inherited
177
@Documented
178
@API(status = STABLE, since = "1.10")
179
public @interface DisableParentConfigurationParameters {
180
}
181
```
182
183
**Usage Examples:**
184
185
```java
186
// Isolated suite configuration
187
@Suite
188
@SelectPackages("com.example")
189
@DisableParentConfigurationParameters
190
@ConfigurationParameter(key = "junit.jupiter.execution.parallel.enabled", value = "false")
191
class IsolatedConfigSuite {
192
}
193
194
// Override parent settings
195
@Suite
196
@SelectPackages("com.example")
197
@DisableParentConfigurationParameters
198
@ConfigurationParametersResource("override-config.properties")
199
class OverrideConfigSuite {
200
}
201
```
202
203
### Suite Lifecycle Hooks
204
205
Provide setup and teardown capabilities at the suite level, executing before and after all tests in the suite.
206
207
```java { .api }
208
/**
209
* Executed before all tests in the current test suite.
210
* Method must be static, void return type, and not private.
211
* Inherited from superclasses if not overridden.
212
* Multiple methods have deterministic but non-obvious order.
213
* Recommendation: At most one per test class/interface.
214
*
215
* @since 1.11
216
*/
217
@Retention(RetentionPolicy.RUNTIME)
218
@Target(ElementType.METHOD)
219
@Documented
220
@API(status = EXPERIMENTAL, since = "1.11")
221
public @interface BeforeSuite {
222
}
223
224
/**
225
* Executed after all tests in the current test suite.
226
* Method must be static, void return type, and not private.
227
* Inherited from superclasses if not overridden.
228
* Multiple methods have deterministic but non-obvious order.
229
* Recommendation: At most one per test class/interface.
230
*
231
* @since 1.11
232
*/
233
@Retention(RetentionPolicy.RUNTIME)
234
@Target(ElementType.METHOD)
235
@Documented
236
@API(status = EXPERIMENTAL, since = "1.11")
237
public @interface AfterSuite {
238
}
239
```
240
241
**Usage Examples:**
242
243
```java
244
// Basic lifecycle management
245
@Suite
246
@SelectPackages("com.example")
247
class BasicLifecycleSuite {
248
249
@BeforeSuite
250
static void setupSuite() {
251
System.setProperty("test.environment", "suite");
252
// Initialize shared resources
253
TestDatabase.initialize();
254
}
255
256
@AfterSuite
257
static void cleanupSuite() {
258
// Clean up shared resources
259
TestDatabase.cleanup();
260
System.clearProperty("test.environment");
261
}
262
}
263
264
// Complex setup with configuration
265
@Suite
266
@SelectPackages("com.example")
267
@ConfigurationParameter(key = "test.database.url", value = "jdbc:h2:mem:suitedb")
268
class ComplexLifecycleSuite {
269
270
private static TestServer testServer;
271
272
@BeforeSuite
273
static void setupInfrastructure() {
274
// Start test server
275
testServer = new TestServer()
276
.withPort(9999)
277
.withDatabase("suitedb")
278
.start();
279
280
// Wait for server readiness
281
testServer.waitForReadiness(Duration.ofSeconds(30));
282
283
// Set system properties for tests
284
System.setProperty("test.server.url", testServer.getUrl());
285
}
286
287
@AfterSuite
288
static void teardownInfrastructure() {
289
// Stop test server
290
if (testServer != null) {
291
testServer.stop();
292
}
293
294
// Clear system properties
295
System.clearProperty("test.server.url");
296
}
297
}
298
299
// Inherited lifecycle methods
300
class BaseSuite {
301
@BeforeSuite
302
static void baseSetup() {
303
// Base suite setup
304
}
305
306
@AfterSuite
307
static void baseCleanup() {
308
// Base suite cleanup
309
}
310
}
311
312
@Suite
313
@SelectClasses({SpecificTest.class})
314
class ExtendedSuite extends BaseSuite {
315
316
@BeforeSuite
317
static void extendedSetup() {
318
// Extended suite setup (runs after baseSetup)
319
}
320
321
@AfterSuite
322
static void extendedCleanup() {
323
// Extended suite cleanup (runs before baseCleanup)
324
}
325
}
326
```
327
328
## Configuration Strategy Patterns
329
330
### Environment-Specific Configuration
331
332
Different configurations for different test environments:
333
334
```java
335
// Local development configuration
336
@Suite
337
@SelectPackages("com.example")
338
@ConfigurationParameter(key = "test.database.url", value = "jdbc:h2:mem:localdb")
339
@ConfigurationParameter(key = "test.timeout.default", value = "10s")
340
@ConfigurationParameter(key = "test.parallel.enabled", value = "false")
341
class LocalDevSuite {
342
}
343
344
// CI/CD configuration
345
@Suite
346
@SelectPackages("com.example")
347
@ConfigurationParameter(key = "test.database.url", value = "${TEST_DB_URL}")
348
@ConfigurationParameter(key = "test.timeout.default", value = "60s")
349
@ConfigurationParameter(key = "test.parallel.enabled", value = "true")
350
@ConfigurationParameter(key = "test.parallel.threads", value = "4")
351
class CISuite {
352
}
353
```
354
355
### Resource-Based Configuration
356
357
Externalized configuration using properties files:
358
359
```java
360
// Main configuration from resources
361
@Suite
362
@SelectPackages("com.example")
363
@ConfigurationParametersResource("test-defaults.properties")
364
@ConfigurationParametersResource("test-environment.properties")
365
class ResourceBasedSuite {
366
}
367
368
// Override with additional parameters
369
@Suite
370
@SelectPackages("com.example")
371
@ConfigurationParametersResource("common-config.properties")
372
@ConfigurationParameter(key = "test.suite.name", value = "SpecialSuite")
373
@ConfigurationParameter(key = "test.override.enabled", value = "true")
374
class OverriddenResourceSuite {
375
}
376
```
377
378
### Isolated Configuration
379
380
Complete isolation from parent configuration:
381
382
```java
383
// Completely isolated suite
384
@Suite
385
@SelectPackages("com.example")
386
@DisableParentConfigurationParameters
387
@ConfigurationParameter(key = "junit.jupiter.execution.parallel.enabled", value = "false")
388
@ConfigurationParameter(key = "junit.jupiter.testinstance.lifecycle.default", value = "per_class")
389
class IsolatedSuite {
390
391
@BeforeSuite
392
static void setupIsolatedEnvironment() {
393
// Setup completely independent environment
394
}
395
396
@AfterSuite
397
static void cleanupIsolatedEnvironment() {
398
// Cleanup independent environment
399
}
400
}
401
```
402
403
### Complex Lifecycle Management
404
405
Advanced setup and teardown patterns:
406
407
```java
408
@Suite
409
@SelectPackages("com.example.integration")
410
@ConfigurationParametersResource("integration-test-config.properties")
411
class IntegrationTestSuite {
412
413
private static TestCluster testCluster;
414
private static MockServices mockServices;
415
416
@BeforeSuite
417
static void setupIntegrationEnvironment() {
418
// Start test cluster
419
testCluster = TestCluster.builder()
420
.withServices("database", "cache", "messaging")
421
.withReplicas(3)
422
.build()
423
.start();
424
425
// Start mock external services
426
mockServices = MockServices.builder()
427
.withPaymentService()
428
.withEmailService()
429
.withAuditService()
430
.start();
431
432
// Configure system properties
433
System.setProperty("integration.cluster.url", testCluster.getConnectionUrl());
434
System.setProperty("integration.mocks.url", mockServices.getBaseUrl());
435
436
// Wait for services to be ready
437
testCluster.waitForReadiness(Duration.ofMinutes(2));
438
mockServices.waitForReadiness(Duration.ofSeconds(30));
439
}
440
441
@AfterSuite
442
static void teardownIntegrationEnvironment() {
443
try {
444
// Collect test metrics
445
if (testCluster != null) {
446
testCluster.exportMetrics("target/integration-metrics.json");
447
}
448
449
// Stop services
450
if (mockServices != null) {
451
mockServices.stop();
452
}
453
if (testCluster != null) {
454
testCluster.stop();
455
}
456
} finally {
457
// Clear system properties
458
System.clearProperty("integration.cluster.url");
459
System.clearProperty("integration.mocks.url");
460
}
461
}
462
}
463
```