JUnit 6 Tutorial with Examples

JUnit 6 is a modern, polished evolution of JUnit 5 that embraces Java 17+, improves extension handling, enhances performance, and adds new features like nullability annotations and native Kotlin coroutine support.

JUnit6 Logo

JUnit is the de-facto standard testing framework for Java (and the JVM), widely used for writing automated unit tests. With the release of JUnit 6, the framework has matured further into a modern, unified platform.

Under the hood, JUnit 6 combines:

  • the JUnit Platform (test launch infrastructure),
  • JUnit Jupiter (the programming and extension model for writing new tests),
  • and (optionally) JUnit Vintage (for running legacy JUnit 3 / JUnit 4 tests).

JUnit 6.0.1 = JUnit Platform + JUnit Jupiter + JUnit Vintage

1. JUnit 5 vs JUnit 6

The following table showing the main differences between JUnit 6 and JUnit 5, along with examples wherever helpful.

Feature / AreaJUnit 5JUnit 6
Minimum Java VersionJava 8Java 17
Module / Platform VersioningWhile all artifacts share the 5.x version, differences exist between submodules.All modules use a single unified version 6.x version with synchronized development, easier BOM management, and predictable compatibility.
Nullability AnnotationsNo standard nullability annotationsIntroduces built-in @NonNull, @Nullable, @NullMarked annotations for improved static code analysis across test code
Extension APIExtension API mature but sometimes verboseMore refined extension model with clearer lifecycle rules, better ordering semantics, and more consistent annotation behavior.
Vintage EngineFully available to run JUnit 3/4 testsStill available but marked deprecated
Dynamic TestsFully supportedEngine internally optimized for dynamic tests. Enhanced performance with large dynamic test suites and cleaner error reporting.
Migrating Build FilesRequires Jupiter + Platform dependenciesUses the junit-bom as standard
IDE / ToolingNeeds plugins to support JUnit 5 (historically)Supported natively in all major IDEs
Test Discovery & RuntimeMature, stable. Some reflection limitations due to old Java compatibility.More efficient discovery, better parallel test defaults.
IDE CompatibilityStrong IDE support (IntelliJ, Eclipse, VS Code). IDEs use adapters to integrate JUnit 5 Platform.IDEs have updated built-in JUnit 6 runners with full support for new features (nullability, coroutine tests, unified reporting). Less reliance on compatibility layers.
API CleanupsLegacy API maintained for compatibilityUnused / confusing APIs removed or simplified. Prioritizes developer experience over backward compatibility.

2. Maven and Gradle

If you are using Maven, here is a minimal pom.xml snippet to set up JUnit 6 for testing.

<project>
  ...
  <properties>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
  </properties>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.junit</groupId>
        <artifactId>junit-bom</artifactId>
        <version>6.0.0</version>  <!-- or latest JUnit 6 version -->
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <dependencies>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>3.0.0</version> <!-- minimum required for JUnit 6 -->
      </plugin>
    </plugins>
  </build>
  ...
</project>

In case of Gradle, use the following configuration:

Requires Gradle 7.3+ because of the Java 17 baseline.

plugins {
    id 'java'
}

repositories {
    mavenCentral()
}

dependencies {
    testImplementation(platform("org.junit:junit-bom:6.0.0"))

    testImplementation("org.junit.jupiter:junit-jupiter")
    testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}

test {
    useJUnitPlatform()
}

3. A JUnit 6 Simple Test

Here’s a minimal example to get started with JUnit 6. This class runs the tests and assets few basic assumptions.

package com.howtodoinjava;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.DisplayName;

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

public class AppTest {

  @Test
  @DisplayName("Simple test to verify that 1 + 1 equals 2")
  void testAddition() {

    assertEquals(2, 1 + 1);
  }

  @Test
  @DisplayName("Test string equality")
  void testStringEquality() {

    String expected = "Hello World!";
    String actual = "Hello World!";
    assertEquals(expected, actual);
  }

  @Test
  @DisplayName("Test boolean assertion")
  void testBooleanAssertion() {

    assertTrue(true);
    assertFalse(false);
  }

  @Test
  @DisplayName("Test not null assertion")
  void testNotNull() {

    App app = new App();
    assertNotNull(app);
  }
}

4. Conclusion

JUnit 6 is a modern, polished evolution of JUnit 5 that embraces Java 17+, improves extension handling, enhances performance, and adds new features like nullability annotations and native Kotlin coroutine support. Writing tests remains simple and familiar, using the same @Test annotation and clear assertion APIs.

Happy Learning !!

Comments

Subscribe
Notify of
0 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.