JUnit5 Test Suite doesn't test all classes from a package - java

I've got a Suite class as follows:
package test.suite;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.platform.suite.api.SelectPackages;
import org.junit.platform.suite.api.SuiteDisplayName;
import org.junit.runner.RunWith;
#RunWith(JUnitPlatform.class)
#SuiteDisplayName("JUnit Platform Suite Demo")
#SelectPackages("test")
public class Suite {
}
And two identical test classes (they differ only by their name at the moment) in the same package called test:
package test;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
public class testClass1 {
#Test
void mainA() {
assertTrue(42==42);
}
When I hit run on 'Suite', only testClass1 will be tested and testClass2 is left out. What am I missing?
The Suite should test classes even recursively from other subpackages in the given package if I'm not mistaken.
--EDIT:
Initially I created two test classes for the same class, and the second test class gets ignored. If I add a third test class in the package, but this time for a separate class, that will get tested as expected.

I was experiencing same issue. I had several files and in my case when i do run as suite some of them would be included and other would not. It was pretty frustrating as I can run them fine individually.
It turned out the one that were not included were those whose name did not end with Test. For example, ClassA wouldn't be added but once i renamed to ClassATest it got added when running as suite package feature.

Related

Why am I asked to refactor code and include org.testng.AssertJUnit when creating testng.xml suite?

I have two TestNG classes containing a few #Test annotations, nothing fancy, and test methods just under them. When I select both of my class files in Eclipse, right-click, choose TestNG - Convert to TestNG, I am presented with a refacotoring wizard in Eclipse to create said testng.xml suite. But when I cliked Next, I'm asked to refactor my code and include org.testng.AssertJUnit.
Why JUnit? What does JUnit have to do with this?
Here's a code sample:
package seleniumTestovi.Pages; import org.testng.Assert;
import org.testng.annotations.Test;
public class NewTest {
#Test
public void foo() {
Assert.assertTrue(true);
}
}
And here is the code Eclipse wants me to refactor when i try to create testng.xml suite.
package seleniumTestovi.Pages;
import org.testng.annotations.Test;
import org.testng.AssertJUnit;
import org.testng.annotations.Test;
public class NewTest {
#Test
public void foo() {
AssertJUnit.assertTrue(true);
}
}

Can't add the test classes in JUnit suite

I use Eclipse Oxygen and JUnit 5. I have a class with a method and 3 test cases for the method that work fine. When I try to create a JUnit test suite to group all the cases by new/other/Java/JUnit/Junit test case in the window for test suite nothing appears in "Test classes to include in suite" despite that everything is in one packet and even set to public. I create the test suite and manually type in the classes I want to include in the test suit.
package testing;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
#RunWith(Suite.class)
#SuiteClasses({oddNumberOfLettersPalindromeTest.class,
evenNumberOfLettersPalindromeTest.class, notAPalindromeTest.class})
public class AllTests {
}
When I run the AllTest suite I get only 1/1 runs for the same AllTest suite class. All my JUnit tests have #Test as well
Correct me if I wrong but do you want to add new classes every time foreach test? In that case you can use the #Before tag in JUnit. What it does is it generates a new class every time a #Test is hit.
private TestClass test;
#Before
public void setUp()
{
test = new TestClass();
//You can declare other classes right here
}
did you tried to follow this example ?
JUnit - Suite Test - Tutorials Point
It has to do with versions of JUnit or something, on my laptop it was JUnit 5 and eclipse oxygen, now I am on JUnit4 and eclipse Mars and everything is working fine. I just wanted to group few testcases in one suite
It looks like your test suite is not importing the test cases you want to trigger. Also, apparently your test cases are not following the class naming pattern (starting with lower case and so on).
package testing;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
import OddNumberOfLettersPalindromeTest;
import EvenNumberOfLettersPalindromeTest;
import NotAPalindromeTest;
#RunWith(Suite.class)
#SuiteClasses({OddNumberOfLettersPalindromeTest.class,
EvenNumberOfLettersPalindromeTest.class, NotAPalindromeTest.class})
public class AllTests {
}
I believe by doing this it has no reason to work.
Try changing the Junit version to Junit4 in build path -> libraries.

Android UnitTest - RuntimeExceptions for Android classes

I'm developing an SDK and I'm trying to perform UnitTests on it.
This means most of the my project is pure java code which involves Android code in some places.
I want to perform UnitTest on my SDK and I decided to with with Roboelectric, Mockito and PowerMock (for static methods mocks).
Everything works fine except one issue:
When my test calls any method which contains Android class, my test crashes (due to Stub issues).
I know I can't test Activity,Views and more classes but the problem is I get RuntimeException even when my functions contain a use with Log class.
How can I handle this issue?
I decided to work with pure UnitTest because most of my code doesn't contain Android classes except of Log class. By using pure java UnitTest I don't need any device to run and as a result I can perform multi test task on the same time.
I've tried to include the android.jar file in my gradle but it didn't work.
What should I do?
1. Stick to pure Java UnitTest: so how can I ignore/import the Log instructions.
2. Move to Android test framework: What is the best for my needs?
Here is a section in my gradle file relevant for the tests:
robolectric {
// configure the set of classes for JUnit tests
include '**/*UnitTest.class'
// confgure max heap size of the test JVM
maxHeapSize = '2048m'
// configure the test JVM arguments
jvmArgs '-XX:MaxPermSize=512m', '-XX:-UseSplitVerifier'
// configure whether failing tests should fail the build
ignoreFailures true
// use afterTest to listen to the test execution results
afterTest { descriptor, result ->
println "Executing test for {$descriptor.name} with result: ${result.resultType}"
}
}
dependencies {
androidTestCompile 'org.robolectric:robolectric:2.3'
androidTestCompile 'junit:junit:4.10'
androidTestCompile 'org.mockito:mockito-core:1.8.5'
androidTestCompile 'org.powermock:powermock-mockito-release-full:1.4.9'
androidTestCompile files('../libs-test/json.jar')
}
And here is an Example of a TestCase class:
import android.util.Log;
import junit.framework.TestCase;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.junit.Test;
import org.json.JSONObject;
import static org.powermock.api.mockito.PowerMockito.when;
#RunWith(PowerMockRunner.class)
#PrepareForTest(StaticInClass.class)
public class ClassExampleUnitTest extends TestCase{
#Test
public void testSimple(){
Log.d("UnitTest", "test");
assertTrue(true);
}
}
When you run with PowerMockRunner, you aren't actually running through robolectric. Normally you would run like this, when you need the robolectric framework:
#RunWith(RobolectricTestRunner.class)

Can I avoid running junit tests twice in eclipse when using a TestSuite?

I need to do some per-suite initialisation (starting a web-server). It is working fine except that when I run all tests in my project in eclipse my tests run twice. My test suite looks a bit like this:
#RunWith(Suite.class)
#Suite.SuiteClasses({
SubtestOne.class,
SubtestTwo.class
})
public class TestSuite
{
[...]
}
public class SubtestOne
{
#Test public void testOne() { [...] }
}
public class SubtestTwo
{
#Test public void testTwo() { [...] }
}
When I run all test in project in eclipse this causes the junit plugin to run the tests twice like this:
SubtestOne
SubtestTwo
TestSuite
SubtestOne
SubtestTwo
Is it possible to make "run all test in project" not run the sub-tests twice? I want my sub tests to be only ever run as part of the suite.
No, the test class will always be started directly and then through the "link" in the suite. This is as expected.
One workaround might to set in the run configuration to only run tests from the package which contains your suites. Open the run configuration and select Run all tests in the selected project, package or source folder then click Search... and select the package.
I realize that this has been asked over 5 years ago, but as quite a few folks up-voted the question I thought I'd still chime in with a solution. Skip right to the end if you just want the solution; read the whole text if you also want to understand it ;-)
First of all, it is indeed possible to ensure that a particular JUnit test class gets only run inside a test suite. Also, it is irrelevant whether you want to run that test suite inside Eclipse (as asked here) or any other tool or environment; this is really a pure JUnit issue for the most part.
Before I sketch out the solution, it might be a good idea to revisit what the exact problem is here. All JUnit tests need to be visible and instantiable to be picked up by the JUnit framework and its various runners. This also applies to test suites and the individual tests that are part of a test suite. As a consequence, if JUnit picks up the test suite it will also pick up the individual tests, and all tests in the suite will be executed twice, once individually and once as part of the suite.
So, the trick, if you will, is to prevent JUnit from picking up the individual tests while still being able to instantiate and execute them as part of the suite.
One thing that comes to mind is to make the test classes static inner classes nested inside the test suite. However, the nested classes still need to be public (otherwise they can't be run in the suite either), and if they are public classes they will also be picked up individually, despite being nested inside the suite's public class. JUnit will not try to run test classes that are not considered visible, though. So, nesting the test classes inside a non-public class would presumably be sufficient to hide them, but we can't make the suite class non-public because then JUnit would not execute it. What we can do, however, is to nest the individual tests inside another non-public class that's nested inside the test suite, which leads us to the solution of this conundrum:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
#RunWith(Suite.class)
#SuiteClasses({AllTests.InSuiteOnly.Test1.class, AllTests.InSuiteOnly.Test2.class})
public class AllTests
{
static class InSuiteOnly
{
public static class Test1
{
#Test
public void test1()
{
//...
}
}
public static class Test2
{
#Test
public void test2()
{
//...
}
}
}
}
A lot of folks will probably object to all tests needing to be inside a single source file now. What if I want to maintain separate JUnit test classes that don't get executed by themselves but still get executed inside the test suite? A simple solution is to make the individual test classes abstract (public/non-public doesn't matter) so that JUnit won't execute them, and inside the test suite we simply use concrete subclasses of the original abstract test classes:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
#RunWith(Suite.class)
#SuiteClasses({AllTests.InSuiteOnly.SuiteTest1.class, AllTests.InSuiteOnly.SuiteTest2.class})
public class AllTests
{
static class InSuiteOnly
{
public static class SuiteTest1 extends Test1 {}
public static class SuiteTest2 extends Test2 {}
}
}
abstract class Test1
{
#Test
public void test1()
{
//...
}
}
abstract class Test2
{
#Test
public void test2()
{
//...
}
}
This scheme works with Maven, Eclipse, and all other environments that either directly leverage JUnit's runners or implement their own runners that closely follow JUnit's original behavior and semantics.
I have an idea for you. Actually you do not want to run these test case as stand-alone test cases. You can do the following.
Mark the test cases with annotation #RunWith(DoNothingRunner.class)
Implment DoNothingRunner as following:
public class DoNothingRunner extends Runner {
public Description getDescription() {
return "do nothing";
}
public void run(RunNotifier notifier) {
// indeed do nothing
}
}
I have not tried this personally but I hope this will work.
do you need the suite in the first place ? depending on when you click for run all (class, package, or src/test/java), all underlying tests will be executed. So what's the point of having a suite ?
There is a solution, it's a bit tricky, but it may easily resolve your problem: create one suite class, and include all your suite classes in it. Then you can use this suite class to run all your tests.
#RunWith(Suite.class)
#Suite.SuiteClasses({
AXXSuite.class,
BXXSuite.class,
CXXSuite.class
})
public class AllSuites {
}

Is it possible to run JUnit tests from multiple packages in Eclipse?

Is it possible to run JUnit tests for multiple packages at the same time without manually creating test suites.
For example if I have the hierarchy:
code.branchone
code.branchone.aaa
code.branchone.bbb
code.branchtwo
code.branchtwo.aaa
code.branchtwo.bbb
Is it possible to:
Run all tests in code.branchone and in descendent packages
Run all tests in say code.branchone.aaa and code.branchtwo.bbb
The problem I see with manually creating test suites is that when new tests come along you may forget to add them.
Yes, it is possible. The easiest way for me at least is to add a test suite class. It can look like this:
package tests;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
import tests.message.ATest;
import tests.validator.BTest;
import tests.validator.CTest;
import tests.validator.DTest;
#RunWith(Suite.class)
#SuiteClasses({ ATest.class,
BTest.class,
CTest.class,
DTest.class })
public class AllTests {
}
This will allow you to test any class that you import no matter what package it is in. To run this in eclipse you just right click the AllTests class and run it as JUnit test. It will then run all the tests you define in #SuiteClasses.
This will work with linked sources as well, I use it all the time.
An other way:
Click on the black triangle denoted by red rectangle in the picture below (in your Eclipse, not here :).)
Then open run configurations, create a new configuration and then set "Run all tests..." as exemplified in the image below.
Maybe not exactly what the original question was, but you can easily run all tests of a whole Project, by simply right-clicking the project -> Run As JUnitTest. Don't worry where the annotated classes reside, this will be scanned.
This does not work if applied to the test-src-folder or a package with subpackes. Quite a shame actually -.-
I'm sure u can tweak this a bit. Make a Collection of the CLASSES_DIR property and loop over it in the findClasses method. (junit4)
http://burtbeckwith.com/blog/?p=52
I beleieve that you can add all your test packages to a single directory. If you right click on this directory, then you should find the "run as -> JUnit test" option available. This will run all tests contained in the directory and will catch anything you've added. Any new tests get put in there with the rest of them and whatever package name you have it doesn't matter. Hope that helps
Sure, right-click on the packages you want, and select Run As... JUnit Test
In Eclipse, on your debug/run configurations you have the following options:
Run a single test
Run all tests in the selected project, package or source folder
I think the second option is your friend in this case.
If you are using JUnit 5 you can cherry pick which tests you want to run:
import org.junit.platform.suite.api.SelectClasses;
import org.junit.platform.suite.api.Suite;
import tests.Test1;
import tests.Test2;
import tests.Test3;
#Suite
#SelectClasses({
Test1.class,
Test2.class,
Test3.class
})
public class AllMyTests {
}
If you want to select which packages to run you can:
import org.junit.platform.suite.api.SelectPackages;
import org.junit.platform.suite.api.Suite;
#Suite
#SelectPackages({
"com.package1",
"com.package2",
"com.package3"
})
public class AllMyTests {
}
If you need to be able to exclude certain sub-packages you can do:
import org.junit.platform.suite.api.ExcludePackages;
import org.junit.platform.suite.api.SelectPackages;
import org.junit.platform.suite.api.Suite;
#Suite
#SelectPackages({
"com.package1",
"com.package2",
"com.package3"
})
#ExcludePackages({
"com.package1.subpackage",
"com.package2.othersubpackage"
})
public class AllMyTests {
}
Other useful annotations:
To match a particular pattern:
#IncludeClassNamePatterns({"^.*ATests?$"})
To exclude a particular pattern:
#ExcludeClassNamePatterns({"^.*ATests?$"})
Examples were based on: https://howtodoinjava.com/junit5/junit5-test-suites-examples/

Categories