JUnit 5 @BeforeAll and @AfterAll Example

By Arvind Rai, 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.

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---");
    }
} 
Output
---Inside initAll---
---Inside multiplyTest---
---Inside tearDownAll--- 
Find the sample utility class used in our example.
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---");
    }
} 
Output
---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---");
    }
} 
Output
---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---");
    }    
}
MyMultiplicationTest.java
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");
    }
} 
Output
---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---");
    }    
} 
MyAdditionTest.java
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");
    }    
} 
Output
---Inside initAll---
Start...Add Test
---Inside addTest---
Finished...Add Test
---Inside tearDownAll--- 
To run the example, download the source code and import into Eclipse Oxygen IDE. To run a test class, right click on the test class -> Run As -> JUnit Test. We will get output in console. If we are using JUnit 4 environment to run JUnit 5 examples then we need to annotate our test class with @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.

Reference

JUnit 5 User Guide

Download Source Code

POSTED BY
ARVIND RAI
ARVIND RAI
LEARN MORE








©2024 concretepage.com | Privacy Policy | Contact Us