0
# Core Testing API
1
2
Essential testing annotations and lifecycle methods that form the foundation of JUnit Jupiter tests. These provide the basic structure for organizing and executing tests with modern Java features.
3
4
## Imports
5
6
```java
7
import org.junit.jupiter.api.*;
8
import static org.junit.jupiter.api.Assertions.*;
9
```
10
11
## Capabilities
12
13
### Test Annotation
14
15
Marks a method as a test method that should be executed by the test engine.
16
17
```java { .api }
18
/**
19
* Marks a method as a test method
20
*/
21
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})
22
@Retention(RetentionPolicy.RUNTIME)
23
@interface Test {
24
}
25
```
26
27
**Usage Example:**
28
29
```java
30
class MyTest {
31
@Test
32
void shouldCalculateCorrectly() {
33
// Test implementation
34
assertEquals(4, 2 + 2);
35
}
36
}
37
```
38
39
### Lifecycle Annotations
40
41
Control test execution lifecycle with setup and teardown methods.
42
43
```java { .api }
44
/**
45
* Executed once before all test methods in the class
46
* Method must be static
47
*/
48
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})
49
@Retention(RetentionPolicy.RUNTIME)
50
@interface BeforeAll {
51
}
52
53
/**
54
* Executed before each individual test method
55
*/
56
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})
57
@Retention(RetentionPolicy.RUNTIME)
58
@interface BeforeEach {
59
}
60
61
/**
62
* Executed after each individual test method
63
*/
64
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})
65
@Retention(RetentionPolicy.RUNTIME)
66
@interface AfterEach {
67
}
68
69
/**
70
* Executed once after all test methods in the class
71
* Method must be static
72
*/
73
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})
74
@Retention(RetentionPolicy.RUNTIME)
75
@interface AfterAll {
76
}
77
```
78
79
**Usage Example:**
80
81
```java
82
class DatabaseTest {
83
static Database database;
84
Connection connection;
85
86
@BeforeAll
87
static void initDatabase() {
88
database = new Database();
89
database.start();
90
}
91
92
@AfterAll
93
static void cleanupDatabase() {
94
database.stop();
95
}
96
97
@BeforeEach
98
void openConnection() {
99
connection = database.openConnection();
100
}
101
102
@AfterEach
103
void closeConnection() {
104
if (connection != null) {
105
connection.close();
106
}
107
}
108
109
@Test
110
void testQuery() {
111
// Test with connection
112
}
113
}
114
```
115
116
### Display Names
117
118
Customize test names for better readability in test reports.
119
120
```java { .api }
121
/**
122
* Custom display name for tests and test classes
123
*/
124
@Target({ElementType.TYPE, ElementType.METHOD})
125
@Retention(RetentionPolicy.RUNTIME)
126
@interface DisplayName {
127
String value();
128
}
129
130
/**
131
* Generate display names using a specific strategy
132
*/
133
@Target({ElementType.TYPE})
134
@Retention(RetentionPolicy.RUNTIME)
135
@interface DisplayNameGeneration {
136
Class<? extends DisplayNameGenerator> value();
137
}
138
```
139
140
**Usage Example:**
141
142
```java
143
@DisplayName("Calculator Tests")
144
class CalculatorTest {
145
146
@Test
147
@DisplayName("Addition should work for positive numbers")
148
void testAddition() {
149
assertEquals(5, 2 + 3);
150
}
151
152
@Test
153
@DisplayName("Division by zero should throw exception")
154
void testDivisionByZero() {
155
assertThrows(ArithmeticException.class, () -> 10 / 0);
156
}
157
}
158
```
159
160
### Display Name Generators
161
162
Built-in strategies for generating display names automatically.
163
164
```java { .api }
165
interface DisplayNameGenerator {
166
String generateDisplayNameForClass(Class<?> testClass);
167
String generateDisplayNameForNestedClass(Class<?> nestedClass);
168
String generateDisplayNameForMethod(Class<?> testClass, Method testMethod);
169
170
class Standard implements DisplayNameGenerator { }
171
class Simple implements DisplayNameGenerator { }
172
class ReplaceUnderscores implements DisplayNameGenerator { }
173
class IndicativeSentences implements DisplayNameGenerator { }
174
}
175
```
176
177
### Nested Tests
178
179
Organize related tests in hierarchical structure using nested classes.
180
181
```java { .api }
182
/**
183
* Marks a nested class as a test class
184
*/
185
@Target(ElementType.TYPE)
186
@Retention(RetentionPolicy.RUNTIME)
187
@interface Nested {
188
}
189
```
190
191
**Usage Example:**
192
193
```java
194
class AccountTest {
195
196
@Test
197
void testCreateAccount() {
198
// Test account creation
199
}
200
201
@Nested
202
@DisplayName("When account has balance")
203
class WhenAccountHasBalance {
204
205
Account account;
206
207
@BeforeEach
208
void createAccountWithBalance() {
209
account = new Account(100);
210
}
211
212
@Test
213
@DisplayName("withdraw should decrease balance")
214
void withdrawShouldDecreaseBalance() {
215
account.withdraw(20);
216
assertEquals(80, account.getBalance());
217
}
218
219
@Nested
220
@DisplayName("And withdrawal amount exceeds balance")
221
class AndWithdrawalExceedsBalance {
222
223
@Test
224
@DisplayName("should throw InsufficientFundsException")
225
void shouldThrowException() {
226
assertThrows(InsufficientFundsException.class,
227
() -> account.withdraw(150));
228
}
229
}
230
}
231
}
232
```
233
234
### Test Disabling
235
236
Disable tests temporarily or conditionally.
237
238
```java { .api }
239
/**
240
* Disable test execution with optional reason
241
*/
242
@Target({ElementType.TYPE, ElementType.METHOD})
243
@Retention(RetentionPolicy.RUNTIME)
244
@interface Disabled {
245
String value() default "";
246
}
247
```
248
249
**Usage Example:**
250
251
```java
252
class FeatureTest {
253
254
@Test
255
@Disabled("Feature not yet implemented")
256
void testNewFeature() {
257
// This test won't run
258
}
259
260
@Test
261
@Disabled
262
void temporarilyDisabled() {
263
// This test won't run either
264
}
265
}
266
```
267
268
### Test Tagging
269
270
Tag tests for filtering and selective execution.
271
272
```java { .api }
273
/**
274
* Tag a test for filtering
275
*/
276
@Target({ElementType.TYPE, ElementType.METHOD})
277
@Retention(RetentionPolicy.RUNTIME)
278
@Repeatable(Tags.class)
279
@interface Tag {
280
String value();
281
}
282
283
/**
284
* Container for multiple tags
285
*/
286
@Target({ElementType.TYPE, ElementType.METHOD})
287
@Retention(RetentionPolicy.RUNTIME)
288
@interface Tags {
289
Tag[] value();
290
}
291
```
292
293
**Usage Example:**
294
295
```java
296
class IntegrationTest {
297
298
@Test
299
@Tag("fast")
300
void testQuickOperation() {
301
// Fast test
302
}
303
304
@Test
305
@Tag("slow")
306
@Tag("integration")
307
void testDatabaseIntegration() {
308
// Slow integration test
309
}
310
311
@Test
312
@Tags({@Tag("smoke"), @Tag("critical")})
313
void testCriticalPath() {
314
// Critical smoke test
315
}
316
}
317
```
318
319
### Repeated Tests
320
321
Execute the same test multiple times with repetition information.
322
323
```java { .api }
324
/**
325
* Repeat test execution multiple times
326
*/
327
@Target(ElementType.METHOD)
328
@Retention(RetentionPolicy.RUNTIME)
329
@interface RepeatedTest {
330
int value();
331
String name() default "";
332
}
333
```
334
335
**Usage Example:**
336
337
```java
338
class RandomTest {
339
340
@RepeatedTest(10)
341
void testRandomBehavior() {
342
int random = (int) (Math.random() * 100);
343
assertTrue(random >= 0 && random < 100);
344
}
345
346
@RepeatedTest(value = 5, name = "Run {currentRepetition} of {totalRepetitions}")
347
void testWithCustomName(RepetitionInfo repetitionInfo) {
348
System.out.println("Repetition: " + repetitionInfo.getCurrentRepetition());
349
}
350
}
351
```
352
353
### Test Information
354
355
Access test metadata at runtime.
356
357
```java { .api }
358
interface TestInfo {
359
String getDisplayName();
360
Set<String> getTags();
361
Optional<Class<?>> getTestClass();
362
Optional<Method> getTestMethod();
363
}
364
365
interface RepetitionInfo {
366
int getCurrentRepetition();
367
int getTotalRepetitions();
368
}
369
```
370
371
**Usage Example:**
372
373
```java
374
class InfoTest {
375
376
@Test
377
void testWithInfo(TestInfo testInfo) {
378
System.out.println("Test name: " + testInfo.getDisplayName());
379
System.out.println("Tags: " + testInfo.getTags());
380
}
381
382
@RepeatedTest(3)
383
void repeatedTestWithInfo(RepetitionInfo repetitionInfo) {
384
System.out.println("Repetition " + repetitionInfo.getCurrentRepetition()
385
+ " of " + repetitionInfo.getTotalRepetitions());
386
}
387
}
388
```
389
390
### Test Ordering
391
392
Control the order of test execution.
393
394
```java { .api }
395
/**
396
* Configure test method execution order
397
*/
398
@Target(ElementType.TYPE)
399
@Retention(RetentionPolicy.RUNTIME)
400
@interface TestMethodOrder {
401
Class<? extends MethodOrderer> value();
402
}
403
404
/**
405
* Configure test class execution order
406
*/
407
@Target(ElementType.TYPE)
408
@Retention(RetentionPolicy.RUNTIME)
409
@interface TestClassOrder {
410
Class<? extends ClassOrderer> value();
411
}
412
413
/**
414
* Specify execution order
415
*/
416
@Target({ElementType.TYPE, ElementType.METHOD})
417
@Retention(RetentionPolicy.RUNTIME)
418
@interface Order {
419
int value();
420
}
421
```
422
423
**Usage Example:**
424
425
```java
426
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
427
class OrderedTest {
428
429
@Test
430
@Order(3)
431
void testThird() {
432
// Runs third
433
}
434
435
@Test
436
@Order(1)
437
void testFirst() {
438
// Runs first
439
}
440
441
@Test
442
@Order(2)
443
void testSecond() {
444
// Runs second
445
}
446
}
447
```
448
449
### Test Instance Lifecycle
450
451
Control how test instances are created and managed.
452
453
```java { .api }
454
/**
455
* Configure test instance lifecycle
456
*/
457
@Target(ElementType.TYPE)
458
@Retention(RetentionPolicy.RUNTIME)
459
@interface TestInstance {
460
Lifecycle value();
461
462
enum Lifecycle {
463
PER_METHOD, // Default: new instance per test method
464
PER_CLASS // One instance per test class
465
}
466
}
467
```
468
469
**Usage Example:**
470
471
```java
472
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
473
class SharedStateTest {
474
int counter = 0;
475
476
@Test
477
void firstTest() {
478
counter++;
479
assertEquals(1, counter);
480
}
481
482
@Test
483
void secondTest() {
484
counter++;
485
assertEquals(2, counter); // Works because same instance
486
}
487
}
488
```
489
490
### Test Timeouts
491
492
Configure execution timeouts for individual tests or entire test classes.
493
494
```java { .api }
495
/**
496
* Configure test execution timeout
497
*/
498
@Target({ElementType.TYPE, ElementType.METHOD})
499
@Retention(RetentionPolicy.RUNTIME)
500
@interface Timeout {
501
/**
502
* Timeout value
503
*/
504
long value();
505
506
/**
507
* Time unit for timeout value
508
*/
509
TimeUnit unit() default TimeUnit.SECONDS;
510
511
/**
512
* Thread mode for timeout enforcement
513
*/
514
ThreadMode threadMode() default ThreadMode.SAME_THREAD;
515
516
enum ThreadMode {
517
/**
518
* Execute in same thread with timeout monitoring
519
*/
520
SAME_THREAD,
521
522
/**
523
* Execute in separate thread and interrupt on timeout
524
*/
525
SEPARATE_THREAD
526
}
527
}
528
```
529
530
**Usage Examples:**
531
532
```java
533
class TimeoutTest {
534
535
@Test
536
@Timeout(5) // 5 seconds
537
void testWithTimeout() throws InterruptedException {
538
Thread.sleep(1000); // Will pass
539
}
540
541
@Test
542
@Timeout(value = 500, unit = TimeUnit.MILLISECONDS)
543
void testWithMillisecondTimeout() {
544
// Test must complete within 500ms
545
performQuickOperation();
546
}
547
548
@Test
549
@Timeout(value = 10, threadMode = Timeout.ThreadMode.SEPARATE_THREAD)
550
void testWithSeparateThread() throws InterruptedException {
551
// Will be interrupted after 10 seconds if still running
552
Thread.sleep(5000);
553
}
554
}
555
556
@Timeout(30) // Default 30 second timeout for all tests in class
557
class SlowTestsWithTimeout {
558
559
@Test
560
void slowTest1() throws InterruptedException {
561
Thread.sleep(10000); // 10 seconds - within class timeout
562
}
563
564
@Test
565
@Timeout(60) // Override class timeout for this test
566
void verySlowTest() throws InterruptedException {
567
Thread.sleep(45000); // 45 seconds - within method timeout
568
}
569
}
570
```