Java unit testing maven

Java unit testing maven

Maven Surefire Plugin

  • Apache /
  • Maven /
  • Surefire /
  • Maven Surefire Plugin /
  • Using JUnit
  • | Last Published: 2023-06-03
  • Version: 3.1.2

Using JUnit

Configuring JUnit

To get started with JUnit, you need to add the required version of JUnit to your project:

This is the only step that is required to get started — you can now create tests in your test source directory (e.g., src/test/java ).

Different Generations of JUnit support

Surefire supports three different generations of JUnit: JUnit 3.8.x, JUnit 4.x (serial provider) and JUnit 4.7 (junit-core provider with parallel support). The provider is selected based on the JUnit version in your project and the configuration parameters (for parallel).

Upgrade Check for JUnit 4.x

As of Surefire version 2.7, the algorithm for choosing which tests to run has changed. From 2.7 and on, only valid JUnit tests are run for all versions of JUnit, where older versions of the plugin would also run invalid tests that satisfied the naming convention.

When upgrading from a Surefire version prior to 2.7, the build can be run with the flag -Dsurefire.junit4.upgradecheck . This will perform a check and notify you of any invalid tests that will not be run with this version of Surefire (and the build fails). This is only meant to be used as a tool when upgrading to check that all expected tests will be run. It is a transitional feature that will be removed in a future version of surefire.

Provider Selection

If nothing is configured, Surefire detects which JUnit version to use by the following algorithm:

if the JUnit 5 Platform Engine is present in the project use junit-platform if the JUnit version in the project >= 4.7 and the >> configuration parameter has ANY value use junit47 provider if JUnit >= 4.0 is present use junit4 provider else use junit3.8.1

Please note that the «else» part of this algorithm is also a FAQ response:

You depend on the appropriate version of JUnit being present in the project dependencies, or Surefire may choose the wrong provider. If, for instance, one of your dependencies pulls in JUnit 3.8.1 you risk that surefire chooses the 3.8.1 provider, which will not support annotations or any of the 4.x features.

Use mvn dependency:tree , POM dependency ordering and/or exclusion of transitive dependencies to fix this problem.

Manually Specifying a Provider

You can also manually force a specific provider by adding it as a dependency to Surefire itself:

 [. ] org.apache.maven.plugins maven-surefire-plugin 3.1.2  org.apache.maven.surefire surefire-junit47 3.1.2    [. ] 

When using this technique there is no check that the proper test-frameworks are present on your project’s classpath. Failing to add the proper test-frameworks will result in a build failure.

Читайте также:  Сохранить html на компьютере

Running Tests in Parallel

From JUnit 4.7 onwards you can run your tests in parallel. To do this, you must set the parallel parameter, and may change the threadCount or useUnlimitedThreads attribute. For example:

 [. ] org.apache.maven.plugins maven-surefire-plugin 3.1.2 methods 10   [. ] 

If your tests specify any value for the parallel attribute and your project uses JUnit 4.7+, your request will be routed to the concurrent JUnit provider, which uses the JUnit JUnitCore test runner.

This is particularly useful for slow tests that can have high concurrency.

As of Surefire 2.7, no additional dependencies are needed to use the full set of options with parallel. As of Surefire 2.16, new thread-count attributes are introduced, namely threadCountSuites , threadCountClasses and threadCountMethods . Additionally, the new attributes parallelTestsTimeoutInSeconds and parallelTestsTimeoutForcedInSeconds are used to shut down the parallel execution after an elapsed timeout, and the attribute parallel specifies new values.

Using Custom Listeners and Reporters

The junit4 and junit47 providers provide support for attaching custom RunListeners to your tests.

You can configure multiple custom listeners like this:

 [. ] your-junit-listener-artifact-groupid your-junit-listener-artifact-artifactid your-junit-listener-artifact-version test  [. ] [. ] [. ] org.apache.maven.plugins maven-surefire-plugin 3.1.2   listener com.mycompany.MyResultListener,com.mycompany.MyResultListener2     [. ] 

For more information on JUnit, see the JUnit web site.

You can implement JUnit listener interface org.junit.runner.notification.RunListener in a separate test artifact your-junit-listener-artifact with scope=test, or in project test source code src/test/java . You can filter test artifacts by the parameter dependenciesToScan to load its classes in current ClassLoader of surefire-junit* providers.

Since JUnit 4.12 thread safe listener class should be annotated by org.junit.runner.notification.RunListener.ThreadSafe which avoids unnecessary locks in JUnit.

Using a Security Manager (JUnit3 only)

As long as forkCount is not 0 and you use JUnit3, you can run your tests with a Java security manager enabled. The class name of the security manager must be sent as a system property variable to the JUnit3 provider.

The JDK 17 deprecated the class java.lang.SecurityManager and the security manager is not fully supported since JDK 18. The JUnit3 provider fails with enabled system property surefire.security.manager> in JDK 18+.

JUnit4 uses mechanisms internally that are not compatible with the tested security managers and thus this means of configuring a security manager with JUnit4 is not supported by Surefire.

 [. ] org.apache.maven.plugins maven-surefire-plugin 3.1.2  java.lang.SecurityManager    [. ] 

Using a Security Manager (All providers)

Alternatively you can define a policy file that allows all providers to run with Surefire and configure it using the argLine parameter and two system properties:

 [. ] org.apache.maven.plugins maven-surefire-plugin 3.1.2 -Djava.security.manager -Djava.security.policy=$/src/test/resources/java.policy   [. ] 

The disadvantage of this solution is that the policy changes will affect the tests too, which make the security environment less realistic.

Using JUnit Categories

JUnit 4.8 introduced the notion of Categories. You can use JUnit categories by using the groups parameter. As long as the JUnit version in the project is 4.8 or higher, the presence of the «groups» parameter will automatically make Surefire select the junit47 provider, which supports groups.

 [. ] org.apache.maven.plugins maven-surefire-plugin 3.1.2 com.mycompany.SlowTests   [. ] 

This will execute only those tests annotated with the @Category(com.mycompany.SlowTests.class) annotation and those tests annotated with @Category(com.mycompany.SlowerTests.class) if class/interface SlowerTests is subclass of SlowTests :

public interface SlowTests<> public interface SlowerTests extends SlowTests<>
public class AppTest < @Test @Category(com.mycompany.SlowTests.class) public void testSlow() < System.out.println("slow"); >@Test @Category(com.mycompany.SlowerTests.class) public void testSlower() < System.out.println("slower"); >@Test @Category(com.mycompany.FastTests.class) public void testSlow() < System.out.println("fast"); >>

The @Category annotation can also be applied at class-level.

Читайте также:  Php функция пустая строка

Multiple categories can be specified by comma-delimiting them in the groups parameter in which case tests annotated with any of the categories will be executed.

For more information on JUnit, see the JUnit web site.

Since version 2.18.1 and JUnit 4.12, the @Category annotation type is automatically inherited from superclasses, see @java.lang.annotation.Inherited . Make sure that test class inheritance still makes sense together with @Category annotation of the JUnit 4.12 or higher appeared in superclass.

Apache Maven Surefire Plugin, Maven Surefire Plugin, Apache, the Apache feather logo, and the Apache Maven Surefire Plugin project logos are trademarks of The Apache Software Foundation.

Источник

JUnit 5 Tutorial: Running Unit Tests With Maven

We can get the required dependencies by adding the junit-jupiter (version 5.8.2) dependency to the test scope. This is an aggregator artifact which simplifies the dependency management because it has the following transitive dependencies:

  • The junit-jupiter-api dependency ( compile scope) provides the public API for writing tests and extensions.
  • The junit-jupiter-params dependency ( compile scope) provides support for writing parameterized tests.
  • The junit-jupiter-engine dependency ( runtime scope) contains the implementation of the JUnit Jupiter test engine that runs our unit tests. If we add this dependency to our classpath, the Maven Surefire and Failsafe plugins (version 2.22.0 or newer) can run tests which use JUnit 5.

After we have added the required dependency to our POM file, its dependencies section looks as follows:

  org.junit.jupiter junit-jupiter 5.8.2 test   

After we have declared the required dependencies, we have to configure the Maven Surefire Plugin. Let’s find out how we can do it.

Configuring the Maven Surefire Plugin

We can run our unit tests by using the Maven Surefire Plugin. Because we want to use its native JUnit 5 support, we have to use the version 2.22.0 (or newer).

After we have ensured that our unit tests are run by the Maven Surefire Plugin 2.22.2, the build section of our POM file looks as follows:

   org.apache.maven.plugins maven-surefire-plugin 2.22.2    

First, if we want to use the native JUnit 5 support of the Maven Surefire Plugin, we must ensure that at least one test engine implementation is found from the classpath. That’s why we ensured that the junit-jupiter-engine dependency is found from the classpath when we configured the dependencies of our Maven build.

Second, if we use the default configuration of the Maven Surefire Plugin, it runs all test methods found from a test class if the name of the test class:

  • Starts or ends with the string: Test .
  • Ends with the string: Tests .
  • Ends with the string: TestCase .
Читайте также:  Установка java home mac

Additional Reading:

We have now created a Maven project that can run unit tests which use JUnit 5. Let’s move on and write a simple unit test with JUnit 5.

Writing a Simple Unit Test

Before we can write unit tests which use JUnit 5, we have to know these two things:

  • The src/test/java directory contains the source code of our unit tests.
  • The src/test/resources directory contains the resources of our unit tests.

Let’s create a new test class and add an empty test method to the created class. After we have written our test class, its source code looks as follows:

import org.junit.jupiter.api.Test; class JUnit5ExampleTest < @Test void justAnExample() < >>

If you want to get more information about JUnit 5 test classes, you should read this blog post. Also, it’s not a good idea to write empty test methods. I use this technique here only because I want to demonstrate that our test method is run by the Maven Surefire Plugin.

Next, we will find out how we can run our unit tests.

Running Unit Tests With Maven

We can run our unit tests with Maven by using the command: mvn clean test. When we run this command at command prompt, we should see that the Maven Surefire Plugin runs our unit tests.

[INFO] [INFO] --- maven-surefire-plugin:2.22.2:test (default-test) @ running-unit-tests --- [INFO] ------------------------------------------------------- T E S T S ------------------------------------------------------- Running net.petrikainulainen.junit5.JUnit5ExampleTest Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.033 sec - in net.petrikainulainen.junit5.JUnit5ExampleTest Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------

We can now create a Maven project that compiles and runs unit tests which use JUnit 5. Also, we know how we can run our unit tests with Maven. Let’s summarize what we learned from this blog post.

If you want to get access to up-to-date material which is essentially a better version of my JUnit 5 tutorial, you should take a look at my Introduction to JUnit 5 course.

Summary

This blog post has taught us six things:

  • The junit-jupiter-api dependency provides the public API that allows us to write tests and extensions which use JUnit 5.
  • The junit-jupiter-engine dependency ensures that the Maven Surefire Plugin can run tests which use JUnit 5.
  • The junit-jupiter dependency is an aggregator artifact which simplifies the dependency management because it ensures that the required dependencies are found from the classpath.
  • The Maven Surefire Plugin 2.22.0 (or newer) provides native support for JUnit 5.
  • If we want to use the native JUnit 5 support of the Maven Surefire Plugin, we must ensure that at least one test engine implementation is found from the classpath.
  • We can run our unit tests by using the command: mvn clean test.

Источник

Оцените статью