JUnit: initializationError : No runnable methods - java

I wrote a eclipse plugin that as part of its job, it reads all test cases of the current active projects and run them. The problem is when it wants to run test cases I get the error initializationError : No runnable methods.
Extra information that may help:
Unit test code is running JUnit4.11. All test cases are annotated with #Test. Test are all public and not static. And tests are working correctly when I run them directly. Therefore, there is no problem with tests, and it is probably because of below code that I am using to load test class and then run that.
The code that I used to load class and then run test cases: (Suppose the active project open in eclipse is ExampleProject).
//Load class contains test cases
File root = new File("c:\ExampleProject\bin")
classLoader = URLClassLoader.newInstance(new URL[] {root.toURI().toURL()});
cls = Class.forName(testClassName, true, classLoader);
//Above lines work and I have test class determined with testClassName
//create a request
Request request = Request.aClass(cls);
//run the request
Result result = new JUnitCore().run(request);
for (Failure failure : result.getFailures()) {
System.out.println(failure.toString());
}
It prints initializationError(testClassName): No runnable methods.
Please let me know if any one knows what is the problem and how can I fix that.
PS: Note that when I run a test case from my plugin (C:\myplugin\bin), then above code works fine and it runs the test case exist in plugin, but when I want to run a test from current project then get the above run time error. Probably, some tings is wrong about classPath?

Related

JUnit - Run specific tests using JUnitCore

I have a couple of classes which contain Tests.
I have a main method that uses JUnitCore in order to run all tests.
What can I do in order to run specific tests in each class?
Currently I use something like this to run all my tests :
Result result = JUnitCore.runClasses(TestJunit.class, TestJunit2.class);
Maybe there is a possibility to categorize the relevant tests and then run them using JUnitCore ?? Thanks !
You can build a org.junit.runner.Request by providing class and method name and pass it to run method of JUnitCoreclass. This will execute given test of the specified class.
Request request = Request.method(TestClass.class, "methodName");
Result result = new JUnitCore().run(request);
You can check the result of test by invoking wasSuccessful() method available in Result class .

Failures are not collected in dynamic created test suite

I have a jar file that I reflect from it test classes (junit test).
I created TestSuite instance and added the tests to it.
In order to check my code, I've tried to add only one example test class to the test suite.
TestSuite suite = new TestSuite();
suite.addTest(new JUnit4TestAdapter(ExampleTest.class));
Then I called suite.run() in order to run the test:
TestResult result = new TestResult();
suite.run(result);
The problem is that when the test is done, the failures list that should be in result is empty.
Enumeration<TestFailure> failures = result.failures(); // = empty list
How can I get the failures using testSuite? If I use JUnitCore.runclasses , I do get the failures list but it can't be used with an instance of TestSuite, which I have to use since I get the test classes as input.
Edit-1:
If it is possible to create a Class that extends TestSuite and add classes to the suite dynamically, it will be good for my needs to.
Any suggestion will be great.
Edit-2:
From more searching in the web, I saw there us a difference between a failure and a testFailure. How can I fail a test with testFailure and not a failure?
After some more debugging, I found out that the TestResult object did catch the failures but reported them as Errors (Assertion Errors).
I also found out that TestResult.errors() returned an enumerator of TestFailure. Each TestFailure contain information about the thrown exception, so I can distinguish now between errors and failures by checking which of the errors are Assertion Errors and which are not.

How to run also ignored tests in JUnit 4 from command line?

I would like to run some ignored tests from a java program's main method in JUnit 4. They are ignored because they only insert some data for demonstration purpose.
in my main method:
JUnitCore junit = new JUnitCore();
junit.run(MyClass.class);
However this will not run test classes annotated with #Ignored
#Ignore("Only for filling system with demo data")
public class MyClass { ... }
In IntelliJ I can run those by right clicking on the class. How can I run them from the command line / in a main method?
I saw the Runner IgnoredClassRunner but not sure how to use that and if that is the correct Runner/Class.
It turned out this is quite easy achievable with:
JUnitCore junit = new JUnitCore();
junit.run(new BlockJUnit4ClassRunner(MyClass.class));
I will leave this answer open if anybody comes up with something better, which just prevents IgnoredClassRunner to be invoked for classes annotated with #Ignored

Spock Unit test with a closure ends with error "No runnable methods"

I wrote a simple feature method with the following then block :
then:
1 * view.setAttachments({ it?.size == 3 })
But the gradle test fails with the error :
initializationError
java.lang.Exception: No runnable methods
at org.junit.runners.BlockJUnit4ClassRunner.validateInstanceMethods(BlockJUnit4ClassRunner.java:169)
at org.junit.runners.BlockJUnit4ClassRunner.collectInitializationErrors(BlockJUnit4ClassRunner.java:104)
at org.junit.runners.ParentRunner.validate(ParentRunner.java:355)
...
initializationError
java.lang.Exception: Test class should have exactly one public zero-argument constructor
at org.junit.runners.BlockJUnit4ClassRunner.validateZeroArgConstructor(BlockJUnit4ClassRunner.java:147)
at org.junit.runners.BlockJUnit4ClassRunner.validateConstructor(BlockJUnit4ClassRunner.java:124)
at org.junit.runners.BlockJUnit4ClassRunner.collectInitializationErrors(BlockJUnit4ClassRunner.java:103)
at org.junit.runners.ParentRunner.validate(ParentRunner.java:355)
at org.junit.runners.ParentRunner.<init>(ParentRunner.java:76)
...
I noticed that if I remove the closure, there is no more error
then:
1 * view.setAttachments(_) // everything works well without closure!
It seems Spock tries to run the closure like it was another test method... How to avoid that ?
I had a similar problem trying to write a spring-boot test.
Do not use #RunWith(SpringRunner.class) and try removing your junit runner if you're using another one.
For me my Spock Specification executed properly without specifying the SpringRunner.
I found that the issue in my case is that the test file/class ended with Test, rather than Spec. Changing that resolved the issue (e.g. SomeServiceTest -> SomeServiceSpec).
I had the same problem. For me worked moving the test file from "src" directory to "Test" directory.
Try adding the following property to your build.gradle
test {
systemProperty 'project.buildDir', project.buildDir
}

Junit test that creates other tests

Normally I would have one junit test that shows up in my integration server of choice as one test that passes or fails (in this case I use teamcity). What I need for this specific test is the ability to loop through a directory structure testing that our data files can all be parsed without throwing an exception.
Because we have 30,000+ files that that 1-5 seconds each to parse this test will be run in its own suite. The problem is that I need a way to have one piece of code run as one junit test per file so that if 12 files out of 30,000 files fail I can see which 12 failed not just that one failed, threw a runtimeexception and stopped the test.
I realize that this is not a true "unit" test way of doing things but this simulation is very important to make sure that our content providers are kept in check and do not check in invalid files.
Any suggestions?
I think what you want is parameterized tests. It's available if you're using JUnit4 (or TestNG). Since you mention JUnit, you'll want to look at the #RunWith(Parameterized.class)
and #Parameters annotations' documentation.
I'd write one test that read all the files, either in a loop or some other means, and collected all the failed files in a collection of some kind for reporting.
Maybe a better solution would be a TestNG test with a DataProvider to pass along the list of file paths to read. TestNG will create and run one test for each file path parameter passed in.
A Junit3 answer: Create a TestSuite, that creates the instances of the TestCases that you need, with each TestCase initialized according to your dynamic data. The suite will run as a whole within a single JVM instance, but the individual TestCases are independent of each other (setUp, tearDown get called, the error handling is correct, reporting gives what you asked for, etc).
The actual implementation can be a bit clumsy, because TestCase conflates the Name of the test with the METHOD to be run, but that can be worked around.
We normally just combine the suite with the dynamic testcases in the same class, and use the suite() method to get the TestSuite. Ant's JUnit task is smart enough to notice this, for example.
public class DynamicTest extends TestCase {
String filename ;
public DynamicTest ( String crntFile ) {
super("testMethod");
filename = crntFile ;
}
// This is gross, but necessary if you want to be able to
// distinguish which test failed - otherwise they all share
// the name DynamicTest.testMethod.
public String getName() {
return this.getClass().getName() + " : " + filename ;
}
// Here's the actual test
public void testMethod() {
File f = new File( filename ) ;
assertTrue( f.exists() ) ;
}
// Here's the magic
public static TestSuite suite() {
TestSuite s = new TestSuite() ;
for ( String crntFile : getListOfFiles() ) {
s.addTest( new DynamicTest(crntFile ) ) ;
}
return s ;
}
}
You can, of course, separate the TestSuite from the TestCase if you prefer. The TestCase doesn't hold up well stand alone, though, so you'll need to have some care with your naming conventions if your tests are being auto-detected.

Categories