Junit5 test suites with #Suite annotation doesn't execute tests with mvn test command - junit5

We intended to upgrade a JUnit4 based project to JUnit5. I modified JUnit4 suites according to the instruction in JUnit5 official site: https://junit.org/junit5/docs/current/user-guide/#running-tests-junit-platform-runner-test-suite.
Tests were not executed when using mvn test in command line: mvn test -Dtest=SuiteXXTest, neither in JUnit4 nor JUnit5 suite.
Error msg: [ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:3.0.0-M5:test (default-test) on project XXX: No tests were executed!
Yet both JUnit4 and JUnit5 suites can run and execute the included tests in IDEA. Maven surefire plugin version is 3.0.0-M5. Single test classes(ATest and BTest) are based on JUnit4 progamming model.
Old JUnit4 suite is like this:
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import test.XX.*;
#RunWith(Suite.class)
#Suite.SuiteClasses({
ATest.class,
BTest.class
})
public class SuiteXXTest {
}
Modified to:
import org.junit.platform.suite.api.SelectClasses;
import org.junit.platform.suite.api.Suite;
import test.XX.*;
#Suite
#SelectClasses({
ATest.class,
BTest.class
})
public class SuiteXXTest {
}
related dependencies:
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-suite</artifactId>
<version>1.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
Curiously, if I use the depracated #RunWith(JUnitPlatform.class) annotation, the test suites can execute properly. But according to JUnit5 official user guide, using this runner means tests will be executed in a JUnit4 envrionment, and I don't understand what condition is regarded as JUnit4 environment(JUnit5 dependency already configured in pom).
I don't known if it's a bug or my incorrect use.

RunWith is a JUnit 4 construct and won’t work with JUnit 5. Use JUnit Platform suites instead as described in https://junit.org/junit5/docs/current/user-guide/#junit-platform-suite-engine

Found the solution here: https://github.com/junit-team/junit5/discussions/2753.
According to this answer I just changed my command from -Dtest=SuiteXXTest to -Dinclude=SuiteXXTest and it works fine. I think it has something to do with the surefire plugin. It seems surefire cannot pick up tests form suite annotated with #Suite when using -Dtest command.

Related

How to get the TestNG report in VS Code?

Running selenium test cases with TestNG in VS Code. But the test-output folder is not generated. Tried refreshing the project.
Unlike other IDEs, like Eclipse, etc., VS Code doesn't have a plugin for exclusive TestNG activities. In your case, to generate the TestNG report, you need to have the reporting dependency in your pom.xml:
<dependency>
<groupId>org.testng</groupId>
<artifactId>reportng</artifactId>
<version>1.2.2</version>
<scope>test</scope>
</dependency>

Why is Surefire not executing my JUnit5 tests?

I'm trying to convert one Maven SpringBoot (2.3.12) app from JUnit4 to JUnit5. I've read many different posts on how to do this.
I'm able to execute my JUnit5 tests in Eclipse.
My problem is that I am unable to get Maven Surefire to execute my JUnit5 tests. I've tried various configuration variations. When it gets to the Surefire step, it ONLY executes my old JUnit4 tests and simply ignores any JUnit5 tests. I've verified that if one of those JUni4 tests is executed from this, and I convert that test to JUnit5, it will then ignore that test. At this point, I'm only focusing on the tests that were using the Mockito runner, as they are simpler to convert than the Spring runner tests (the vast majority of which likely could be changed to just use the mockito runner).
This is what I have in the surefire plugin config:
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<!-- <groups>UnitTest</groups> -->
<reuseForks>false</reuseForks>
<redirectTestOutputToFile>true</redirectTestOutputToFile>
<argLine>${surefireArgLine}</argLine>
<skipTests>${skip.unit.tests}</skipTests>
<excludes>
<exclude>**/component/*.java</exclude>
<exclude>**/contract/*.java</exclude>
<exclude>**/integration/*.java</exclude>
</excludes>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.8.2</version>
</dependency>
</dependencies>
</configuration>
</plugin>
I currently have "groups" commented out until I understand what it is doing without that.
This is an excerpt of one of the unit tests:
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.junit.jupiter.MockitoExtension;
#ExtendWith(MockitoExtension.class)
public class BDSHelperTest {
Before I converted this to use the JUnit5 classes, it would execute when I run "mvn package". Now that I've converted it, Surefire is not executing it.
This is what I see at the start of the surefire step:
[INFO] --- maven-surefire-plugin:3.0.0-M5:test (default-test) # NotesMs ---
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
At this point, it shows the test runs for all the old JUnit4 tests, but it doesn't run any of the JUnit5 tests.
I am the Apache developer of Surefire. I have created a project which proves that it works with Surefire 3.0.0-M5, JUnit Jupiter 5.8.2 and Mockito Extension.
Please do not use JUnit4 and Vintage in this case.
It is not necessary to use a dependency inside of the plugin.
Use a dependency in the project POM.
Follow it on Github:
https://github.com/Tibor17/junit5-mockito-examples

JUnit on IntelliJ not working

I tried setting up JUnit 5 on my INtelliJ IDEA Community Edition 2018.2. The jar was downloaded but I am getting Cannot resolve symbol Assertions on importing
import static org.junit.jupiter.api.Assertions.*;
Error
Are you trying to use the JUnit assertions in a regular app class rather than a test class?
Delete <scope>test</scope>
When a Maven dependency carries a scope element with a value of test, that means you cannot use that library outside of your test-specific source package/folder.
If you are trying to call JUnit from code in your example project’s src/main/java/… folder hierarchy, you will see that error. If you call JUnit from src/test/java…, you will see success.
To enable JUnit in the src/main/java/… folder hierarchy, delete the scope element in your POM dependency. So this:
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.4.0-RC1</version>
<scope>test</scope>
</dependency>
…becomes this:
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.4.0-RC1</version>
</dependency>
By the way, note that as of 5.4.0 of JUnit, we can specify the new and very convenient single Maven artifact of junit-jupiter which in turn will supply 8 libraries to your project.

Cucumber Selenium - parallel browser testing

I have the following feature file :
Given I open "google.com" simultaneously in both FF and IE
When I type "stackoverflow" and submit
Then I should see the desired results
How can I run the test on 2 different browsers in parallel ?
I know it can done using TestNG, but I am not using TestNG in my project. I was wondering if there was some other approach.
I can think of three different different approaches here.
Write the scenario as you have done. When you find IE in the first step, create an IE instance. When you see FF in the first step, create a FF instance. Then use both in the following steps.
Do not include the browser at all in the steps. Create them and use them in the helper class you will delegate the work to.
Create one scenario for each browser. “When I open Google with Firefox…”
If you want to be explicit, use the last approach.
If you your users doesn’t care about the browsers, use the second approach.
I wouldn’t use the first approach myself.
Identify which approach is best to implement parallel execution - Cucumber-JVM 4 supports parallel execution from cucumber v 4.0.0 and we do not need to create individual runner per feature file and You can implement this with JUnit (Do not need to use TestNG & cucumber-jvm-parallel-plugin)
Steps to implement parallel execution starting from cucumber 4.0.0 -
1.Adding correct set of dependency. I have followed JUnit during the implementation.
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>4.2.3</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit</artifactId>
<version>4.2.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>datatable</artifactId>
<version>1.1.12</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-picocontainer</artifactId>
<version>4.2.3</version>
<scope>test</scope>
</dependency>
2.Adding Maven-Surefire-Plugin under POM.XML
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
<configuration>
<parallel>methods</parallel>
<threadCount>1</threadCount>
<reuserForks>false</reuserForks>
<testErrorIgnore>true</testErrorIgnore>
<testFailureIgnore>true</testFailureIgnore>
<includes>
<include>**/*RunCukeTest.java</include>
</includes>
</configuration>
</plugin>
Note - RunCukeTest is the runner file name and remember, TestNG dependency causes Surefire to ignore JUnit wrapper class. Remove all the TestNG dependencies if not required at all or you would need to define 2 execution one for TestNG & other for JUnit and disable one as per your need.
Once everything is done then you would need to pass browser name you want to run from a source like excel, json etc for each scenario.
If you are using cucumber you have to create multiple runners and then use maven to run them in parallel. So creating runner for every step definition is pain, so we have to create runners in run time in target folder.There are two ways to create runners on run time.
Use cucumber JVM parallel plugin here
If you are using the newest version of cucumber there is an awesome plugin called cucable
Here

run maven tests from classpath

In order to clean up something of a giant mess, I set out to put the code of my tests all in one ordinary java project (all in src/main/java), and then declare that as a <scope>test</scope> dependency in another project, and expect the tests to run.
No such luck. surefire wants to just run the tests that it can see in the sources.
I can see a sadly obvious solution here involving the build-helper-plugin and adding the tests into the test compilation environment as a source directory, but I was hoping to avoid it.
In case anyone is wondering, the reason for all this is that the POM configuration for use of the failsafe plugin to run some integration tests got so complex that I wanted to split out the compiling of the test classes from the running of the tests.
This is now possible with Maven Surefire v2.15. Simply add the following kind of configuration to the surefire plugin:
<build>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.15</version>
<configuration>
<dependenciesToScan>
<dependency>com.group.id:my-artifact</dependency>
<dependency>com.group.id:my-other-artifact</dependency>
</dependenciesToScan>
...
</configuration>
...
</plugin>
...
</build>
You should also declare the actual dependencies in the dependencies section:
<dependencies>
<dependency>
<groupId>com.group.id</groupId>
<artifactId>my-artifact</artifactId>
<type>test-jar</type>
<version>1.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.group.id</groupId>
<artifactId>my-other-artifact</artifactId>
<type>test-jar</type>
<version>1.1</version>
<scope>test</scope>
</dependency>
</dependencies>
No such luck. surefire wants to just run the tests that it can see in the sources.
This is currently not possible out of the box, surefire just looks at classes in target/test-classes:
Re: Surefire not picking up tests from test-jar
Re: maven-surefire-plugin: run unit tests from classes in a jar, not a directory
This is actually logged as SUREFIRE-569 - There should be a way to run unit tests from a dependency jar.
I can see a sadly obvious solution here involving the build-helper-plugin and adding the tests into the test compilation environment as a source directory, but I was hoping to avoid it.
The current workaround is to use dependency:unpack to unpack the jar into target/test-classes before the test phase.
Can't you do it the other way round?
I mean put the code the src/test/java, depend on your main module, and run the tests in your test module?