/
JUnit 4 to 5 Migration Guide

JUnit 4 to 5 Migration Guide

The Maven coordinates for JUnit 5 are:

compile("org.junit.jupiter:junit-jupiter-api:5.3.1")
compile("org.junit.jupiter:junit-jupiter-engine:5.3.1")

Upgrade Dependencies

Upgrade to newest ihmc-ci Gradle plugin
Searching in *.gradle, *.gradle.kts, replace

ihmc-ci-plugin
ihmc-ci

(us\.ihmc[ \t\x0B\S\.]*ihmc-ci[ \t\x0B:"a-zA-Z)]*)([0-9\.]+)("|')
$1<version>$3

Integrated projects: Remove testSuites block
[ \t\x0B]*testSuites[ \t\x0B]*\{(\R[ \t\x0B]*[\s\w+=\-,\."\[\]]*)+\R}\R\R

Upgrade ihmc-commons
(us\.ihmc[ \t\x0B\S]*("|')ihmc-commons[- \t\x0B:",a-zA-Z)]*)([0-9\.]+)("|')
$1<version>$4

Annotations

add JUnit 5 imports

Switch test import statements to JUnit 5
import org\.junit\.Test[ \t\x0B]*;
import org.junit.jupiter.api.Test;

Switch test annotations, leaving parameters in a comment; i.e. timeout, expected
([ \t\x0B]*)(@Test)[ \t\x0B]*\((.*)\)
$1$2// $3

replace beforeeach import
import org\.junit\.Before[ \t\x0B]*;
import org.junit.jupiter.api.BeforeEach;

beforeeach
([ \t\x0B]*)@Before[ \t\x0B]*\R
$1@BeforeEach\R

replace beforeall import
import org\.junit\.BeforeClass[ \t\x0B]*;
import org.junit.jupiter.api.BeforeAll;

beforeall
([ \t\x0B]*)@BeforeClass[ \t\x0B]*\R
$1@BeforeAll\R

replace aftereach import
import org\.junit\.After[ \t\x0B]*;
import org.junit.jupiter.api.AfterEach;

aftereach
([ \t\x0B]*)@After[ \t\x0B]*\R
$1@AfterEach\R

replace afterall import
import org\.junit\.AfterClass[ \t\x0B]*;
import org.junit.jupiter.api.AfterAll;

afterall
([ \t\x0B]*)@AfterClass[ \t\x0B]*\R
$1@AfterAll\R

((import us\.ihmc\.continuousIntegration\.ContinuousIntegrationAnnotations[ \t\x0B\S]*;\s*)+)
$1import org.junit.jupiter.api.Tag;\Rimport org.junit.jupiter.api.Disabled;\R

add Disabled import (if needed)
(import org\.junit\.jupiter\.api\.Tag[ \t\x0B\S]*;\s*)
$1import org.junit.jupiter.api.Disabled;\R

fast (actually probably dont add these) (integrated)
([ \t\x0B]*)(@[a-zA-Z\.\s]*ContinuousIntegration\w{4}\s*\([ \t\x0B\S]*categories\w*[ \t\x0B\S]+FAST.*\R)
$1@Tag\("fast"\)\R$1$2

slow (integrated)
([ \t\x0B]*)(@[a-zA-Z\.\s]*ContinuousIntegration\w{4}\s*\([ \t\x0B\S]*categories\w*[ \t\x0B\S]+SLOW.*\R)
$1@Tag\("allocation"\)\R$1$2

video (integrated)
([ \t\x0B]*)(@[a-zA-Z\.\s]*ContinuousIntegration\w{4}\s*\([ \t\x0B\S]*categories\w*[ \t\x0B\S]+VIDEO.*\R)
$1@Tag\("video"\)\R$1$2

ui (integrated)
([ \t\x0B]*)(@[a-zA-Z\.\s]*ContinuousIntegration\w{4}\s*\([ \t\x0B\S]*categories\w*[ \t\x0B\S]+UI.*\R)
$1@Tag\("gui"\)\R$1$2

flaky (integrated)
([ \t\x0B]*)(@[a-zA-Z\.\s]*ContinuousIntegration\w{4}\s*\([ \t\x0B\S]*categories\w*[ \t\x0B\S]+FLAKY.*\R)
$1@Disabled\R$1$2

indev (integrated)
([ \t\x0B]*)(@[a-zA-Z\.\s]*ContinuousIntegration\w{4}\s*\([ \t\x0B\S]*categories\w*[ \t\x0B\S]+IN_DEVELOPMENT.*\R)
$1@Disabled\R$1$2

manual (disabled or converted to demo) (integrated)
([ \t\x0B]*)(@[a-zA-Z\.\s]*ContinuousIntegration\w{4}\s*\([ \t\x0B\S]*categories\w*[ \t\x0B\S]+MANUAL.*\R)
$1@Disabled\R$1$2

exclude
([ \t\x0B]*)(@[a-zA-Z\.\s]*ContinuousIntegration\w{4}\s*\([ \t\x0B\S]*categories\w*[ \t\x0B\S]+EXCLUDE.*\R)
$1@Disabled\R$1$2

replace ignore keeping message
([ \t\x0B]*)(@Ignore)(.*)\R
$1@Disabled$3\R

switch ignore with disabled import (standalone)
import[ \t\x0B]+org\.junit\.Ignore[ \t\x0B]*;[ \t\x0B]*
import org.junit.jupiter.api.Disabled;

remove custom annotations
[ \t\x0B]*@[a-zA-Z\.\s]*ContinuousIntegration\w{4}\s*\([ \t\x0B\S]*\).*\R

remove custom imports
import us\.ihmc\.continuousIntegration\.ContinuousIntegrationAnnotations[ \t\x0B\S]*;\s*\R
import us\.ihmc\.continuousIntegration\.IntegrationCategory[ \t\x0B\S]*;\s*\R

remove junit4 Ignore statement
[ \t\x0B]*import[ \t\x0B]+org\.junit\.Ignore[ \t\x0B]*;[ \t\x0B]*\R

delete existing test suites
*Suite*java*

Assertions

Place Assert.java in ihmc-robotics-toolkit-test

switch junit to Assert.java
((import\s*static\s*org\.junit\.Assert[ \t\x0B\S]*;\s*)+)
import static us.ihmc.robotics.Assert.*;\R\R

switch junit framework to Assert.java
((import\s*static\s*junit\.framework\.[ \t\x0B\S\.]*;\s*)+)
import static us.ihmc.robotics.Assert.*;\R\R

switch non-static junit to Assert
((import\s*org\.junit\.Assert[ \t\x0B\S]*;\s*)+)
import us.ihmc.robotics.Assert;\R

add to a few projects (ihmc-robot-data-logger, robot-environment-awareness-test, ihmc-parameter-tuner)
compile group: "us.ihmc", name: "ihmc-robotics-toolkit-test", version: "source"

Remove Asserts from main source sets

switch ContinuousIntegrationTools source
import us.ihmc.continuousIntegration.ContinuousIntegrationTools;
import us.ihmc.commons.ContinuousIntegrationTools;

disable on debug thing
a few asserts in footstep planning
a few misc items (<20)

Remove JUnit 4

From *.gradle, *.gradle.kts

remove junit4
\R[ \t\x0B]+compile[ \t\x0B\S]*junit[ \t\x0B\S]*junit[ \t\x0B\S]*[0-9\.]+("|')[ \t\x0B\S]*
all*.exclude group: "junit", module: "junit"

add exclude to commons (if alreadly refactored)
(\R[ \t\x0B]+)(compile[ \t\x0B\S]*us.ihmc[ \t\x0B\S]*ihmc-commons[ \t\x0B\S]*[0-9\.]+("|')[ \t\x0B\S]*)
$1$2$1all*.exclude group: "junit", module: "junit"

(mainDependencies\s*\{)[ \t\x0B]*\R([ \t\x0B]+)(compile)
$1\R$2all*.exclude group: "junit", module: "junit"\R$2$3

(testDependencies\s*\{)[ \t\x0B]*\R([ \t\x0B]+)(compile)
$1\R$2all*.exclude group: "junit", module: "junit"\R$2$3

remove junit 5 vintage
([ \t\x0B]+)(compile[ \t\x0B\S]*vintage[ \t\x0B\S]*junit-vintage-engine[ \t\x0B\S]*[0-9\.]+("|')[ \t\x0B\S]*)

remove ihmc-ci-core-api
\R[ \t\x0B]+compile[ \t\x0B\S]*us\.ihmc[ \t\x0B\S]*ihmc-ci-core-api[ \t\x0B\S]*[0-9\.]+("|')[ \t\x0B\S]*

Get tests running

Problem tests:
us.ihmc.atlas.behaviorTests.AtlasBehaviorDispatcherTest > testDispatchPelvisPoseBehavior()

Go through and fing the expected exceptions and add the JUnit 5 assertThrows


	   Assertions.assertThrows(NoSuchElementException.class, () -> 
	   {
       });
	   Assertions.assertThrows(RuntimeException.class, () -> 
	   {
       });

Inlining Assert.java

In Assert.java, remove all unused methods.

In Eclipse, inline all methods except the deltas.

Direct Inline Everything (Option A) ← preferred if it works, could throw zero delta exceptions

Remove the == 0.0 checks in Assert.java and wrap straight to the JUnit 5 delta assert

Switch Assert to jupiter

((import\s*static\s*us\.ihmc\.robotics\.Assert[ \t\x0B\S]*;\s*)+)
import static org.junit.jupiter.api.Assertions.*;\R\R

Delta Tool Class (Option B)

Rename all delta methods, adding Delta


Add an XJUnitTools class containing the deltas.


switch Assert import to jupiter plus your custom delta class
((import\s*static\s*us\.ihmc\.robotics\.Assert[ \t\x0B\S]*;\s*)+)
import static org.junit.jupiter.api.Assertions.*;\Rimport static us.ihmc.euclid.tools.EuclidJUnitTools.*;\R\R

Resume migration

switch non-static Assert to jupiter
((import\s*us\.ihmc\.robotics\.Assert[ \t\x0B\S]*;\s*)+)
import org.junit.jupiter.api.Assertions;\R


Delete Assert.java


remove the prefix from all non-imports
org\.junit\.jupiter\.api\.Assertions\.([^*])
$1


remove long casts - run twice
(assert\w+.*)(\(long\) )
$1


remove Object casts - run twice
(assert\w+.*)(\(Object\) )
$1


remove Assert. prefixes
Assert\.assert
assert

Removing JUnit 4 dependencies
,[ \t\x0B]+\{\R[ \t\x0B]+exclude group: "junit", module: "junit"\R[ \t\x0B]+\}\)
, \{ exclude group: "junit", module: "junit" \}\)

compile("us.ihmc:IHMCNativeLibraryLoader:blah", { exclude group: "junit", module: "junit" })

Later

Refactor away Assert class
Add scs tag to all scs tests
Add network tag?
Add expected exception assertions
Add assertTimeouts5.3.1")

Related content

IHMC Build Maintainer Guide
IHMC Build Maintainer Guide
More like this
Library Version Upgrade Regular Expressions
Library Version Upgrade Regular Expressions
More like this
IHMC Commons Maintainer Guide
IHMC Commons Maintainer Guide
More like this
IHMC CI Maintainer Guide
IHMC CI Maintainer Guide
More like this
Java Platform Module System
Java Platform Module System
More like this
Gradle
Gradle
More like this