Eclipse - No tests found with test runner 'JUNIT 4' - spring

I have generated a spring boot project from start.spring.io and imported it into STS. The tutorial I'm watching wants to run a JUNIT test before continuing. But when I try to run Junit test I get the following error "No tests found with test runner 'JUNIT 4'.
Also tested with following dependency
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
Any suggestion on how to fix this?
I suspect class DevopsApplicationTests. If I add class DevopsApplicationTests extends TestCase then unit test works but fails. Not sure what should be the correct code.
When testing "import org.junit.Test" I see the following errors.
When trying "import junit.framework.Test;" Also I get "No tests found with test runner 'JUNIT 4' like before but also there is a error near "#Test".

You're using the wrong import.
org.junit.jupiter.api.Test is the annotation for JUnit 5.
For JUnit 4, you need to import junit.framework.Test.
By the way, the latest version of STS is 3.8.0, released in 2017, based on Eclipse Neon from 2016.
STS is deprecated, and is replaced by 'Spring Tools 4 for Eclipse': https://spring.io/tools

Making the class Public fixed the issue.
package com.example.devops;
// import org.junit.jupiter.api.Test;
import org.junit.Test;
import org.springframework.boot.test.context.SpringBootTest;
#SpringBootTest
public class DevopsApplicationTests {
#Test
public void contextLoads() {
}
}

Related

Can not run Junit in eclipse

I am trying to run spring boot crud example with following code
#SpringBootTest
#RunWith(MockitoJUnitRunner.class)
public class CreateUserServiceTest {
#Mock
private UserRepository userRepository;
#InjectMocks
private CreateUserService createUserService;
#Test
public void whenSaveUser_shouldReturnUser() {
User user = new User();
user.setName("Test Name");
when(userRepository.save(ArgumentMatchers.any(User.class))).thenReturn(user);
User created = createUserService.createNewUser(user);
assertThat(created.getName()).isSameAs(user.getName());
verify(userRepository).save(user);
}
}
But after run it gives bellow error.
"NO test found with test runner 'junit5'"
anyone please help me.
Please check the error message from this file.
Edit: I found the root cause.
JUnit 5 uses annotations from a different package than JUnit 4. When you start a test, Eclipse automatically creates a launch configuration for JUnit 5, but if your annotations are not in the new package, Eclipse would not find the tests and will display the error message.
New annotations:
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
// ... other imports from org.junit.jupiter.api
Old annotations:
import org.junit.Test;
// ... imports without "jupiter" in their name
You need to add the following dependencies in a Maven project in order to use JUnit 5:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<scope>test</scope>
</dependency>
Workaround: Use JUnit 4.
You need to select JUnit 4 in your launch configuration. Otherwise this error is shown.
From the main menu select Run -> Run configurations, then select your JUnit test configuration from the navigation bar on the left hand side.

what package should be imported when using #Before #After cucumber Hooks

I'm using Cucumber and Junit for my Maven Project. When I tried to create Cucumber Hooks with #After or #Before annotation and imported cucumber.api.java.Before; package, it didnt work. It says this is deprecated. Can someone tell me what annotation I can use for running the steps before every scenario or if I should import any other package for cucumber hooks? I tried importing io.cucumber.junit.CucumberOptions as well. It didn't work.
I'm using io.cucumber dependencies version 4.8.1. With this version, it shows #After #Before cucumber hooks annotation deprecated but With version 2.0.0,it doesn't show deprecated.
Could someone help on this.
Adapt your imports' packages. There is:
cucumber.api.java.After which is deprecated
io.cucumber.java.After which is not
The same applies to Before.
You need to add below dependency in POM.xml file
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>${cucumber.version}</version>
<scope>test</scope>
</dependency>
Import below packages:
import io.cucumber.java.After;
import io.cucumber.java.Before;

Spring Boot 2.3.1, JUnit 5, Maven 3.6.3 - Maven lifecycle "test" does not run test suite

pom.xml:
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-runner</artifactId>
<version>1.7.0-M1</version>
<scope>test</scope>
</dependency>
...
In <build> only is used:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
Not in use in <build> are the plugins maven-surefire-plugin and maven-compiler-plugin
There are a few test classes (MyTest1Test, MyTest2Test, etc.), testing REST controllers. Some test methods are tagged with "myTag", to be included in a test suite, like:
#SpringBootTest
#AutoConfigureMockMvc
public class MyTest1Test {
...
#Test
#WithMockUser
public void test1() {...}
#Test
#WithMockUser
#Tag("myTag")
public void test2() {...}
...
}
Also there is a test suite, defined like:
#RunWith(JUnitPlatform.class)
#SelectClasses({MyTest1Test.class, MyTest3Test.class})
#IncludeTags({"myTag"})
public class MyTestSuiteTest {
...
}
When I select Maven > test, all test classes are run, only the test suite is not run. Why not? What kind of configuration has to be done?
When I run the test suite itself by right-click > Run 'MyTestSuiteTest' within the test class, it is run correctly.
Trying replacing #RunWith(JUnitPlatform.class with #ExtendWith(SpringExtension.class) doesn't solve it. Maven > "test" doesn't run the test suite, and worth, trying to run the test suite with IDE (right-click on the class > Run 'MyTestSuiteTest") shows and error:
org.junit.runners.model.InvalidTestClassError: Invalid test class '...MyTestSuiteTest':
1. No runnable methods
at org.junit.runners.ParentRunner.validate(ParentRunner.java:525)
at org.junit.runners.ParentRunner.<init>(ParentRunner.java:102)
at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:84)
at org.junit.runners.JUnit4.<init>(JUnit4.java:23)
at org.junit.internal.builders.JUnit4Builder.runnerForClass(JUnit4Builder.java:10)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:70)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:37)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:70)
at org.junit.internal.requests.ClassRequest.createRunner(ClassRequest.java:28)
at org.junit.internal.requests.MemoizingRequest.getRunner(MemoizingRequest.java:19)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:49)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
The IDE tries to run the test suite with JUnit 4, but why? Because of #SelectClasses, #IncludeTags? I have to include the dependency
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-runner</artifactId>
<version>1.7.0-M1</version>
<scope>test</scope>
</dependency>
to be able to use #SelectClasses and #IncludeTags, but also I excluded the vintage engine. Btw, do I have to remove the exclusion of vintage engine, if running a test suite with #RunWith?
Observation:
Including vintage engine:
Using #RunWith, Maven > "test", shows the following in the console output:
org.junit.vintage.engine.discovery.DefensiveAllDefaultPossibilitiesBuilder$DefensiveAnnotatedBuilder buildRunner
WARNING: Ignoring test class using JUnitPlatform runner: ....MyTestSuiteTest
Running the test suite directly with right-click > Run 'MyTestSuiteTest" via IDE shows an additional entry in the unit test view:
MyTestSuiteTest
JUnit Jupiter
MyTest1Test
test2
MyTest3Test
test1
JUnit Vintage
<no name>
Although there are just two annotated methods to run with the test suite (one from MyTest1Test class, and one from MyTest3Test class), it says 3 test were run successfully. JUnit Vintage didn't show up before when vintage engine was exluded.
Using #ExtendWith with vintage engine included:
Maven > "test" doesn't run the test suite, no warning or similar in the console output. "right-click > Run 'MyTestSuiteTest" gives the reported error.
Excluding vintage engine:
#RunWith behaves as described initially in the question.
#ExtendWith Maven > "test" doesn't run the test suite, no warning or similar in the console output. "right-click > Run 'MyTestSuiteTest" gives the reported error.

Auto-Restart for Spring Boot Tests

I am currently writing unit and integration tests for a Spring Boot application. I'm using Spring Tool Suites 4 for development.
When I run the application using Spring Tool Suites, the auto-restart works fine when I modify and save a file. I'm trying to find a similar way to run my tests.
I currently run the tests using a separate Windows CMD terminal using Maven:
mvn test
This runs one time and terminates. Is there anyway to have the tests run every time a test file is saved?
Edit: Here's an example of a test I am running that uses JUnit and Spring to run the tests. This is taken straight from the Spring.io website https://spring.io/guides/gs/testing-web/
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
#SpringBootTest
public class ControllerTest {
#Autowired
private Controller controller;
#Test
public void contexLoads() throws Exception {
assertThat(controller).isNotNull();
}
}
I found this Maven plugin https://github.com/fizzed/maven-plugins#watcher-fizzed-watcher-maven-plugin that will watch files and let you run specific Maven goals on file changes.
I added the plugin to my POM and changed the goal to "test".
<build>
<plugins>
<plugin>
<groupId>com.fizzed</groupId>
<artifactId>fizzed-watcher-maven-plugin</artifactId>
<version>1.0.6</version>
<configuration>
<touchFile>target/classes/watcher.txt</touchFile>
<watches>
<watch>
<directory>src/main/java</directory>
</watch>
<watch>
<directory>src/test/java</directory>
</watch>
</watches>
<goals>
<goal>test</goal>
</goals>
</configuration>
</plugin>
<plugins>
<build>
I opened a terminal within Spring Tool Suites (ctrl + alt + t) and docked it next to my console and ran the following:
mvn fizzed-watcher:run
So far this seems to be working exactly like I want.

error: cannot access BlockJUnit4ClassRunner

While i run the mvn install I'm able to find this above error .
This is my POM.xml i have configured JUnit.
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.4</version>
<scope>test</scope>
</dependency>
This is the service Test class
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration
public class ServiceTestCase {
protected static final Logger LOG = Logger.getLogger(ServiceTestCase.class);
#Configuration
static class AccountServiceTestContextConfiguration {
....
....
....
}
While compiling the above error I am getting.
this Test class I have created in src/test/java
can any one please suggest. How to resolve this ?
When I remove the I am getting error as #Test is not recognise.
Ok, the solution might be quite simple: Update to JUnit 4.5 (or higher).
The javadoc of the BlockJUnit4Runner (which is the Superclass of the SpringJUnit4ClassRunner you are using) states:
#since 4.5
...but as you only use <version>4.4</version>, that's probably the whole problem. Just checked it and the class does simply not exist in JUnit 4.4, so you'll have to upgrade your JUnit version to fix that problem.

Resources