Running JUnit Tests in IntelliJ with category annotations - java

I am trying to run all tests with the annotation #FastTests in a module using IntelliJ . I can run all tests in the module using the JUnit configuration with the test kind All In Package and the relevant package name.
When I try to run a single category by choosing the Category test kind JUnit configuration and choose Search For Tests: Across Module Dependencies or Search for Tests: In Single module I get No Tests were found
Is there a way to run JUnit tests with annotated with a single category in intellij?
Cheers

This works for me using Intellij IDEA 2018.1:
with category marker defined as interface:
public interface FastTests { /* category marker */ }
and test class or method annotated like this:
import cu.nicolau.sircap.nomencladores.FastTests;
import org.junit.Test;
import org.junit.experimental.categories.Category;
public class NomencladorServiceImplTest {
#Test
#Category(FastTests.class)
public void categoryTest() {
...
}
}
With JUnit 5, the #Category annotation gets replaced with the more flexible #Tag annotation.
If you consider migrating to JUnit 5, this blog can be a good place to start. Also, this and this answer can show you how to filter the tests execution based on their tags, using Intellij IDEA or Maven.

Related

Create TestSuite in JUnit5 (Eclipse)

I have created multiple Test case java files in eclipse and version of JUnit is JUnit5.
Now, I am trying to create a Junit TestSuite through the eclipse GUI and during the creation, I am not seeing the JUnit5 in the available versions.
This is the sample code that I have written for creation of TestSuite.
import org.junit.platform.runner.JUnitPlatform;
import org.junit.platform.suite.api.IncludeClassNamePatterns;
import org.junit.platform.suite.api.IncludeEngines;
import org.junit.runner.RunWith;
#RunWith(JUnitPlatform.class)
#IncludeClassNamePatterns(".*Tests?")
#IncludeEngines("junit-jupiter")
public class AllTests {
}
This is the error I am getting while executing.
Should I do any manual setting to be able to create/run test suites?
When executing tests in a class annotated with #RunWith, that class is technically a JUnit 4 test class.
Thus, you have to execute your test suite using the "JUnit 4 Runner" in the "Run Configurations" of Eclipse.
See the following Eclipse bug for more information: https://bugs.eclipse.org/bugs/show_bug.cgi?id=512772
Regarding the "JUnit Test Suite" dialog, that won't help you if you are using #RunWith(JUnitPlatform.class) to execute a suite in JUnit 5.
you are not using JUnit5, Junit5 FQN is org.junit.jupiter.api.*
see https://www.eclipse.org/community/eclipse_newsletter/2017/october/article5.php

Using SpringBootTest annotation

I've built an API using Spring Boot and have a few unit tests associated with it so far. As expected these are ran locally and when Jenkins builds the project via gradle build on the build server. I'm looking to add some integration tests to the project now using rest-assured so I can actually test request and responses but I'm not overly clear how to add them to the project.
So far I've added an integrationTests folder to src/test and have told gradle to exclude the rest-assured tests when gradle build or via gradle test so I can keep them independent. I've setup a gradle task gradle integrationTest to trigger the integration tests which runs fine as long as the API is currently running.
Apparently I can annotate the test class with #SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT) to instruct spring to start up an embedded server for testing automatically but it doesn't appear to be doing anything, the tests just fail with a java.net.ConnectException error until I start the API in another window. Is there anything wrong with the below sample code or am I missing something else?
com.example.restassured;
import org.junit.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import static io.restassured.RestAssured.*;
#SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
public class RunSomeTestsIT {
#Test public void url_should_return_200_response() {
get("/v1/test/123456").then().statusCode(200);
}
}
build.gradle
task integrationTest(type: Test) {
include 'com/example/restassured/**'
// Run all tests each time. Do not cache.
outputs.upToDateWhen { false }
}
By co-incidence I was working on something very similar today, and hopefully can provide some useful pointers.
When I compare with this code I think you are missing the #RunWith(SpringRunner.class) annotation !
Edit: other than moving your test to the same package as the "Application" class, you can try a Spring "first-principles" approach which side-steps all the black-magic of the Spring annotations. At least you can troubleshoot things better and control what's going on:
https://github.com/ptrthomas/spring-testing/blob/master/src/test/java/example/HelloE2ERestKarateTest.java

Finding all tests in a subpackage

When I try running JUnit tests, I get the error message
No tests found with test runner 'JUnit 4'
and therefore I have tried solutions from
No tests found with test runner 'JUnit 4'
junit: no tests found
'No JUnit tests found' in Eclipse
However, in my case, the difference seems to be that I specify the tests to run on package level instead of folder level.
Running JUnit tests works if I specify a package that directly contains test classes (e.g. com.example.tests.smoketests) but does not work if a higher level package is specified (e.g. com.example.tests).
If I define a test in com.example.tests, it is found and run.
Is there a way to let Eclipse/JUnit find tests in a package and all subpackages?
Out of the box, there is nothing to do this for you. You can use the Suite annotation to achieve this goal in JUnit4, though this still requires you to manually define a Suite test for each package, and then include all of them in a aggregate Suite test (such they recursively call child Suites).
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import a.sub.package.AnotherSuiteTest.class;
#RunWith(Suite.class)
#Suite.SuiteClasses({
PackageLocalTestClass1.class,
PackageLocalTestClass2.class,
AnotherSuiteTest.class
})
public class JunitTestSuite {
}
I've played around with building my own utility class before which creates the entire series of tests. This article provides an analogous utility.

How to automatically create a list for #SuiteClasses

I need a possibility to run a subset of my JUnit tests cases during Maven build process. I've decided to use JUnit categories for this purposes. I've created two marker interfaces: UnitTest and IntegrationTest and assigned them to the bunch of my JUnit test cases. Now I need to create a test suite for them:
package ru.hive.parser;
import org.junit.experimental.categories.Categories;
import org.junit.experimental.categories.Categories.IncludeCategory;
import org.junit.runner.RunWith;
import org.junit.runners.Suite.SuiteClasses;
import ru.hive.test.UnitTest;
#RunWith(Categories.class)
#IncludeCategory(UnitTest.class)
#SuiteClasses({ SomeClass.class })
public class ParserTestSuite {
}
The problem is #SuiteClasses annotation in which I need to list all the classes I want to be in test suite and I have A LOT (more than 100) of such classes and the number is growing. I will be nice if I have the way to build the list of classes automatically. I've read all the question here on stackoverflow that some sort similar to my own, but none of the answers fit my needs since I need to use #RunWith(Categories.class) instead of other test runners. Any ideas how to realize this?
Maven is able to use the categories runner. See here: http://maven.apache.org/surefire/maven-surefire-plugin/examples/junit.html
You could also use the classpath suite and modify it to use the categories runner for tests found on the classpath (if it doesn't do so already?).
Generating a long list of #SuiteClasses doesn't seem worth the effort.

Run all tests in Junit 4

I want to be able to run all tests in a project programmatically. I know Eclipse has a "Run as JUnit test" configuration which somehow grabs all the tests in a project and run them. Is there any way for me to also grab the list of tests programmatically and run them? Or is there some good way to construct a test suite containing all the test cases without manually listing out every one (all 700+) of them?
I've tried the "New... -> Test Suite" option in Eclipse, but that seems to work only for JUnit 3, identifying tests by their extending from TestCase
The test classes are JUnit 4, so their only distinguishing characteristic is the annotation, no naming convention, no subclassing from TestCase.
Thanks in advance!
Though it does not really solve your immediate problem, I find it a very useful general practice to create suites and suites of suites, e.g. for a package something like PackageFooSuite etc. and assemble these suites in one or more suites again, like ModuleFooSuite and have one top-level suite, like AllTestsSuite. That way it's easy to run both all tests in one step as well as submodule tests for the package I'm currently working on (and have the tests run quicker than if I would always run all of them):
#RunWith(Suite.class)
#Suite.SuiteClasses({ PackageFooSuite.class, PackageBarSuite.class} )
public final class AllTestsSuite {} // or ModuleFooSuite, and that in AllTests
None of the other answers did it for me. I had 40k tests I needed to run, so manually listing every class was not an option.
I did it with ClasspathSuite. A test suite that runs all Junit4 and Junit3 test cases in the class path is as follows:
import org.junit.extensions.cpsuite.ClasspathSuite;
import org.junit.extensions.cpsuite.ClasspathSuite.*;
import org.junit.runner.RunWith;
import org.junit.runner.JUnitCore;
import static org.junit.extensions.cpsuite.SuiteType.*;
#RunWith(ClasspathSuite.class)
#SuiteTypes({ JUNIT38_TEST_CLASSES, TEST_CLASSES })
public class RunAllSuite {
/* main method not needed, but I use it to run the tests */
public static void main(String args[]) {
JUnitCore.runClasses(RunAllSuite.class);
}
}
I needed to run it from command line, so this is what I did:
Downloaded cp-1.2.6.jar
Create the previously mentioned RunAllSuite
Compile the class, javac RunAllSuite.java -cp cpsuite-1.2.6.jar;junit-4.8.1.jar
run it with target tests in the class path, java -cp cpsuite-1.2.6.jar;junit-4.8.1.jar;path/to/runallsuite/folder;target/classes;target/test-classes RunAllSuite
And that's it. With the RunAllSuite above, anywhere in your code you can just do JUnitCore.runClasses(RunAllSuite.class), which runs all tests in class path. There are other config options as well which are explained in the ClasspathSuite home page.
Note also that the class given above does not print anything. If that is needed, you can do
import org.junit.extensions.cpsuite.ClasspathSuite;
import org.junit.extensions.cpsuite.ClasspathSuite.*;
import org.junit.runner.RunWith;
import org.junit.runner.JUnitCore;
import org.junit.internal.TextListener;
import static org.junit.extensions.cpsuite.SuiteType.*;
#RunWith(ClasspathSuite.class)
#SuiteTypes({ JUNIT38_TEST_CLASSES, TEST_CLASSES })
public class RunAllSuite {
public static void main(String args[]) {
JUnitCore junit = new JUnitCore();
junit.addListener(new TextListener(System.out));
junit.run(RunAllSuite.class);
}
}
You can do this fairly easily from within maven using the surefire plugin: I usually clean/compile/install my projects from the command line before comparing them for eclipse usage (mvn eclipse:clean eclipse:eclipse) and you can define a test suite in your pom which lists all the tests you want to run en masse every time you run mvn install. You're not calling them programatically, exactly, but you can certainly call them en masse.
In Eclipse (I'm using 4.6.1) - Right click the project folder, select "Run As", choose "JUnit Test"
It will run all tests in that project. Same for a package.
Of the top of my head using Spring:
Implement a TypeFilter that matches classes with methods annotated with #Test (don't forget to consider the superclasses)
Invoke classpath scanning on your top-most test package
Invoke the JUnitRunner with the scan results
More info on classpath scanning and custom type filters here
With Eclipse Indigo (possibly Helios as well) in the Run Configurations dialog box, you now have the ability to Run all tests in a selected project, package or source folder.
Also a good reference from Eclipse is the article Java Unit testing with JUnit 4.x in Eclipse.
I also recommend using the JUnit Suite annotations. Follow the link for more detail.

Categories