0
# Core Testing Framework
1
2
Essential testing annotations, assertions, and lifecycle management providing the foundation for all JUnit Jupiter testing scenarios. This includes test method marking, setup/teardown hooks, comprehensive assertion methods, and test organization features.
3
4
## Capabilities
5
6
### Test Annotations
7
8
Core annotations for marking test methods and controlling test lifecycle.
9
10
```java { .api }
11
/**
12
* Marks a method as a test method. Test methods must not be private or static and must not return a value.
13
*/
14
@Test
15
16
/**
17
* Executed before each test method in the current class
18
*/
19
@BeforeEach
20
21
/**
22
* Executed after each test method in the current class
23
*/
24
@AfterEach
25
26
/**
27
* Executed once before all test methods in the current class (static methods only)
28
*/
29
@BeforeAll
30
31
/**
32
* Executed once after all test methods in the current class (static methods only)
33
*/
34
@AfterAll
35
```
36
37
**Usage Examples:**
38
39
```java
40
import org.junit.jupiter.api.*;
41
42
class UserServiceTest {
43
44
private UserService userService;
45
private static DatabaseConnection connection;
46
47
@BeforeAll
48
static void initDatabase() {
49
connection = DatabaseConnection.create();
50
}
51
52
@BeforeEach
53
void setUp() {
54
userService = new UserService(connection);
55
}
56
57
@Test
58
void shouldCreateUser() {
59
User user = userService.createUser("john", "john@example.com");
60
assertNotNull(user);
61
assertEquals("john", user.getName());
62
}
63
64
@AfterEach
65
void tearDown() {
66
userService.cleanup();
67
}
68
69
@AfterAll
70
static void closeDatabase() {
71
connection.close();
72
}
73
}
74
```
75
76
### Test Organization
77
78
Annotations for organizing, describing, and controlling test execution.
79
80
```java { .api }
81
/**
82
* Provides a custom display name for the test class or test method
83
* @param value Custom display name
84
*/
85
@DisplayName(String value)
86
87
/**
88
* Disables a test class or test method
89
* @param value Optional reason for disabling
90
*/
91
@Disabled(String value)
92
93
/**
94
* Tags a test class or test method for filtering during test execution
95
* @param value Tag name
96
*/
97
@Tag(String value)
98
99
/**
100
* Container for multiple @Tag annotations
101
*/
102
@Tags({@Tag("integration"), @Tag("slow")})
103
104
/**
105
* Marks a test class as a nested test class
106
*/
107
@Nested
108
```
109
110
**Usage Examples:**
111
112
```java
113
@DisplayName("User Account Management")
114
class UserAccountTest {
115
116
@Test
117
@DisplayName("Creating user with valid email should succeed")
118
@Tag("unit")
119
void validEmailCreation() {
120
// test implementation
121
}
122
123
@Test
124
@Disabled("Feature not implemented yet")
125
void premiumFeatureTest() {
126
// test implementation
127
}
128
129
@Nested
130
@DisplayName("Password Management")
131
class PasswordTests {
132
133
@Test
134
@Tags({@Tag("security"), @Tag("integration")})
135
void shouldEncryptPassword() {
136
// nested test implementation
137
}
138
}
139
}
140
```
141
142
### Assertion Methods
143
144
Comprehensive static assertion methods in the Assertions class for validating test conditions.
145
146
```java { .api }
147
import java.util.function.Supplier;
148
149
/**
150
* Boolean assertions
151
*/
152
static void assertTrue(boolean condition);
153
static void assertTrue(boolean condition, String message);
154
static void assertTrue(boolean condition, Supplier<String> messageSupplier);
155
static void assertFalse(boolean condition);
156
static void assertFalse(boolean condition, String message);
157
static void assertFalse(boolean condition, Supplier<String> messageSupplier);
158
159
/**
160
* Equality assertions
161
*/
162
static void assertEquals(Object expected, Object actual);
163
static void assertEquals(Object expected, Object actual, String message);
164
static void assertEquals(Object expected, Object actual, Supplier<String> messageSupplier);
165
static void assertNotEquals(Object unexpected, Object actual);
166
static void assertNotEquals(Object unexpected, Object actual, String message);
167
168
/**
169
* Null checks
170
*/
171
static void assertNull(Object actual);
172
static void assertNull(Object actual, String message);
173
static void assertNotNull(Object actual);
174
static void assertNotNull(Object actual, String message);
175
176
/**
177
* Reference equality
178
*/
179
static void assertSame(Object expected, Object actual);
180
static void assertSame(Object expected, Object actual, String message);
181
static void assertNotSame(Object unexpected, Object actual);
182
static void assertNotSame(Object unexpected, Object actual, String message);
183
```
184
185
**Usage Examples:**
186
187
```java
188
import static org.junit.jupiter.api.Assertions.*;
189
190
@Test
191
void testUserCreation() {
192
// Boolean assertions
193
assertTrue(user.isActive(), "User should be active by default");
194
assertFalse(user.isDeleted());
195
196
// Equality assertions
197
assertEquals("john", user.getName());
198
assertEquals(25, user.getAge(), "Age should match");
199
assertNotEquals("admin", user.getRole());
200
201
// Null checks
202
assertNotNull(user.getId(), "User ID should not be null");
203
assertNotNull(user.getCreatedAt());
204
205
// Reference equality
206
User sameUser = userRepository.findById(user.getId());
207
assertEquals(user, sameUser); // value equality
208
assertNotSame(user, sameUser); // different object references
209
}
210
```
211
212
### Exception Testing
213
214
Assertions for testing expected exceptions and error conditions.
215
216
```java { .api }
217
import java.util.function.Supplier;
218
import org.junit.jupiter.api.function.Executable;
219
import org.junit.jupiter.api.function.ThrowingSupplier;
220
221
/**
222
* Assert that execution throws an exception of specified type
223
*/
224
static <T extends Throwable> T assertThrows(Class<T> expectedType, Executable executable);
225
static <T extends Throwable> T assertThrows(Class<T> expectedType, Executable executable, String message);
226
static <T extends Throwable> T assertThrows(Class<T> expectedType, Executable executable, Supplier<String> messageSupplier);
227
228
/**
229
* Assert that execution does not throw any exception
230
*/
231
static void assertDoesNotThrow(Executable executable);
232
static void assertDoesNotThrow(Executable executable, String message);
233
static <T> T assertDoesNotThrow(ThrowingSupplier<T> supplier);
234
static <T> T assertDoesNotThrow(ThrowingSupplier<T> supplier, String message);
235
```
236
237
**Usage Examples:**
238
239
```java
240
@Test
241
void testExceptionHandling() {
242
UserService userService = new UserService();
243
244
// Test expected exception
245
IllegalArgumentException exception = assertThrows(
246
IllegalArgumentException.class,
247
() -> userService.createUser(null, "email@example.com"),
248
"Creating user with null name should throw IllegalArgumentException"
249
);
250
assertEquals("Name cannot be null", exception.getMessage());
251
252
// Test no exception thrown
253
assertDoesNotThrow(() -> userService.createUser("john", "john@example.com"));
254
255
// Test no exception with return value
256
User user = assertDoesNotThrow(() -> userService.findById(123L));
257
assertNotNull(user);
258
}
259
```
260
261
### Timeout Assertions
262
263
Assertions for testing execution time constraints.
264
265
```java { .api }
266
import java.time.Duration;
267
import org.junit.jupiter.api.function.Executable;
268
import org.junit.jupiter.api.function.ThrowingSupplier;
269
270
/**
271
* Assert that execution completes before the given timeout
272
*/
273
static void assertTimeout(Duration timeout, Executable executable);
274
static void assertTimeout(Duration timeout, Executable executable, String message);
275
static <T> T assertTimeout(Duration timeout, ThrowingSupplier<T> supplier);
276
static <T> T assertTimeout(Duration timeout, ThrowingSupplier<T> supplier, String message);
277
278
/**
279
* Assert that execution completes before timeout, preemptively aborting if it exceeds
280
*/
281
static void assertTimeoutPreemptively(Duration timeout, Executable executable);
282
static void assertTimeoutPreemptively(Duration timeout, Executable executable, String message);
283
static <T> T assertTimeoutPreemptively(Duration timeout, ThrowingSupplier<T> supplier);
284
```
285
286
**Usage Examples:**
287
288
```java
289
import java.time.Duration;
290
291
@Test
292
void testPerformance() {
293
// Test completes within timeout (waits for completion)
294
assertTimeout(Duration.ofSeconds(2), () -> {
295
userService.processLargeDataSet();
296
}, "Data processing should complete within 2 seconds");
297
298
// Test completes within timeout, preemptively abort if exceeded
299
String result = assertTimeoutPreemptively(Duration.ofMillis(500), () -> {
300
return fastComputationService.calculate();
301
});
302
assertNotNull(result);
303
}
304
```
305
306
### Group Assertions
307
308
Assertions for validating multiple conditions together.
309
310
```java { .api }
311
import java.util.Collection;
312
import java.util.stream.Stream;
313
import org.junit.jupiter.api.function.Executable;
314
315
/**
316
* Group multiple assertions together - all are executed even if some fail
317
*/
318
static void assertAll(Executable... executables);
319
static void assertAll(String heading, Executable... executables);
320
static void assertAll(Collection<Executable> executables);
321
static void assertAll(String heading, Collection<Executable> executables);
322
static void assertAll(Stream<Executable> executables);
323
static void assertAll(String heading, Stream<Executable> executables);
324
```
325
326
**Usage Examples:**
327
328
```java
329
@Test
330
void testUserProperties() {
331
User user = userService.createUser("john", "john@example.com", 25);
332
333
// Group related assertions
334
assertAll("User properties",
335
() -> assertEquals("john", user.getName()),
336
() -> assertEquals("john@example.com", user.getEmail()),
337
() -> assertEquals(25, user.getAge()),
338
() -> assertTrue(user.isActive()),
339
() -> assertNotNull(user.getId())
340
);
341
342
// All assertions execute even if some fail
343
assertAll("Validation checks",
344
() -> assertTrue(user.getName().length() > 0),
345
() -> assertEquals("gmail.com", user.getEmail().split("@")[1]), // might fail
346
() -> assertTrue(user.getAge() >= 18) // still executes
347
);
348
}
349
```
350
351
### Collection and Array Assertions
352
353
Specialized assertions for collections, arrays, and iterables.
354
355
```java { .api }
356
/**
357
* Array equality assertions
358
*/
359
static void assertArrayEquals(Object[] expected, Object[] actual);
360
static void assertArrayEquals(Object[] expected, Object[] actual, String message);
361
static void assertArrayEquals(boolean[] expected, boolean[] actual);
362
static void assertArrayEquals(byte[] expected, byte[] actual);
363
static void assertArrayEquals(char[] expected, char[] actual);
364
static void assertArrayEquals(double[] expected, double[] actual, double delta);
365
static void assertArrayEquals(float[] expected, float[] actual, float delta);
366
static void assertArrayEquals(int[] expected, int[] actual);
367
static void assertArrayEquals(long[] expected, long[] actual);
368
static void assertArrayEquals(short[] expected, short[] actual);
369
370
/**
371
* Iterable equality assertions
372
*/
373
static void assertIterableEquals(Iterable<?> expected, Iterable<?> actual);
374
static void assertIterableEquals(Iterable<?> expected, Iterable<?> actual, String message);
375
376
/**
377
* Line-by-line string comparison
378
*/
379
static void assertLinesMatch(java.util.List<String> expectedLines, java.util.List<String> actualLines);
380
static void assertLinesMatch(java.util.List<String> expectedLines, java.util.List<String> actualLines, String message);
381
static void assertLinesMatch(java.util.stream.Stream<String> expectedLines, java.util.stream.Stream<String> actualLines);
382
```
383
384
**Usage Examples:**
385
386
```java
387
@Test
388
void testCollections() {
389
int[] expectedScores = {95, 87, 92, 88};
390
int[] actualScores = calculateScores();
391
assertArrayEquals(expectedScores, actualScores, "Scores should match expected values");
392
393
List<String> expectedNames = Arrays.asList("Alice", "Bob", "Charlie");
394
List<String> actualNames = userService.getUserNames();
395
assertIterableEquals(expectedNames, actualNames);
396
397
List<String> expectedOutput = Arrays.asList(
398
"Processing started",
399
">> \\d+ records processed", // regex pattern
400
"Processing completed"
401
);
402
List<String> actualOutput = captureConsoleOutput();
403
assertLinesMatch(expectedOutput, actualOutput);
404
}
405
```
406
407
### Type Assertions
408
409
Assertions for testing object types and instance relationships.
410
411
```java { .api }
412
/**
413
* Assert that an object is an instance of the expected type
414
*/
415
static <T> T assertInstanceOf(Class<T> expectedType, Object actualValue);
416
static <T> T assertInstanceOf(Class<T> expectedType, Object actualValue, String message);
417
static <T> T assertInstanceOf(Class<T> expectedType, Object actualValue, Supplier<String> messageSupplier);
418
```
419
420
**Usage Examples:**
421
422
```java
423
@Test
424
void testInstanceTypes() {
425
Object result = serviceFactory.createService("user");
426
427
// Assert type and get typed reference
428
UserService userService = assertInstanceOf(UserService.class, result,
429
"Factory should create UserService instance");
430
431
// Now can safely use typed methods
432
assertEquals("UserService", userService.getServiceName());
433
}
434
```
435
436
### Assumptions
437
438
Conditional test execution based on runtime conditions using the Assumptions class.
439
440
```java { .api }
441
import java.util.function.BooleanSupplier;
442
import java.util.function.Supplier;
443
import org.junit.jupiter.api.function.Executable;
444
445
/**
446
* Validate assumption and abort test if false
447
*/
448
static void assumeTrue(boolean assumption);
449
static void assumeTrue(boolean assumption, String message);
450
static void assumeTrue(boolean assumption, Supplier<String> messageSupplier);
451
static void assumeTrue(BooleanSupplier assumptionSupplier);
452
static void assumeTrue(BooleanSupplier assumptionSupplier, String message);
453
454
static void assumeFalse(boolean assumption);
455
static void assumeFalse(boolean assumption, String message);
456
static void assumeFalse(BooleanSupplier assumptionSupplier);
457
458
/**
459
* Execute executable only if assumption is true
460
*/
461
static void assumingThat(boolean assumption, Executable executable);
462
static void assumingThat(BooleanSupplier assumptionSupplier, Executable executable);
463
464
/**
465
* Explicitly abort test execution - generic return type allows use in expressions
466
*/
467
static <V> V abort();
468
static <V> V abort(String message);
469
static <V> V abort(Supplier<String> messageSupplier);
470
```
471
472
**Usage Examples:**
473
474
```java
475
import static org.junit.jupiter.api.Assumptions.*;
476
477
@Test
478
void testDatabaseFeature() {
479
// Assume database is available, abort test if not
480
assumeTrue(isDatabaseAvailable(), "Database must be available for this test");
481
482
// Test will only run if assumption passes
483
User user = userRepository.save(new User("test"));
484
assertNotNull(user.getId());
485
}
486
487
@Test
488
void testOptionalFeature() {
489
// Execute part of test only if condition met
490
assumingThat(isFeatureEnabled("premium"), () -> {
491
PremiumService service = new PremiumService();
492
assertTrue(service.isPremiumFeatureAvailable());
493
});
494
495
// This part always executes
496
BasicService basicService = new BasicService();
497
assertTrue(basicService.isBasicFeatureAvailable());
498
}
499
```
500
501
## Types
502
503
### Test Information Interfaces
504
505
```java { .api }
506
import java.lang.reflect.Method;
507
import java.util.Optional;
508
import java.util.Set;
509
import java.util.Map;
510
511
/**
512
* Provides information about the current test
513
*/
514
interface TestInfo {
515
String getDisplayName();
516
Set<String> getTags();
517
Optional<Class<?>> getTestClass();
518
Optional<Method> getTestMethod();
519
}
520
521
/**
522
* Publishes entries (key-value pairs) for the current test
523
*/
524
interface TestReporter {
525
void publishEntry(Map<String, String> map);
526
void publishEntry(String key, String value);
527
}
528
529
/**
530
* Information about the current repetition of a repeated test
531
*/
532
interface RepetitionInfo {
533
int getCurrentRepetition();
534
int getTotalRepetitions();
535
}
536
```
537
538
### Test Instance Lifecycle
539
540
```java { .api }
541
/**
542
* Configuration for test instance lifecycle
543
*/
544
@TestInstance(TestInstance.Lifecycle value)
545
546
enum TestInstance.Lifecycle {
547
/**
548
* New test instance created for each test method (default)
549
*/
550
PER_METHOD,
551
552
/**
553
* Same test instance used for all test methods in a class
554
*/
555
PER_CLASS
556
}
557
```
558
559
### Test Ordering
560
561
```java { .api }
562
/**
563
* Configure the order in which test methods are executed
564
*/
565
@TestMethodOrder(Class<? extends MethodOrderer> value)
566
567
/**
568
* Specify execution order for a test method
569
*/
570
@Order(int value)
571
572
/**
573
* Strategy interface for ordering test methods
574
*/
575
interface MethodOrderer {
576
void orderMethods(Context context);
577
578
// Built-in implementations
579
class DisplayName implements MethodOrderer { }
580
class MethodName implements MethodOrderer { }
581
class OrderAnnotation implements MethodOrderer { }
582
class Random implements MethodOrderer { }
583
}
584
```
585
586
### Repeated Tests
587
588
```java { .api }
589
/**
590
* Repeats a test a specified number of times
591
*/
592
@RepeatedTest(
593
int value,
594
String name = "",
595
FailureThreshold failureThreshold = @FailureThreshold
596
)
597
598
/**
599
* Controls when repeated test execution should stop on failures
600
*/
601
@FailureThreshold(int value)
602
```
603
604
### Dynamic Tests
605
606
```java { .api }
607
/**
608
* A test case generated at runtime
609
*/
610
class DynamicTest implements DynamicNode {
611
static DynamicTest dynamicTest(String displayName, Executable executable);
612
static DynamicTest dynamicTest(String displayName, java.net.URI testSourceUri, Executable executable);
613
614
static java.util.stream.Stream<DynamicTest> stream(java.util.Iterator<String> inputGenerator,
615
java.util.function.Function<String, String> displayNameGenerator,
616
ThrowingConsumer<String> testExecutor);
617
}
618
619
/**
620
* A container for dynamic tests
621
*/
622
class DynamicContainer implements DynamicNode {
623
static DynamicContainer dynamicContainer(String displayName, Iterable<? extends DynamicNode> dynamicNodes);
624
static DynamicContainer dynamicContainer(String displayName, java.net.URI testSourceUri, Iterable<? extends DynamicNode> dynamicNodes);
625
static DynamicContainer dynamicContainer(String displayName, java.util.stream.Stream<? extends DynamicNode> dynamicNodes);
626
}
627
628
/**
629
* Factory method for generating dynamic tests at runtime
630
*/
631
@TestFactory
632
```
633
634
### Named Interfaces
635
636
Container interfaces for associating names with payloads and executables for dynamic test generation.
637
638
```java { .api }
639
import org.junit.jupiter.api.Named;
640
import org.junit.jupiter.api.NamedExecutable;
641
import org.junit.jupiter.api.function.Executable;
642
643
/**
644
* Container that associates a name with a given payload
645
* @param <T> the type of the payload
646
*/
647
interface Named<T> {
648
/**
649
* Factory method for creating an instance of Named based on a name and a payload
650
* @param name the name associated with the payload; never null or blank
651
* @param payload the object that serves as the payload; may be null
652
* @param <T> the type of the payload
653
* @return an instance of Named; never null
654
*/
655
static <T> Named<T> of(String name, T payload);
656
657
/**
658
* Factory method for creating an instance of Named (alias for of method)
659
* @param name the name associated with the payload; never null or blank
660
* @param payload the object that serves as the payload; may be null
661
* @param <T> the type of the payload
662
* @return an instance of Named; never null
663
*/
664
static <T> Named<T> named(String name, T payload);
665
666
/**
667
* Get the name of the payload
668
* @return the name of the payload; never null or blank
669
*/
670
String getName();
671
672
/**
673
* Get the payload
674
* @return the payload; may be null depending on the use case
675
*/
676
T getPayload();
677
}
678
679
/**
680
* Joins Executable and Named in a single functional interface
681
*/
682
@FunctionalInterface
683
interface NamedExecutable extends Named<Executable>, Executable {
684
@Override
685
default String getName() {
686
return toString();
687
}
688
689
@Override
690
default Executable getPayload() {
691
return this;
692
}
693
}
694
```
695
696
### Complete DynamicTest Methods
697
698
Complete method signatures for all DynamicTest streaming methods with Named interfaces.
699
700
```java { .api }
701
import java.net.URI;
702
import java.util.Iterator;
703
import java.util.function.Function;
704
import java.util.stream.Stream;
705
import org.junit.jupiter.api.function.Executable;
706
import org.junit.jupiter.api.function.ThrowingConsumer;
707
import org.junit.jupiter.api.Named;
708
709
class DynamicTest implements DynamicNode {
710
// Basic factory methods
711
static DynamicTest dynamicTest(String displayName, Executable executable);
712
static DynamicTest dynamicTest(String displayName, URI testSourceUri, Executable executable);
713
714
// Stream with input generator and display name generator
715
static <T> Stream<DynamicTest> stream(Iterator<T> inputGenerator,
716
Function<? super T, String> displayNameGenerator,
717
ThrowingConsumer<? super T> testExecutor);
718
719
static <T> Stream<DynamicTest> stream(Stream<T> inputStream,
720
Function<? super T, String> displayNameGenerator,
721
ThrowingConsumer<? super T> testExecutor);
722
723
// Stream with Named input values
724
static <T> Stream<DynamicTest> stream(Iterator<? extends Named<T>> inputGenerator,
725
ThrowingConsumer<? super T> testExecutor);
726
727
static <T> Stream<DynamicTest> stream(Stream<? extends Named<T>> inputStream,
728
ThrowingConsumer<? super T> testExecutor);
729
730
// Stream with NamedExecutable (experimental)
731
static <T extends Named<E>, E extends Executable> Stream<DynamicTest> stream(
732
Iterator<? extends T> iterator);
733
734
static <T extends Named<E>, E extends Executable> Stream<DynamicTest> stream(
735
Stream<? extends T> inputStream);
736
}
737
```