JUnit 5 @BeforeAll and @AfterAll Example
April 17, 2018
This page will walk through JUnit 5 @BeforeAll
and @AfterAll
example. @BeforeAll
and @AfterAll
annotations are analogous to @BeforeClass
and @AfterClass
respectively of JUnit 4. @BeforeAll
and @AfterAll
methods execute before and after respectively of all @Test
, @RepeatedTest
, @ParameterizedTest
, or @TestFactory
methods in current class. It means @BeforeAll
method executes before all test methods in current class and @AfterAll
method executes after all test methods in current class. @BeforeAll
and @AfterAll
methods must be static and must not return a value. But in interface we can create non-static @BeforeAll
and @AfterAll
methods using @TestInstance
annotation and those methods will be default methods. Now find the complete example for @BeforeAll
and @AfterAll
annotations step by step.
Contents
- Technologies Used
- Gradle Build File
- Create Method using @BeforeAll and @AfterAll
- @BeforeAll and @AfterAll with @BeforeEach and @AfterEach
- @BeforeAll and @AfterAll with @Test, @RepeatedTest, @ParameterizedTest and @TestFactory
- @BeforeAll and @AfterAll with Interface Static Methods
- @BeforeAll and @AfterAll with Interface Non-Static Methods (Default Methods) using @TestInstance
- Reference
- Download Source Code
Technologies Used
Find the technologies being used in our example.1. Java 9
2. JUnit 5
3. Gradle 4.3.1
4. Eclipse Oxygen.3a
Gradle Build File
Find the Gradle build file to resolve the JUnit 5 JAR dependencies.build.gradle
apply plugin: 'java' apply plugin: 'eclipse' archivesBaseName = 'concretepage' version = '1' repositories { mavenCentral() } dependencies { testCompile group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.1.1' testCompile group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.1.1' testCompile group: 'org.junit.jupiter', name: 'junit-jupiter-params', version: '5.1.1' testCompile group: 'org.junit.platform', name: 'junit-platform-launcher', version: '1.1.1' }
Create Method using @BeforeAll and @AfterAll
@BeforeAll
and @AfterAll
methods must be static and must not return a value. Here we will create a test class using @Test
annotation. Find the example.
UsingTestAnnotation.java
package com.concretepage; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; public class UsingTestAnnotation { @BeforeAll static void initAll() { System.out.println("---Inside initAll---"); } @Test @DisplayName("Multiplication Test") void multiplyTest() { System.out.println("---Inside multiplyTest---"); Utility utility = new Utility(); assertEquals(30, utility.multiplyNumbers(5, 6), "6 * 5 will be 30"); } @AfterAll static void tearDownAll() { System.out.println("---Inside tearDownAll---"); } }
---Inside initAll--- ---Inside multiplyTest--- ---Inside tearDownAll---
Utility.java
package com.concretepage; import java.util.Arrays; import java.util.List; public class Utility { List<String> allUsers = Arrays.asList("Mahesh", "Ram", "Krishn", "Arjun", "Bheem"); public long multiplyNumbers(int num1, int num2) { return num1 * num2; } public long addNumbers(int num1, int num2) { return num1 + num2; } public boolean isUserAvailable(String userName) { return allUsers.contains(userName); } }
@BeforeAll and @AfterAll with @BeforeEach and @AfterEach
@BeforeEach
method executes after @BeforeAll
method. @AfterEach
method executes before @AfterAll
method. @BeforeAll
method executes before all test methods whereas @BeforeEach
method executes before each test method in the current class. @AfterAll
method executes after all test methods whereas @AfterEach
method executes after each test method in the current class. Find the example of @BeforeAll
and @AfterAll
methods with @BeforeEach
and @AfterEach
methods.
WithBeforeEachAfterEach.java
package com.concretepage; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInfo; public class WithBeforeEachAfterEach { @BeforeAll static void initAll() { System.out.println("---Inside initAll---"); } @BeforeEach void init(TestInfo testInfo) { System.out.println("Start..." + testInfo.getDisplayName()); } @Test @DisplayName("Multiplication Test") void multiplyTest() { System.out.println("---Inside multiplyTest---"); Utility utility = new Utility(); assertEquals(30, utility.multiplyNumbers(5, 6), "6 * 5 will be 30"); } @AfterEach void tearDown(TestInfo testInfo) { System.out.println("Finished..." + testInfo.getDisplayName()); } @AfterAll static void tearDownAll() { System.out.println("---Inside tearDownAll---"); } }
---Inside initAll--- Start...Multiplication Test ---Inside multiplyTest--- Finished...Multiplication Test ---Inside tearDownAll---
@BeforeAll and @AfterAll with @Test, @RepeatedTest, @ParameterizedTest and @TestFactory
Here we will use@BeforeAll
and @AfterAll
methods with @Test
, @RepeatedTest
, @ParameterizedTest
, and @TestFactory
methods. We will observe that @BeforeAll
method will execute before all test methods and @AfterAll
method will execute after all test methods.
MyJUnitTests.java
package com.concretepage; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.stream.Stream; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.RepeatedTest; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestFactory; import org.junit.jupiter.api.TestInfo; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; public class MyJUnitTests { @BeforeAll static void initAll() { System.out.println("---Inside initAll---"); } @BeforeEach void init(TestInfo testInfo) { System.out.println("Start..." + testInfo.getDisplayName()); } @Test @DisplayName("Multiplication Test") void multiplyTest() { System.out.println("---Inside multiplyTest---"); Utility utility = new Utility(); assertEquals(30, utility.multiplyNumbers(5, 6), "6 * 5 will be 30"); } @RepeatedTest(3) void repeatedMultiplicationTest() { System.out.println("---Inside repeatedMultiplicationTest---"); Utility utility = new Utility(); assertEquals(30, utility.multiplyNumbers(5, 6), "6 * 5 will be 30"); } @ParameterizedTest @ValueSource(strings = { "Krishn", "Arjun", "Bheem" }) void checkUserAvailabilityTest(String userName) { System.out.println("---Inside checkUserAvailabilityTest---"); Utility utility = new Utility(); assertTrue(utility.isUserAvailable(userName), "User will exist"); } @TestFactory @DisplayName("User Availability Test with @TestFactory") Stream<DynamicTest> userAvailabilityDynamicTest() { System.out.println("---Inside userAvailabilityDynamicTest---"); Utility utility = new Utility(); return Stream.of("Krishn", "Arjun", "Bheem") .map(userName -> DynamicTest.dynamicTest("Test " + userName, () -> { System.out.println(userName); assertTrue(utility.isUserAvailable(userName), "User will exist"); })); } @AfterEach void tearDown(TestInfo testInfo) { System.out.println("Finished..." + testInfo.getDisplayName()); } @AfterAll static void tearDownAll() { System.out.println("---Inside tearDownAll---"); } }
---Inside initAll--- Start...Multiplication Test ---Inside multiplyTest--- Finished...Multiplication Test Start...[1] Krishn ---Inside checkUserAvailabilityTest--- Finished...[1] Krishn Start...[2] Arjun ---Inside checkUserAvailabilityTest--- Finished...[2] Arjun Start...[3] Bheem ---Inside checkUserAvailabilityTest--- Finished...[3] Bheem Start...User Availability Test with @TestFactory ---Inside userAvailabilityDynamicTest--- Krishn Arjun Bheem Finished...User Availability Test with @TestFactory Start...repetition 1 of 3 ---Inside repeatedMultiplicationTest--- Finished...repetition 1 of 3 Start...repetition 2 of 3 ---Inside repeatedMultiplicationTest--- Finished...repetition 2 of 3 Start...repetition 3 of 3 ---Inside repeatedMultiplicationTest--- Finished...repetition 3 of 3 ---Inside tearDownAll---
@BeforeAll and @AfterAll with Interface Static Methods
We can use@BeforeAll
and @AfterAll
with interface static methods. We will create here a lifecycle logger using interface. To use our logger, we will create a class implementing the interface and then write test methods. Find the example.
LifecycleLogger.java
package com.concretepage; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.TestInfo; public interface LifecycleLogger { @BeforeAll static void initAll() { System.out.println("---Inside initAll---"); } @BeforeEach default void init(TestInfo testInfo) { System.out.println("Start..." + testInfo.getDisplayName()); } @AfterEach default void tearDown(TestInfo testInfo) { System.out.println("Finished..." + testInfo.getDisplayName()); } @AfterAll static void tearDownAll() { System.out.println("---Inside tearDownAll---"); } }
package com.concretepage; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; public class MyMultiplicationTest implements LifecycleLogger { @Test @DisplayName("Multiplication Test") void multiplyTest() { System.out.println("---Inside multiplyTest---"); Utility utility = new Utility(); assertEquals(30, utility.multiplyNumbers(5, 6), "6 * 5 will be 30"); } }
---Inside initAll--- Start...Multiplication Test ---Inside multiplyTest--- Finished...Multiplication Test ---Inside tearDownAll---
@BeforeAll and @AfterAll with Interface Non-Static Methods (Default Methods) using @TestInstance
We can use@BeforeAll
and @AfterAll
annotations with non-static methods (default methods) of interface using @TestInstance
annotation. @TestInstance
is a type-level annotation that is used to configure lifecycle of instances of annotated test class or test interface. @TestInstance
works with following lifecycle mode.
Lifecycle.PER_METHOD: A new test instance will be created for each test method or test factory method.
PER_METHOD
mode is the default mode when @TestInstance
has not explicitly declared on test class or test interface.
Lifecycle.PER_CLASS: A new test instance will be created once per test class. The advantage of
PER_CLASS
mode is that we can use non-static @BeforeAll
and @AfterAll
methods.
In our example we will create a lifecycle logger interface annotated with
@TestInstance
with mode Lifecycle.PER_CLASS
and we will create non-static @BeforeAll
and @AfterAll
methods as interface default methods. Find the example.
LifecycleLoggerWithTestInstance.java
package com.concretepage; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.TestInfo; import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.TestInstance.Lifecycle; @TestInstance(Lifecycle.PER_CLASS) public interface LifecycleLoggerWithTestInstance { @BeforeAll default void initAll() { System.out.println("---Inside initAll---"); } @BeforeEach default void init(TestInfo testInfo) { System.out.println("Start..." + testInfo.getDisplayName()); } @AfterEach default void tearDown(TestInfo testInfo) { System.out.println("Finished..." + testInfo.getDisplayName()); } @AfterAll default void tearDownAll() { System.out.println("---Inside tearDownAll---"); } }
package com.concretepage; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; public class MyAdditionTest implements LifecycleLoggerWithTestInstance { @Test @DisplayName("Add Test") void addTest() { System.out.println("---Inside addTest---"); Utility utility = new Utility(); assertEquals(11, utility.addNumbers(5, 6), "6 + 5 will be 11"); } }
---Inside initAll--- Start...Add Test ---Inside addTest--- Finished...Add Test ---Inside tearDownAll---
@RunWith(JUnitPlatform.class)
annotation. Eclipse Oxygen.1a onwards provides JUnit 5 environment. In our example, we are using Eclipse Oxygen.3a to run test classes.