Tutorial: How to configure maven surefire plugin work with JUnit 5

Recently, I had a task to migrate the unit tests in our project from ‘JUnit 4’ to ‘JUnit 5’. As many developers, I researched a bit to learn about the major differences between the two versions and drafted a plan for smooth migration.

From the first look, I thought my only job was refactoring the tests and probably some helper classes. But, I was wrong! I ran into a configuration issue with the maven-surefire-plugin configuration.

In this post, I will be sharing the encountered issue and its fix. Note that I will not cover the detailed steps of how to migrate from ‘JUnit 4’ to ‘JUnit 5’.

Tests run: 0!

We, as many other developers, use the maven-surefire-plugin to run our tests during the test phase of maven’s build lifecycle. We rely heavily on this plugin because it fails the build when one of the tests is broken!

With JUnit4, everything was working perfectly! But after the migration, the plugin was always reporting that not tests are run:

'Tests run: 0, Failures: 0, Errors: 0, Skipped: 0 ...'!

Calculator Class

For the purpose of this blog, let us assume we want to build a Calculator. For now, we only have the ‘add‘ method implemented as shown below.

Calculator.java

public final class Calculator {
    public static int add(int firstNumber, int secondNumber) {
        return firstNumber + secondNumber;
    }
}

JUnit 4 Code

junit4

I will start with the ‘JUnit 4’ version of the code.

pom.xml

We need to depend on the junit artifacts and add the plugin for the surefire. Here is the required pom file:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.19.1</version>
        </plugin>
    </plugins>
</build>

<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
</dependencies>

CalculatorTest.java

In the test class, we have one test that asserts our method is doing the correct addition.

import org.junit.Assert;
import org.junit.Test;

public class CalculatorTest {
    @Test
    public void
    our_calculator_should_add_2_numbers() {
        Assert.assertEquals(5, Calculator.add(2, 3));
    }
}

Build Output

Now, if we try to run ‘mvn clean install‘ on the above pom file we get the below output:

-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running CalculatorTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.037 sec - in CalculatorTest

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

****
[INFO] --------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] --------------------------------------------------

Everything works perfectly!

JUnit 5 Code

junit5

It’s time to migrate our code to ‘JUnit 5’!

pom.xml

The first step is changing our dependencies in the pom file.

Some significant changes were applied to the ‘Junit 5’ dependency metadata. The framework functionalities have been split into several artifacts:

  • junit-jupiter-api
  • junit-jupiter-engine
  • junit-platform-suite-api
  • junit-jupiter-params
  • junit-platform-surefire-provider

For this simple example, it is enough to depend on ‘junit-jupiter-engine‘ & ‘junit-platform-surefire-provider‘.

So, our pom becomes:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.19.1</version>
        </plugin>
    </plugins>
</build>

<dependencies>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>5.0.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.platform</groupId>
        <artifactId>junit-platform-surefire-provider</artifactId>
        <version>1.0.0</version>
     </dependency>
</dependencies>

P.S. Check ‘JUnit 5 User Guide‘ if you are interested in more details on the ‘JUnit 5’ artifacts

CalculatorTest.java

A good portion of the code in tests has to be changed to migrate to ‘JUnit 5’. Again, I am not going to cover those changes in this blog.

For the simple test we have written before, we need to change two things:

  1. Change the import statements
  2. Change the assertion call
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class CalculatorTest {
    @Test
    public void
    our_calculator_should_add_2_numbers() {
        Assertions.assertEquals(5, Calculator.add(2, 3));
    }
}

Build Output

Although the ‘mvn clean install‘ command is still returning a ‘BUILD SUCCESS‘ message, it is actually not running any tests which make the whole build process suspicious.

This is our issue!

-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running CalculatorTest
Tests run: 0, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.001 sec - in CalculatorTest

Results :

Tests run: 0, Failures: 0, Errors: 0, Skipped: 0

****
[INFO] ------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------

The Fix

The fix of this problem is simple, need to modify the build section in our pom to add the 2 dependencies to the ‘maven-surefire-plugin‘  plugin section as shown below.

By doing so, we forced the maven-surefire-plugin to use the latest JUnit artifacts and thus run the JUnit 5 tests.

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.19.1</version>
            <dependencies>
                <dependency>
                    <groupId>org.junit.platform</groupId>
                    <artifactId>junit-platform-surefire-provider</artifactId>
                    <version>1.0.0</version>
                </dependency>
                <dependency>
                    <groupId>org.junit.jupiter</groupId>
                    <artifactId>junit-jupiter-engine</artifactId>
                    <version>5.0.0</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

Running ‘mvn clean install‘ will return the correct output now:

-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running CalculatorTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.044 sec - in CalculatorTest

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

****
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

 

I hope this blog post would save you some time when migrating to ‘JUnit 5’!

Good luck 🙂

How to move a git repository to subdirectory of another repository

You might come across a situation when working with Git where you want to move a repository to another repository (i.e., make it a subdirectory of the other` repository) while maintaining its full history.

In this blog, I will be pointing out step by step with an example how to achieve that.

Use Case

Let us assume we have two repositories on git, repoA, and repoB, and we want to make repoB a subdirectory of repoA while maintaining its full history.

To achieve that we will move the content of repoB into a subfolder under repoB and then merge repoA and repoB. 

Bellow is the detailed git process:

  1. The first step is to clone repoA and repoB on your machine
    $ git clone repoA
    $ git clone repoB

    Note: For the purpose of this blog I submitted a README.md file in each of the two repositories on Bitbucket. Below are two snapshots are taken for both repositories:

    RepoA:
    REPO-A-Commits

    RepoB:
    REPO-B-Commits

  2. The second step is to copy the content of repoB to a subfolder. Go to the folder repoB and apply the following steps:
    • create a subfolder repoB
      $ mkdir repoB
    • move everything from the parent repoB to the child repoB (except the .git folder)
    • stage the files (the added folder and deleted file(s)) for a later commit
      $ git stage repoB/
      $ git stage README.md
    • commit and push those changes to git
      $ git commit -am '[REPO-B] Move content to a subfolder'
      $ git push origin master
  3. Go to the folder repoA and do the following:
    • add a remote branch with the content of repoB
      $ git remote add repoBTemp (path_to_repoB)
    • fetch repoBTemp the temp repo we created in the previous step
      $ git fetch repoBTemp
    • merge repoBTemp with repoA
      $ git merge repoBTemp/master
    • delete the remote repoBTemp
      $ git remote rm repoBTemp
    • push the changes to the server

      $ git push origin master

  4. Now we can check our git history to verify that our trick worked as intended. In the right image below you can see that the history of repoB is now part of repoA’s history. In the left image, you can notice that repoB is now a subdirectory of repoA.
  5. You it should be sage to delete the repository repoB

I hope you find this blog helpful!