Maven surefire plugin DOES NOT run single test, out of many - java

I have a maven project (multimodule, JDK 11) that has a lot of modules and tests within it.
I suddenly noticed that one of my tests is NOT invoked as part of the surefire plugin.
Other tests in the same module do get to be invoked successfully.
I am able to run this test successfully via Intellij. The test is not disabled nor ignored. it contains a set of #Test methods. In addition, I am able to run it specifically using mvn test -Dtest=... argument.
The test class gets to be compiled successfully and appears in target/test-classes.
(I have already run with -X and could not find relevant additional data there)
I am working with surefire plugin 2.22.1 ; junit-vintage-engine:5.2.0 ; junit-platform-runner:1.2.0 ; Spring Boot 2.5.3 (with BOM) ; My test is spring based and invoked using #ExtendWith(SpringExtension.class)
(I do have other spring based tests that are invoked as expected though).
Following this question, I have also tried to work with 2.22.2. It did not solve the problem
Following this question, I have verified and indeed all tests in the test class that does not invoke are prefixed with the 'test' word
EDIT:
The problem happens in a test that belongs to a module that is part of a larger project in my company, which inherits various defaults across the POM inheritance chain. Unfortunately, I can not isolate only my POM out of it and present it.
I have tried to reproduce the problem in a new isolated project but did not succeed (that is, all the tests were invoked as expected).
What am I missing? Is there a hidden switch of the surefire plugin that reveals what's going on under the hood and where do surefire pull the list of tests he is meant to execute?

The surefire plugin (by default) will run only tests with the following name syntax ...
"**/Test*.java" - includes all of its subdirectories and all Java filenames that start with "Test".
"**/*Test.java" - includes all of its subdirectories and all Java filenames that end with "Test".
"**/*Tests.java" - includes all of its subdirectories and all Java filenames that end with "Tests".
"**/*TestCase.java" - includes all of its subdirectories and all Java filenames that end with "TestCase".
More details can be found here

Problem solved!
Following #Kathrin Geilmann comment:
...By default surefire only executes: ...Test.java, Test....java,
...Tests.java and ...TestCase.java
The name of my file ended with ...Tester (!##$$%^)
Thanks.

Related

Java Maven Cucumber how to correctly rerun tests from the commandline?

Hi i'm using i'm currently using Cucumber version 6.8.1 and i'm trying to figure out how to solve rerunning of failed tests. I've hacked together my own solution but it feels incorrect. In order for
maven clean install
to detect the test runners i appended Test to their names:
#RunWith(Cucumber.class)
#CucumberOptions(plugin = { "de.monochromata.cucumber.report.PrettyReports:target/cucumber", "rerun:target/rerun.txt" })
public class CucumberRunnerTest {
}
and
#RunWith(Cucumber.class)
#CucumberOptions(
features = "#target/rerun.txt",
plugin = {"pretty", "html:target/site/cucumber-pretty",
"json:target/cucumber.json"}
)
public class RerunningTest {
}
Now this works but it seems a bit hacky. since commands like
mvn clean install -Dcucumber.glue="cucumber" \
-Dcucumber.plugin="de.monochromata.cucumber.report.PrettyReports:target/cucumber" \
-Dcucumber.plugin="rerun:target/rerun.txt"
should work, but don't work. The build is successful but no tests run. It's like Dcucumber is being ignored by maven. However, after appending "Test" to the runners and then running the command above uses both runners since they're treated as Tests which feels wrong.
So my question is how can i make this work correctly with Dcucumber?
If you don't name your test class *Test then Surefire won't recognize it. Naming convention wise, try using RunCucumberTest instead. It isn't too ugly.
https://maven.apache.org/surefire/maven-surefire-plugin/examples/inclusion-exclusion.html
Inclusions and Exclusions of Tests
Inclusions
By default, the Surefire Plugin will automatically include all test classes with the following wildcard patterns:
"**/Test*.java" - includes all of its subdirectories and all Java filenames that start with "Test".
"**/*Test.java" - includes all of its subdirectories and all Java filenames that end with "Test".
"**/*Tests.java" - includes all of its subdirectories and all Java filenames that end with "Tests".
"**/*TestCase.java" - includes all of its subdirectories and all Java filenames that end with "TestCase".
If the test classes do not follow any of these naming conventions, then configure Surefire Plugin and specify the tests you want to include.

Running a code with JUnit Test Cases

I have checked out a code from CVS and need to make changes to it. The code has 2 folders
Java
Test
The later has JUnit test cases. I'm not very familiar with JUnit but as far as my understanding is, the classes are duplicated in JUnit as class names. That's why I get the error in the test folder.
Class "xxxxx" already exists
I'm not sure how do I run this project without removing the folder test. Is there a way I can make eclipse ignore the JUnit test cases for now?
Go into the properties of the Eclipse project, open Java Build Path / Source and remove folder Test. Eclipse will then ignore the sources in that folder.
Test and normal java classes are merged together during build time, your error happens because the test classes have the exact same name as the normal classes. You should rename your test cases with some kind of prefix like Test to prevent them conflicting.
Doing things to work around the problem will only conflict later when you are changing the build platform, maybe your current build platform accepts it, but your future platform/editor may not, and then you have the real problems.

Gradle + TestNG only runs certain tests as single tests

I've been using Gradle + TestNG + Java + Selenium for my web UI tests for quite a while now and I've only recently run in to this issue. For some reason when I try to run a single test class using -DtaskName.single=ExampleTestClass where ExampleTestClass would be ExampleTestClass.java it only works on some of my test classes.
I'm getting the error: Could not find a matching test for pattern: ExampleTestClass
I've seen this error in the past due to typos or missing #Test annotations etc, so I'm familiar with the "normal" cause, but this is quite bizarre as it appears to work on some test classes and not others. I've inspected the code and all annotations and groups are in place for the test methods, they run fine from my IDE (IntelliJ), and they are all located in the same directory / package path. Is there something I'm missing here? I don't know if I'm seeing things but I did notice that it didn't work with a test class that did not have Test as the last four characters of the Java class name but upon renaming it, still no dice. I've read the documentation and can't find anything wrong. Is there anything else that may be causing this to fail? It's quite odd since these tests are all so similar in every way. I even checked character encoding etc - no discrepancies between any of them.
Any advice or ideas on where to look next would be great.
Cheers,
Darwin
I ran into the exact same thing with gradle 1.6 (haven't had time to upgrade), and TestNG. A single test in a project with multiple tests get skipped and also gradle complains about not finding it if you try running the single test alone. Debug run shows the missing test .class file being found by gradle.
I worked around it by adding an #Test annotation to the test class in addition to the test method. That seems to make gradle find it.
I recently ran into a similar issue. I tried to run a test with -DTest.single and --tests but it wasn't found. After a bit of frustration I realized that the test was in a test group that was excluded in my test task configuration. I had incorrectly assumed that running with -Dtest.single would overrule exclusions, including that test's group allowed it to run as a single test.

Gradle test tasks with webcontext fails to use entities

I have an issue with some gradle task that should run tests. Since this is some legacy from ant tasks we do not want to include them into our test suite. Especially considering that those ant ones are in testng, and those made by us, and used on regular basis are made using spock and junit.
The problem is that those tests are using some context which works pretty well when I run those tests under eclipse IDE, but it fails if I try to do sth like:
task testNgTesting(type: Test, dependsOn: testClasses){
useTestNG()
includes = ["**/*IT*"]
}
But when I try to use that task I get errors like "org.hibernate.MappingException: Unknown entity:" or "java.lang.IllegalArgumentException: No query defined for that name"
Actually the problem is deeper. Gradle is trying to be smart and from whatever folder it has defined it puts classes files into classes folder, and all the other files into resources. When persistence.xml is loaded it scans for annotated entities starting with classpath root for folder it is present in (i.e. build/resources/main). Since all those classes are in build/classes/main it fails to find them. The workaround I've made is introduce two copy tasks. one named is copying persistence.xml into classes folder, and another is moving this file back to resources after the tests are finished. You might want to use something like
testNgTesting.finalizedBy(cleanAfterIntegrationTests) to make sure the cleanup occurs even if there are some tests that fails.

How to run Tests when developing javaagents?

I'm trying to fiddle with Foursquare's HeapAudit, and am attempting to set it up using IntelliJ IDEA. I have managed to get it to build just fine, using the dependencies from the pom.xml.
However, when I actually try to run the JUnit tests, basically all of them fail. I'm guessing this is because using HeapAudit requires the JVM to be started with it as a -javaagent, according to the github:
$ java -javaagent:heapaudit.jar MyTest
Presumably the tests would pass if I put this line in, and referenced the heapaudit.jar i downloaded/built earlier. However, it seems to me that if I make changes the the source, I'm gonna need to re-package this silly .jar file in order to see if it works.
Is there any way of running the tests with a -javaagent without going through the whole rigmarole of compile -> package-into-jar every testing cycle? Perhaps getting IntelliJ to attached the newly-compiled .class files as a -javaagent before running the tests?
1) Have a jar just with a META-INF/MANIFEST.MF
The manifest must be properly configured with Premain-Class and other attributes. The jar doesn't need any other files. Use this jar with the -javaagent. Provided that the agent classes are in the classpath, the agent will start normally.
This might fail when using maven-surefire-plugin with forkMode=never because by default the application classes are loaded in a child ClassLoader.
Works fine with Eclipse and Intellij.
If doing this, double check the manifest syntax (once I spent a long time to figure out that a package name was wrong).
2) Use ea-agent-loader
It will allow you to load the agent (any agent) in runtime (it uses VM.attach()). However the VM.attach() sometimes disrupts debugging and breakpoints might fail to trigger.
It will have the same issues with the surefire in forkMode=never
3) Load the agent in runtime.
Write your on code to load the agent in runtime. And call it from your #BeforeClass You will still need a jar (which you can generate in runtime if you want).
Just you need to call this (only once):
AgentLoader.loadAgentClass(YourAgentClass.class.getName());

Categories