0
# JUnit Platform Runner
1
2
JUnit Platform Runner is a JUnit 4 based Runner that allows tests to be executed on the JUnit Platform in a JUnit 4 environment. It serves as a bridge component enabling JUnit 5 (Jupiter) tests to run in environments that support JUnit 4 but do not yet support the JUnit Platform directly.
3
4
**⚠️ Deprecated Notice**: This module is deprecated since JUnit Platform 1.8 in favor of `junit-platform-suite-engine` with `@Suite` annotation support, and is scheduled for removal in JUnit Platform 2.0.
5
6
## Package Information
7
8
- **Package Name**: org.junit.platform:junit-platform-runner
9
- **Package Type**: Maven
10
- **Language**: Java
11
- **Version**: 1.12.2
12
- **Installation**:
13
```xml
14
<dependency>
15
<groupId>org.junit.platform</groupId>
16
<artifactId>junit-platform-runner</artifactId>
17
<version>1.12.2</version>
18
</dependency>
19
```
20
21
## Core Imports
22
23
```java
24
import org.junit.platform.runner.JUnitPlatform;
25
import org.junit.runner.RunWith;
26
import org.junit.runner.manipulation.Filter;
27
import org.junit.runner.manipulation.NoTestsRemainException;
28
import org.junit.runner.notification.RunNotifier;
29
import org.junit.runner.Description;
30
```
31
32
Additional imports for configuration:
33
```java
34
import org.junit.platform.suite.api.*;
35
```
36
37
## Basic Usage
38
39
### Running a Single Test Class
40
41
```java
42
import org.junit.jupiter.api.Test;
43
import org.junit.runner.RunWith;
44
import org.junit.platform.runner.JUnitPlatform;
45
46
@RunWith(JUnitPlatform.class)
47
public class MyJUnit5TestClass {
48
49
@Test
50
void shouldPassTest() {
51
// JUnit 5 test logic
52
}
53
54
@Test
55
void anotherTest() {
56
// Another JUnit 5 test
57
}
58
}
59
```
60
61
### Creating a Test Suite
62
63
```java
64
import org.junit.runner.RunWith;
65
import org.junit.platform.runner.JUnitPlatform;
66
import org.junit.platform.suite.api.*;
67
68
@RunWith(JUnitPlatform.class)
69
@SuiteDisplayName("My Test Suite")
70
@SelectPackages("com.example.tests")
71
@ExcludeTags("slow")
72
public class MyTestSuite {
73
// Empty class body - configuration is done via annotations
74
}
75
```
76
77
## Architecture
78
79
The JUnit Platform Runner serves as a bridge between JUnit 4 and the JUnit Platform, enabling JUnit 5 tests to run in JUnit 4 environments:
80
81
- **Runner Pattern**: Implements JUnit 4's `Runner` interface to integrate with existing build tools and IDEs
82
- **Test Discovery**: Uses JUnit Platform's discovery API to find and organize tests
83
- **Event Translation**: Translates JUnit Platform test execution events into JUnit 4 notification events
84
- **Suite Configuration**: Supports extensive configuration through annotations from `junit-platform-suite-api`
85
86
The runner discovers tests using JUnit Platform mechanisms, builds an internal test tree representation, then executes tests while translating events to JUnit 4's RunNotifier system for compatibility with existing tooling.
87
88
## Capabilities
89
90
### JUnitPlatform Runner
91
92
The main Runner class that enables JUnit Platform tests to run in JUnit 4 environments.
93
94
```java { .api }
95
/**
96
* JUnit 4 based Runner which runs tests on the JUnit Platform in a JUnit 4 environment.
97
* Annotating a class with @RunWith(JUnitPlatform.class) allows it to be run with IDEs
98
* and build systems that support JUnit 4 but do not yet support the JUnit Platform directly.
99
*
100
* Note: Test classes and suites annotated with @RunWith(JUnitPlatform.class) cannot be
101
* executed directly on the JUnit Platform and can only be executed using JUnit 4 infrastructure.
102
*
103
* @since 1.0
104
* @deprecated since 1.8, in favor of the @Suite support provided by junit-platform-suite-engine;
105
* to be removed in JUnit Platform 2.0
106
* @status DEPRECATED
107
*/
108
@Deprecated
109
public class JUnitPlatform extends Runner implements Filterable {
110
111
/**
112
* Creates a new JUnitPlatform runner for the specified test class.
113
* @param testClass the test class to run; must be public to be picked up by IDEs and build tools
114
*/
115
public JUnitPlatform(Class<?> testClass);
116
117
/**
118
* Returns the suite description for the test tree.
119
* @return Description object representing the test suite
120
*/
121
@Override
122
public Description getDescription();
123
124
/**
125
* Executes the tests using the provided RunNotifier.
126
* @param notifier the RunNotifier to report test execution events
127
*/
128
@Override
129
public void run(RunNotifier notifier);
130
131
/**
132
* Applies a filter to limit which tests are executed.
133
* @param filter the Filter to apply
134
* @throws NoTestsRemainException if no tests remain after filtering
135
*/
136
@Override
137
public void filter(Filter filter) throws NoTestsRemainException;
138
}
139
```
140
141
**Usage Examples:**
142
143
```java
144
// Basic test class usage - must be public
145
@RunWith(JUnitPlatform.class)
146
public class SimpleTestClass {
147
@Test
148
void testMethod() {
149
// test implementation
150
}
151
}
152
153
// Test suite with package selection and tag filtering
154
@RunWith(JUnitPlatform.class)
155
@SelectPackages({"com.example.unit", "com.example.integration"})
156
@ExcludeTags("slow")
157
@IncludeTags("important | critical") // Tag expression with OR
158
public class ComprehensiveTestSuite {
159
}
160
161
// Configuration with parameters
162
@RunWith(JUnitPlatform.class)
163
@SelectClasses({DatabaseTest.class, NetworkTest.class})
164
@ConfigurationParameter(key = "junit.jupiter.execution.parallel.enabled", value = "true")
165
@ConfigurationParameter(key = "junit.jupiter.execution.parallel.mode.default", value = "concurrent")
166
public class ParallelTestSuite {
167
}
168
```
169
170
### Test Selection Annotations
171
172
Annotations for selecting which tests to include in the test run.
173
174
```java { .api }
175
/**
176
* Select specific test classes to include
177
* @since 1.0
178
* @status MAINTAINED
179
*/
180
@Target(ElementType.TYPE)
181
@Retention(RetentionPolicy.RUNTIME)
182
@Documented
183
@Inherited
184
public @interface SelectClasses {
185
/** One or more classes to select */
186
Class<?>[] value() default {};
187
188
/**
189
* One or more classes to select by their fully qualified names
190
* @since 1.10
191
* @status EXPERIMENTAL
192
*/
193
String[] names() default {};
194
}
195
196
/**
197
* Select tests from specific packages
198
* @since 1.0
199
* @status MAINTAINED
200
*/
201
@Target(ElementType.TYPE)
202
@Retention(RetentionPolicy.RUNTIME)
203
@Documented
204
@Inherited
205
public @interface SelectPackages {
206
String[] value();
207
}
208
209
/**
210
* Select tests from classpath resources
211
* @since 1.0
212
* @status MAINTAINED
213
*/
214
@Target(ElementType.TYPE)
215
@Retention(RetentionPolicy.RUNTIME)
216
@Documented
217
@Inherited
218
public @interface SelectClasspathResource {
219
String value();
220
}
221
222
/**
223
* Select tests from specific directories
224
* @since 1.0
225
* @status MAINTAINED
226
*/
227
@Target(ElementType.TYPE)
228
@Retention(RetentionPolicy.RUNTIME)
229
@Documented
230
@Inherited
231
public @interface SelectDirectories {
232
String[] value();
233
}
234
235
/**
236
* Select tests from specific files
237
* @since 1.0
238
* @status MAINTAINED
239
*/
240
@Target(ElementType.TYPE)
241
@Retention(RetentionPolicy.RUNTIME)
242
@Documented
243
@Inherited
244
public @interface SelectFile {
245
String value();
246
}
247
248
/**
249
* Select tests from specific modules
250
* @since 1.0
251
* @status MAINTAINED
252
*/
253
@Target(ElementType.TYPE)
254
@Retention(RetentionPolicy.RUNTIME)
255
@Documented
256
@Inherited
257
public @interface SelectModules {
258
String[] value();
259
}
260
261
/**
262
* Select tests using URIs
263
* @since 1.0
264
* @status MAINTAINED
265
*/
266
@Target(ElementType.TYPE)
267
@Retention(RetentionPolicy.RUNTIME)
268
@Documented
269
@Inherited
270
public @interface SelectUris {
271
String[] value();
272
}
273
```
274
275
### Test Filtering Annotations
276
277
Annotations for filtering tests based on various criteria.
278
279
```java { .api }
280
/**
281
* Include tests matching class name patterns
282
* @since 1.0
283
* @status MAINTAINED
284
*/
285
@Target(ElementType.TYPE)
286
@Retention(RetentionPolicy.RUNTIME)
287
@Documented
288
@Inherited
289
public @interface IncludeClassNamePatterns {
290
/** Default pattern matches Test classes/methods */
291
String[] value() default "^(Test.*|.+[.$]Test.*|.*Tests?)$";
292
}
293
294
/**
295
* Exclude tests matching class name patterns
296
* @since 1.0
297
* @status MAINTAINED
298
*/
299
@Target(ElementType.TYPE)
300
@Retention(RetentionPolicy.RUNTIME)
301
@Documented
302
@Inherited
303
public @interface ExcludeClassNamePatterns {
304
String[] value();
305
}
306
307
/**
308
* Include specific test engines
309
* @since 1.0
310
* @status MAINTAINED
311
*/
312
@Target(ElementType.TYPE)
313
@Retention(RetentionPolicy.RUNTIME)
314
@Documented
315
@Inherited
316
public @interface IncludeEngines {
317
String[] value();
318
}
319
320
/**
321
* Exclude specific test engines
322
* @since 1.0
323
* @status MAINTAINED
324
*/
325
@Target(ElementType.TYPE)
326
@Retention(RetentionPolicy.RUNTIME)
327
@Documented
328
@Inherited
329
public @interface ExcludeEngines {
330
String[] value();
331
}
332
333
/**
334
* Include specific packages
335
* @since 1.0
336
* @status MAINTAINED
337
*/
338
@Target(ElementType.TYPE)
339
@Retention(RetentionPolicy.RUNTIME)
340
@Documented
341
@Inherited
342
public @interface IncludePackages {
343
String[] value();
344
}
345
346
/**
347
* Exclude specific packages
348
* @since 1.0
349
* @status MAINTAINED
350
*/
351
@Target(ElementType.TYPE)
352
@Retention(RetentionPolicy.RUNTIME)
353
@Documented
354
@Inherited
355
public @interface ExcludePackages {
356
String[] value();
357
}
358
359
/**
360
* Include tests with specific tags. Supports tag expressions
361
* with operators: ! (not), & (and), | (or), and parentheses.
362
* @since 1.0
363
* @status MAINTAINED
364
*/
365
@Target(ElementType.TYPE)
366
@Retention(RetentionPolicy.RUNTIME)
367
@Documented
368
@Inherited
369
public @interface IncludeTags {
370
String[] value();
371
}
372
373
/**
374
* Exclude tests with specific tags. Supports tag expressions
375
* with operators: ! (not), & (and), | (or), and parentheses.
376
* @since 1.0
377
* @status MAINTAINED
378
*/
379
@Target(ElementType.TYPE)
380
@Retention(RetentionPolicy.RUNTIME)
381
@Documented
382
@Inherited
383
public @interface ExcludeTags {
384
String[] value();
385
}
386
```
387
388
### Display and Configuration Annotations
389
390
Annotations for customizing test display and configuration.
391
392
```java { .api }
393
/**
394
* Set custom display name for test suite
395
* @since 1.0
396
* @status MAINTAINED
397
*/
398
@Target(ElementType.TYPE)
399
@Retention(RetentionPolicy.RUNTIME)
400
@Documented
401
@Inherited
402
public @interface SuiteDisplayName {
403
String value();
404
}
405
406
/**
407
* Use technical names instead of display names
408
* @deprecated since 1.8, to be removed in JUnit Platform 2.0
409
* @since 1.0
410
* @status DEPRECATED
411
*/
412
@Deprecated
413
@Target(ElementType.TYPE)
414
@Retention(RetentionPolicy.RUNTIME)
415
@Documented
416
@Inherited
417
public @interface UseTechnicalNames {
418
}
419
420
/**
421
* Set configuration parameters (repeatable annotation)
422
* @since 1.8
423
* @status STABLE
424
*/
425
@Target(ElementType.TYPE)
426
@Retention(RetentionPolicy.RUNTIME)
427
@Documented
428
@Inherited
429
@Repeatable(ConfigurationParameters.class)
430
public @interface ConfigurationParameter {
431
String key();
432
String value();
433
}
434
435
/**
436
* Container for multiple configuration parameters
437
* @since 1.8
438
* @status STABLE
439
*/
440
@Target(ElementType.TYPE)
441
@Retention(RetentionPolicy.RUNTIME)
442
@Documented
443
@Inherited
444
public @interface ConfigurationParameters {
445
ConfigurationParameter[] value();
446
}
447
448
/**
449
* Load configuration from resource
450
* @since 1.8
451
* @status STABLE
452
*/
453
@Target(ElementType.TYPE)
454
@Retention(RetentionPolicy.RUNTIME)
455
@Documented
456
@Inherited
457
public @interface ConfigurationParametersResource {
458
String value();
459
}
460
```
461
462
### Modern Suite Annotation (Replacement)
463
464
The modern `@Suite` annotation that replaces the deprecated JUnit Platform Runner.
465
466
```java { .api }
467
/**
468
* Marks a class as a test suite on the JUnit Platform. This is the modern
469
* replacement for @RunWith(JUnitPlatform.class).
470
* @since 1.8
471
* @status STABLE
472
*/
473
@Target(ElementType.TYPE)
474
@Retention(RetentionPolicy.RUNTIME)
475
@Documented
476
@Inherited
477
public @interface Suite {
478
/**
479
* Configures whether the test suite should fail if no tests are found.
480
* @since 1.9
481
*/
482
boolean failIfNoTests() default true;
483
}
484
```
485
486
## Dependencies
487
488
The JUnit Platform Runner requires the following dependencies:
489
490
**Core Dependencies:**
491
- `junit:junit` (JUnit 4) - Required for Runner infrastructure
492
- `org.junit.platform:junit-platform-launcher` - Required for test discovery and execution
493
- `org.junit.platform:junit-platform-suite-api` - Required for configuration annotations
494
495
**Optional Dependencies:**
496
- `org.apiguardian:apiguardian-api` - Provides API status annotations
497
498
## Migration Path
499
500
Since this runner is deprecated, consider migrating to the modern approach:
501
502
**Old (Deprecated):**
503
```java
504
@RunWith(JUnitPlatform.class)
505
@SelectPackages("com.example")
506
public class TestSuite {}
507
```
508
509
**New (Recommended):**
510
```java
511
@Suite
512
@SelectPackages("com.example")
513
public class TestSuite {}
514
```
515
516
The new approach requires `junit-platform-suite-engine` instead of `junit-platform-runner`.
517
518
## Limitations
519
520
- Test classes run with this runner cannot be executed directly on the JUnit Platform
521
- Only works in JUnit 4 environments - cannot run as native JUnit 5 tests
522
- Deprecated and will be removed in JUnit Platform 2.0
523
- Test classes must be `public` to be picked up by IDEs and build tools
524
- When used without configuration annotations, uses default include pattern for class discovery