0
# JUnit 4
1
2
JUnit 4 is a widely-used unit testing framework for Java, created by Erich Gamma and Kent Beck. It provides a comprehensive set of annotations, assertions, and runners for writing and executing automated tests. JUnit 4 uses annotations to mark test methods and control test execution, making it simple to create well-structured test suites.
3
4
## Package Information
5
6
- **Package Name**: junit:junit
7
- **Package Type**: maven
8
- **Language**: Java
9
- **Installation**:
10
11
Maven:
12
```xml
13
<dependency>
14
<groupId>junit</groupId>
15
<artifactId>junit</artifactId>
16
<version>4.13.2</version>
17
<scope>test</scope>
18
</dependency>
19
```
20
21
Gradle:
22
```groovy
23
testImplementation 'junit:junit:4.13.2'
24
```
25
26
## Core Imports
27
28
```java
29
import org.junit.Test;
30
import org.junit.Before;
31
import org.junit.After;
32
import org.junit.BeforeClass;
33
import org.junit.AfterClass;
34
import org.junit.Ignore;
35
import static org.junit.Assert.*;
36
```
37
38
For running tests:
39
```java
40
import org.junit.runner.JUnitCore;
41
import org.junit.runner.Result;
42
```
43
44
For rules:
45
```java
46
import org.junit.Rule;
47
import org.junit.ClassRule;
48
import org.junit.rules.*;
49
```
50
51
## Basic Usage
52
53
```java
54
import org.junit.*;
55
import static org.junit.Assert.*;
56
57
public class CalculatorTest {
58
private Calculator calculator;
59
60
@BeforeClass
61
public static void setUpClass() {
62
System.out.println("Running Calculator tests");
63
}
64
65
@Before
66
public void setUp() {
67
calculator = new Calculator();
68
}
69
70
@Test
71
public void testAddition() {
72
assertEquals(5, calculator.add(2, 3));
73
}
74
75
@Test
76
public void testSubtraction() {
77
assertEquals(1, calculator.subtract(3, 2));
78
}
79
80
@Test(expected = ArithmeticException.class)
81
public void testDivisionByZero() {
82
calculator.divide(10, 0);
83
}
84
85
@Test(timeout = 1000)
86
public void testPerformance() {
87
calculator.complexCalculation();
88
}
89
90
@After
91
public void tearDown() {
92
calculator = null;
93
}
94
95
@AfterClass
96
public static void tearDownClass() {
97
System.out.println("Calculator tests complete");
98
}
99
}
100
```
101
102
## Architecture
103
104
JUnit 4's architecture is built around several key components:
105
106
- **Annotations**: Declarative markers (`@Test`, `@Before`, `@After`, etc.) that define test structure and lifecycle
107
- **Assertions**: Static methods in the `Assert` class for verifying expected behavior
108
- **Runners**: Execute tests and report results. The default `BlockJUnit4ClassRunner` processes annotated test classes, while custom runners like `Suite` and `Parameterized` enable advanced scenarios
109
- **Rules**: Reusable components (`@Rule`, `@ClassRule`) that add behavior around test methods, such as temporary file creation or timeout enforcement
110
- **Test Lifecycle**: Methods annotated with `@BeforeClass` and `@AfterClass` run once per test class, while `@Before` and `@After` run before and after each test method
111
- **Result Reporting**: The `Result` class collects test outcomes, failures, and timing information
112
113
This design allows JUnit to provide a flexible, extensible framework for Java testing while maintaining simplicity for common use cases.
114
115
## Capabilities
116
117
### Test Annotations
118
119
Declarative annotations for marking test methods and controlling test execution lifecycle. These annotations define which methods are tests, how they should be executed, and what setup/teardown is required.
120
121
```java { .api }
122
@Target(ElementType.METHOD)
123
@Retention(RetentionPolicy.RUNTIME)
124
public @interface Test {
125
Class<? extends Throwable> expected() default None.class;
126
long timeout() default 0L;
127
}
128
129
@Target(ElementType.METHOD)
130
@Retention(RetentionPolicy.RUNTIME)
131
public @interface Before {}
132
133
@Target(ElementType.METHOD)
134
@Retention(RetentionPolicy.RUNTIME)
135
public @interface After {}
136
137
@Target(ElementType.METHOD)
138
@Retention(RetentionPolicy.RUNTIME)
139
public @interface BeforeClass {}
140
141
@Target(ElementType.METHOD)
142
@Retention(RetentionPolicy.RUNTIME)
143
public @interface AfterClass {}
144
145
@Target({ElementType.METHOD, ElementType.TYPE})
146
@Retention(RetentionPolicy.RUNTIME)
147
public @interface Ignore {
148
String value() default "";
149
}
150
```
151
152
[Test Annotations](./annotations.md)
153
154
### Assertions
155
156
Comprehensive assertion methods for verifying expected behavior in tests. The `Assert` class provides static methods for comparing values, checking conditions, and validating object states.
157
158
```java { .api }
159
public class Assert {
160
public static void assertEquals(String message, Object expected, Object actual);
161
public static void assertEquals(Object expected, Object actual);
162
public static void assertTrue(String message, boolean condition);
163
public static void assertTrue(boolean condition);
164
public static void assertFalse(String message, boolean condition);
165
public static void assertFalse(boolean condition);
166
public static void assertNull(String message, Object object);
167
public static void assertNull(Object object);
168
public static void assertNotNull(String message, Object object);
169
public static void assertNotNull(Object object);
170
public static void assertSame(String message, Object expected, Object actual);
171
public static void assertSame(Object expected, Object actual);
172
public static void assertNotSame(String message, Object unexpected, Object actual);
173
public static void assertNotSame(Object unexpected, Object actual);
174
public static void assertArrayEquals(String message, Object[] expecteds, Object[] actuals);
175
public static void assertArrayEquals(Object[] expecteds, Object[] actuals);
176
public static <T extends Throwable> T assertThrows(Class<T> expectedThrowable, ThrowingRunnable runnable);
177
public static void fail(String message);
178
public static void fail();
179
}
180
```
181
182
[Assertions](./assertions.md)
183
184
### Assumptions
185
186
Methods for conditionally skipping tests based on runtime conditions. When an assumption fails, the test is marked as skipped rather than failed, useful for environment-specific tests.
187
188
```java { .api }
189
public class Assume {
190
public static void assumeTrue(boolean condition);
191
public static void assumeTrue(String message, boolean condition);
192
public static void assumeFalse(boolean condition);
193
public static void assumeFalse(String message, boolean condition);
194
public static void assumeNotNull(Object... objects);
195
public static <T> void assumeThat(T actual, Matcher<T> matcher);
196
public static void assumeNoException(Throwable t);
197
}
198
```
199
200
[Assumptions](./assumptions.md)
201
202
### Test Runners
203
204
Core classes for executing tests and collecting results. `JUnitCore` provides the main API for running tests programmatically, while the `Runner` class hierarchy enables custom test execution strategies.
205
206
```java { .api }
207
public class JUnitCore {
208
public static void main(String... args);
209
public Result run(Class<?>... classes);
210
public Result run(Request request);
211
public Result runClasses(Class<?>... classes);
212
public void addListener(RunListener listener);
213
public void removeListener(RunListener listener);
214
}
215
216
public abstract class Runner implements Describable {
217
public abstract Description getDescription();
218
public abstract void run(RunNotifier notifier);
219
public int testCount();
220
}
221
222
public class Result {
223
public int getRunCount();
224
public int getFailureCount();
225
public int getIgnoreCount();
226
public long getRunTime();
227
public List<Failure> getFailures();
228
public boolean wasSuccessful();
229
}
230
```
231
232
[Test Runners](./test-runners.md)
233
234
### Standard Runners
235
236
Built-in test runners for common scenarios including the standard JUnit 4 runner, test suites, and parameterized tests that run the same test with different data.
237
238
```java { .api }
239
public class BlockJUnit4ClassRunner extends ParentRunner<FrameworkMethod> {
240
public BlockJUnit4ClassRunner(Class<?> testClass) throws InitializationError;
241
}
242
243
public class Suite extends ParentRunner<Runner> {
244
public Suite(Class<?> klass, Class<?>[] suiteClasses) throws InitializationError;
245
246
@Retention(RetentionPolicy.RUNTIME)
247
@Target(ElementType.TYPE)
248
public @interface SuiteClasses {
249
Class<?>[] value();
250
}
251
}
252
253
public class Parameterized extends Suite {
254
public Parameterized(Class<?> klass) throws Throwable;
255
256
@Retention(RetentionPolicy.RUNTIME)
257
@Target(ElementType.METHOD)
258
public @interface Parameters {
259
String name() default "{index}";
260
}
261
262
@Retention(RetentionPolicy.RUNTIME)
263
@Target(ElementType.FIELD)
264
public @interface Parameter {
265
int value() default 0;
266
}
267
}
268
```
269
270
[Standard Runners](./standard-runners.md)
271
272
### Rules
273
274
The rule system provides reusable test behavior that can be applied to test methods or entire test classes. Rules wrap test execution with custom logic for resource management, verification, and more.
275
276
```java { .api }
277
public interface TestRule {
278
Statement apply(Statement base, Description description);
279
}
280
281
@Retention(RetentionPolicy.RUNTIME)
282
@Target({ElementType.FIELD, ElementType.METHOD})
283
public @interface Rule {}
284
285
@Retention(RetentionPolicy.RUNTIME)
286
@Target({ElementType.FIELD, ElementType.METHOD})
287
public @interface ClassRule {}
288
```
289
290
[Rules](./rules.md)
291
292
### Categories
293
294
Experimental feature for grouping and filtering tests by category markers. Allows selective test execution based on custom category interfaces.
295
296
```java { .api }
297
@Retention(RetentionPolicy.RUNTIME)
298
@Target({ElementType.TYPE, ElementType.METHOD})
299
public @interface Category {
300
Class<?>[] value();
301
}
302
303
public class Categories extends Suite {
304
@Retention(RetentionPolicy.RUNTIME)
305
@Target(ElementType.TYPE)
306
public @interface IncludeCategory {
307
Class<?> value();
308
}
309
310
@Retention(RetentionPolicy.RUNTIME)
311
@Target(ElementType.TYPE)
312
public @interface ExcludeCategory {
313
Class<?> value();
314
}
315
}
316
```
317
318
[Categories](./categories.md)
319
320
### Theories
321
322
Experimental feature for property-based testing where tests are theories proven against multiple data points. Theories are parameterized tests with data point injection.
323
324
```java { .api }
325
@Retention(RetentionPolicy.RUNTIME)
326
@Target(ElementType.METHOD)
327
public @interface Theory {}
328
329
@Retention(RetentionPolicy.RUNTIME)
330
@Target({ElementType.FIELD, ElementType.METHOD})
331
public @interface DataPoint {
332
String[] value() default {};
333
}
334
335
@Retention(RetentionPolicy.RUNTIME)
336
@Target({ElementType.FIELD, ElementType.METHOD})
337
public @interface DataPoints {
338
String[] value() default {};
339
}
340
341
public class Theories extends BlockJUnit4ClassRunner {
342
public Theories(Class<?> klass) throws InitializationError;
343
}
344
```
345
346
[Theories](./theories.md)
347
348
### Matchers
349
350
Integration with Hamcrest matchers for expressive assertions. Matchers provide readable, composable conditions for test verification.
351
352
```java { .api }
353
public class Assert {
354
public static <T> void assertThat(T actual, Matcher<? super T> matcher);
355
public static <T> void assertThat(String reason, T actual, Matcher<? super T> matcher);
356
}
357
358
public class JUnitMatchers {
359
public static Matcher<String> containsString(String substring);
360
public static <T> CombinableBothMatcher<T> both(Matcher<? super T> matcher);
361
public static <T> CombinableEitherMatcher<T> either(Matcher<? super T> matcher);
362
public static <T extends Throwable> Matcher<T> isThrowable(Matcher<T> causeMatcher);
363
public static <T extends Exception> Matcher<T> isException(Matcher<T> causeMatcher);
364
}
365
```
366
367
[Matchers](./matchers.md)
368
369
## Types
370
371
```java { .api }
372
@FunctionalInterface
373
public interface ThrowingRunnable {
374
void run() throws Throwable;
375
}
376
377
public class Description implements Serializable {
378
// Constants
379
public static final Description EMPTY;
380
public static final Description TEST_MECHANISM;
381
382
// Factory methods for test descriptions
383
public static Description createTestDescription(String className, String name, Annotation... annotations);
384
public static Description createTestDescription(String className, String name, Serializable uniqueId);
385
public static Description createTestDescription(Class<?> clazz, String name);
386
public static Description createTestDescription(Class<?> clazz, String name, Annotation... annotations);
387
388
// Factory methods for suite descriptions
389
public static Description createSuiteDescription(String name, Annotation... annotations);
390
public static Description createSuiteDescription(String name, Serializable uniqueId, Annotation... annotations);
391
public static Description createSuiteDescription(Class<?> testClass);
392
public static Description createSuiteDescription(Class<?> testClass, Annotation... annotations);
393
394
// Naming methods
395
public String getClassName();
396
public String getMethodName();
397
public String getDisplayName();
398
399
// Type checking
400
public boolean isTest();
401
public boolean isSuite();
402
public boolean isEmpty();
403
404
// Children management
405
public void addChild(Description description);
406
public ArrayList<Description> getChildren();
407
public Description childlessCopy();
408
409
// Counting
410
public int testCount();
411
412
// Annotations
413
public <T extends Annotation> T getAnnotation(Class<T> annotationType);
414
public Collection<Annotation> getAnnotations();
415
416
// Class information
417
public Class<?> getTestClass();
418
}
419
420
public class Failure implements Serializable {
421
public Failure(Description description, Throwable thrownException);
422
public Description getDescription();
423
public Throwable getException();
424
public String getMessage();
425
public String getTrace();
426
}
427
428
public abstract class Statement {
429
public abstract void evaluate() throws Throwable;
430
}
431
```
432