Tag Archives: junit 5

JUnit 5 Tutorial – New Features with Examples

What is JUnit?

It is an opensource testing framework which performs unit testing on Java based application. The current version is JUnit 5.

What’s New in JUnit 5?

Unlike its previous version, JUnit 5 is composed of several different modules from three different sub directories. (JUnit 5 requires Java 8 at run-time)

JUnit 5JUnit Platform + JUnit Jupiter + JUnit Vintage

1. JUnit Platform:

a) It serves as a foundation for launching testing frameworks on JVM.

b) It defines TestEngine API for developing testing framework that runs on the platform.

c) It provides console launcher to launch the platform from command line.

d) It provides build plugin for maven and Gradle as well as a JUnit4 based runner for running any TestEngine on platform.

2. JUnit Jupiter:

a) It is the combination of new programming model and extension model for writing tests and extensions.

b) It provides a TestEngine for running Jupiter based tests on platform.

3. JUnit Vintage:

a) It provides a TestEngine for running junit 3 and junit 4 based tests on platform.

Installation Guide of JUnit 5:

To install JUnit 5 in the application, please add the following maven dependencies in the respective pom.xml.


 <dependencies>
<!-- JUnit Platform -->
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-commons</artifactId>
<version>1.0.0-M2</version>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-console</artifactId>
<version>1.0.0-M2</version>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-engine</artifactId>
<version>1.0.0-M2</version>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-gradle-plugin</artifactId>
<version>1.0.0-M2</version>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<version>1.0.0-M2</version>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-runner</artifactId>
<version>1.0.0-M2</version>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-surefire-provider</artifactId>
<version>1.0.0-M2</version>
</dependency>

<!-- JUnit Jupiter -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.0.0-M2</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.0.0-M2</version>
</dependency>

<!-- JUnit Vintage -->
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>4.12.0-M2</version>
</dependency>
</dependencies>

Example: FirstJunit5Test.java


/**
*
*/
package com.abhi.junit5.learning;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;

import org.junit.jupiter.api.Test;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith;

/**
* @author Abhinav
*
*/
@RunWith(JUnitPlatform.class)
class FirstJunit5Test {

@Test
void testCaseFirst(){
assertEquals(2, 1+1);
}

@Test
@CustomTag
void failingTest() {
fail("Failing for failing's sake.");
}
}

JUnit 5 Annotations:

. @Test : It denotes that annoted method is a test method. It does not declare any attributes, since test extensions in junit jupiter operate based on their own annotations.

. @TestFactory : It denotes that annoted method is a test factory for dynamic tests*.

. @DisplayName : It declares the custom display names for the test class or test method. It could be the text with blank spaces, special characters, and even emojis.

. @BeforeEach : It denotes that the annoted method should be executed before each @Test annoted method. Such methods are inherited. Similar to junit 4 @Before.

. @AfterEach : It denotes that the annoted method should be executed after each @Test annoted method. Such methods are inherited. Similar to junit 4 @After.

. @BeforeAll : It denotes that the annoted method should be executed before all @Test annoted method. Such methods must be static and inherited. Similar to junit 4 @BeforeClass.

. @AfterAll : It denotes that the annoted method should be executed after all @Test annoted method. Such methods must be static and inherited. Similar to junit 4 @AfterClass.

. @Nested : It denotes that the annoted class is a nested, non static test class. @BeforeAll and @AfterAll annotations cannnot be used in @Nested test class.

. @Tag : It is used for filtering the test cases either at class or method level. Similar to junit 4 TestNG or categories.

. @Disabled : It is used to disable a test class or test method. Similar to junit 4 @ignore.

. @ExtendWith : It is used to register custom extensions*.

Meta Annotations and Composed Annotations:

In JUnit Jupiter you can define your own custom composed annotations that will automatically inherit the semantics of its meta-annotations.
Example: CustomTag.java

Sample Test Case example: BasicJUnit5Test.java


/**
 *
 */
package com.abhi.junit5.learning;

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.Disabled;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith;

/**
 * @author Abhinav
 *
 */
@RunWith(JUnitPlatform.class)
@DisplayName("Sample test class for showcasing the annotations")
class BasicJUnit5Test {

@BeforeAll
 static void beforeALL(){
 System.out.println("It will execute once before executing all the Test case");
 }

 @BeforeEach
 void beforeEach(){
 System.out.println("It will execute each time before executing the Test case");
 }

 @Test
 void passedTestCase(){
 System.out.println("Success Test case");
 }

 @Test
 void failedTestCase(){
 System.out.println("Failed Test case");
 }

 @Test
 @Disabled("For demo purpose")
 void disabledTestCase(){
 System.out.println("Ignored Test case");
 }

 @AfterEach
 void afterEach(){
 System.out.println("It will execute each time after executing any Test case");
 }

 @AfterAll
 static void afterAll(){
 System.out.println("It will execute once After executing all Test case");
 }
}

JUnit 5 Assertions:

JUnit 5 have many assertions methods packaged under JUnit Jupiter. Their are few new assertion methods introduce in JUnit 5 to support the Java 8 lambda expression feature. Else most of them are similar what we had in JUnit 4.

Example: AssertionsJunit5.java


/**
 *
 */
package com.abhi.junit5.learning;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith;

import static org.junit.jupiter.api.Assertions.*;
/**
 * @author Abhinav
 *
 */
@RunWith(JUnitPlatform.class)
@DisplayName("Assertions in JUnit5")
public class AssertionsJunit5 {

@Test
 @DisplayName("Test case to show standard assertion methods.")
 void basicAssertions(){
 assertEquals("Abhi", "Abhi");
 assertNotEquals(4, 2, ()-&amp;amp;gt;"Assertion not equals message.");
 assertTrue(3&amp;amp;gt;2, ()-&amp;amp;gt;"Assertion messages can be lazily evaluated to avoid constructing complex messages unnecessarily.");
 }

 @Test
 @DisplayName("Test case to show Grouped assertion methods.")
 void newAssertion(){
 assertAll("Group Assertions",
 ()-&amp;amp;gt;assertEquals("Abhi", "Abhi"),
 ()-&amp;amp;gt;assertNotEquals(4, 3, ()-&amp;amp;gt;"Assertion not equals message."),
 ()-&amp;amp;gt;assertTrue(3&amp;amp;gt;2, ()-&amp;amp;gt;"Assertion messages can be lazily evaluated to avoid constructing complex messages unnecessarily.")
 );
 }

 @Test
 @DisplayName("Test case to show exception handle through assertion methods.")
 void exceptionAssertion(){
 Throwable exception = expectThrows(NullPointerException.class, ()-&amp;amp;gt;{ throw new NullPointerException("Got exception message");
 });

 assertEquals("Got exception message", exception.getMessage());
 }
}

JUnit 5 Assumptions:

Junit 5 have many assumption methods packaged under JUnit Jupiter. Their are few new assumption methods introduce to support the Java 8 lambda expression feature. Else most of them are similar what we had in JUnit 4.

Example: AssumptionsBasic.java


/**
 *
 */
package com.abhi.junit5.learning;

import static org.junit.jupiter.api.Assumptions.*;
import static org.junit.jupiter.api.Assertions.*;

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith;

/**
 * @author Abhinav
 *
 */
@RunWith(JUnitPlatform.class)
@DisplayName("Assumptions in JUnit5")
public class AssumptionsBasic {

@BeforeAll
 static void setUp(){
 System.setProperty("TestEnv", "JUnit5");
 System.setProperty("Environment", "Stage");
 }

 @Test
 void showAssumeTrue(){
 assumeTrue("Stage".equals(System.getProperty("Environment")), ()-&amp;amp;gt; "Not on development environment");
 }

 @Test
 void showAssumptionBasic(){
 assumingThat("JUnit5".equals(System.getProperty("TestEnv")),
 ()-&amp;amp;gt;{
 assertEquals(2, 2);
 System.out.println("Inside assumption");
 });

 }
}

You can checkout/clone the JUnit 5 example repository from the mentioned path – https://github.com/erabhinavrana/my-junit5-learning

 

Advertisements