Related
I'm looking for the ability to nest JUnit tests. I found #RunWith(Enclosed.class), but it only runs one level inclosed and other tests aren't run.
Never mind, I found the answer over here: NitorCreations Nested Runner
This is exactly what I was looking for. It allows JUnit tests to be fully nested.
Because NestedRunner tests did not properly visualize test names in my IntelliJ IDEA I am using HierarchicalContextRunner instead
It provides exactly the same functionality. Just swap them in the #RunWith if you are not happy with how your IDE is showing your tests.
Here is an example of what was wrong:
#RunWith(NestedRunner.class)
public class ATest {
#Test
public void haveARegularTestsInside() {}
public class hasASubClass {
#Test
public void thatHasTests() {}
}
}
looks like this:
Here I expected to have thatHasTests at the last line, but got the whole AClass$hasASubClass.thatHasTests.
change #RunWith to HierarchicalContextRunner and what you get is now this:
Better, isn't it?
I am using Struts 2 to create a web application. I am using StrutsTestCase for Junit test case to test the Action class. I have imported struts2-junit-plugin-2.3.4.jar as I am using struts2-core-2.3.4.jar. Inside the testcase method, when i tried to set the request parameters, request variable is not available for use. it is showing compilation error. I am getting 'request cannot be resolve' error. In my test class i am extending StrutsTestCase which has request as protected parameter. But it is not available inside extended method.
My test action looks like this:
import org.apache.struts2.StrutsTestCase;
public class WallPlanningActionTest extends StrutsTestCase {
public void testList() {
request.setParameter("salesOrg",1);
}
You can only get compilation errors if StrutsTestCase which your class is extended is not org.apache.struts2.StrutsTestCase. You could optimize the imports or just use FQCN.
public class WallPlanningActionTest extends org.apache.struts2.StrutsTestCase {
For future readers:
I had the same problem - the protected request field was not accessible. The problem was that i hadn't add the spring libraries. StrutsTestCase uses spring-core-x.y.z and spring-test-x.y.z. It is depended on them an i couldn't find a way to use the unit tests without them.
Other dependencies could be found by opening the struts-junit-plugin jar (as archive). Open the META-INF folder and in there you will find DEPENDENCIES file with a list of all dependencies.
Hope this helps someone.
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 {
}
I've got the following test:
#Test(expected = IllegalStateException.class)
public void testKey() {
int key = 1;
this.finder(key);
}
But JUnit reports, that the test fails, although it throws — as expected — an IllegalStateException.
Do I have to configure something else to make this run?
I run the test now with
#RunWith(Suite.class)
#SuiteClasses(Test.class)
public class TestSuite {
}
like in this question, but am still not getting the desired result.
And when I remove the test prefix I'm still getting an error.
I gotta say that I run these tests with Eclipse, but it's configured to use the JUnit 4 Runner.
The problem was, that the class in which the test was nested was an extension of TestCase. Since this is JUnit 3 style, the annotation didn't work.
Now my test class is a class on its own.
#RunWith(JUnit4.class)
public class MyTestCaseBase extends TestCase
I also had problems with #Test(expected = ...) annotation when I extended TestCase class in my base test. Using #RunWith(JUnit4.class) helped instantly (not an extremely elegant solution, I admit)
i tried this one, and work perfectly as expected.
public class SampleClassTest {
#Test(expected = ArithmeticException.class )
public void lost(){
this.lost(0);
}
private void lost(int i) throws ArithmeticException {
System.out.println(3/i);
}
}
also ensure that junit4 is added as dependancy, # (annotations) are new feature in junit 4.
I faced same issue, solution is simple "Don't extends TestCase class"
No, this JUnit test should work as it is - there is nothing more needed on this side.
What makes you sure that the test throws an IllegalStateException? Is it possible that it gets wrapped into another exception of different type?
Please post the exact failure message from JUnit.
As #duffymo suggested, it is easy to verify what (if any) exception the test really throws.
I had the same problem I just changed my imports statements.
I removed :
import org.junit.jupiter.api.Test;
import junit.framework.TestCase;
and added :
import org.junit.Test;
And it worked fine for me.
This looks correct to me.
Check your assumptions. Are you sure it throws the exception? If what you say is true, removing the expected from the annotation should make it fail.
I'd be stepping through the code with a debugger to see what's going on. I'll assume you have an IDE that will do so, like IntelliJ.
Just tested this under JUnit4: this DO work, test completes successfully. Look if it is a IllegalSelectorException or such.
When running all my tests in Eclipse (Eclipse 3.4 'Ganymede'), one test is listed under "Unrooted Tests". I'm using Junit 3.8 and this particular test extends TestCase. I do not see any difference between this test and the other tests. I don't remember seeing this occur in Eclipse 3.3 (Europa).
Clarification:
We haven't moved to JUnit 4.0 yet, so we are not using annotations. I also googled and it seemed like most people were having issues with JUnit 4, but I did not see any solutions. At this point the test passes both locally and in CruiseControl so I'm not overly concerned, but curious.
When I first saw this, though, it was on a failing test that only failed when run with other tests. This led me down the rabbit hole looking for a solution to the "Unrooted" issue that I never found. Eventually I found the culprit in another test that was not properly tearing down.
I agree, it does seem like an Eclipse issue.
Finally I found the solution. The problem is that you are not defining your test cases using annotations but are still doing it the "old way". As soon as you convert over to using annotations you will be able to run one test at a time again.
Here is an example of what a basic test should now look like using annotations:
import static org.junit.Assert.*; // Notice the use of "static" here
import org.junit.Before;
import org.junit.Test;
public class MyTests { // Notice we don't extent TestCases anymore
#Before
public void setUp() { // Note: It is not required to call this setUp()
// ...
}
#Test
public void doSomeTest() { // Note: method need not be called "testXXX"
// ...
assertTrue(1 == 1);
}
}
I was getting the "unrooted tests" error message as well and it went away magically. I believe it was due to the fact that I was using Eclipse with a Maven project. When I added a new method to my Test class and gave it the #Test annotation, it began getting the error message when I tried to run that one method using the "Run as Junit test" menu option; however, once I ran a maven build the unrooted tests message disappeared and I believe that is the solution to the problem in the future.
Run a maven build because it will refresh the class that JUnit is using.
If your class extends TestCase somewhere in its hierarchy, you have to use the JUnit 3 test runner listed in the drop down under run configurations. Using the JUnit 4 runner (the default I believe) causes that unrooted test phenomenon to occur.
I got this error because I renamed my test method and then tried to run the test in Eclipse by clicking on the same run configuration - referring to the old method which now didn't exist.
We solved the problem by making sure our test project was built. We had an issue in the build path which would not allow our test class to be compiled. Once we resolved the build path issue, the test compiled and the "new" method was able to be run. So we can assume that "Unrooted" tests also mean that they don't exist in the compiled binary.
I've never seen this -- but as far as I can tell from skimming Google for a few minutes, this appears as though it could be a bug in Eclipse rather than a problem with your test. You don't have the #Test annotation on the test, I assume? Can you blow the test away and recreate it, and if so do you get the same error?
Another scenario that causes this problem was me blindly copy/pasting a method that requires a parameter. i.e.
import org.junit.Test;
public class MyTest {
#Test
public void someMethod(String param) {
// stuff
}
}
You have a few simple solutions:
define the variable in the specific test method
add it as an instance variable to the test class
create a setup method and annotate it with #Before
For me, it was due to the project got build path issues. My maven dependencies configuration needs to be updated.
I had that problem and putting one "#Test" before the test method solved it!
like this:
#Test
public void testOne() { // ...
assertTrue(1 == 1);
}
These are the two scenarios that the Unrooted errors show up.
If you have missed the annotation #Test before the test.
#Test
public void foo(){
}
If it is a Gwt project and when two mock of the same object are defined. Lets say there is one class Class A and
#GwtMock
private A atest;
#GwtMock
private A a;
Then this will also show a Unrooted test error.
One other thing you can try is to upgrade your version of JUnit to at least 4.12.
I was experiencing this problem for a while with a class that extended one that used #RunWith(Parameterized.class).
After a while, and I'm sorry that I don't know precisely what I did to cause this, the 'Unrooted Tests' message went away, but the test still didn't run correctly. The constructor that should have accepted arguments from the #Parameters method was never getting called; execution jumped straight from #BeforeClass to #AfterClass.
The fix for that problem was to upgrade JUnit from the 4.8.1 it was using, to the latest (4.12). So maybe that could help someone else in the future.
I had the same problem with
java.lang.NoClassDefFoundError: org/hamcrest/SelfDescribing
you need the jar hamcrest.
same question 14539072: java.lang.NoClassDefFoundError: org/hamcrest/SelfDescribing
I could the fix the issue by shifting from TestRunner ver 4.0 to 3 in run configurations for the individual test method.
Do not extend junit.framework.TestCase in your test class with junit1.4 and this should solve the problem
You are using Hamcrest? or another library to help in your test?. You are not using
import static org.junit.Assert.*;
Check if in your test you use:
import static org.hamcrest.MatcherAssert.assertThat;
or other assert isn´t JUnit assert.
It turned out to be that my build path had some error...some jars were missing.
I reconfigured build path and it worked!
For me the problem was, that an exception was thrown in the #BeforeClass or #AfterClass methods. This will also cause tests to be categorized as unrooted.
I got this error with the test method name as "test"
#Test
public void test() {
// ... assertTrue(1 == 1);
}
I renamed the method and it worked
I ran into this problem by not also declaring the test to be static.
Maybe it's just a logical confusion about the goal of the method. Let's remember:
E.g. correct tagged test method:
#Test
#Transactional
#Rollback(true)
public void testInsertCustomer() {
(...)
}
-With Eclipse Junit plugin, You can run that test method using context menu over the method (E.g. at package explorer expanding the class and methods and selecting "testInsertCustomer()" method and from that item selecting "Run as >> JUnit test").
If you forgot "#Test" tag, or simply the method is not a test, but a (private or not) common method for using as utility for the other tests (e.g. "private fillCustomerObject()"), then the method does not require "#Test" tag, and simply you can not run it as a JUnit test!
It's easy that you could create a utility method and later you forgot the real goal of that method, so if you try to run it as a test, JUnit will shout "Unrooted Tests".
For me this problem was created by a real-time exception thrown in the #AfterClass method (take a look here for documentation):
Basically all the test methods succeeded but at the end of the class this method was failing. Therefore all the tests seems fine but there was on my Eclipse an additional "unrooted test" failed.
I got these errors for a maven project. I rebuild the project with mvn clean install.And the issue was solved
It actually told me there is a test with annotation: #RunWith(MockitoJUnitRunner.class)