I am trying to run the JUnit on my Linux command prompt /opt/junit/
contains the necessary JARS(hamcrest-core-1.3.jar and junit.jar) and class files and I am using the following command to run the JUnit:
java -cp hamcrest-core-1.3.jar:junit.jar:. org.junit.runner.JUnitCore TestRunner
TestJunit class:
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class TestJunit {
@Test
public void testAdd() {
String str= "Junit is working fine";
assertEquals("Junit is working fine",str);
}
}
TestRunner:
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
public class TestRunner {
public static void main(String[] args) {
Result result = JUnitCore.runClasses(TestJunit.class);
for (Failure failure : result.getFailures()) {
System.out.println("fail ho gaya"+failure.toString());
}
System.out.println("passed:"+result.wasSuccessful());
}
}
I am getting the following exception on running this
JUnit version 4.11
.E
Time: 0.003
There was 1 failure:
1) initializationError(TestRunner)
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)
at org.junit.runners.ParentRunner.<init>(ParentRunner.java:76)
at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:57)
at org.junit.internal.builders.JUnit4Builder.runnerForClass(JUnit4Builder.java:10)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
at org.junit.runner.Computer.getRunner(Computer.java:40)
at org.junit.runner.Computer$1.runnerForClass(Computer.java:31)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.runners.model.RunnerBuilder.runners(RunnerBuilder.java:101)
at org.junit.runners.model.RunnerBuilder.runners(RunnerBuilder.java:87)
at org.junit.runners.Suite.<init>(Suite.java:80)
at org.junit.runner.Computer.getSuite(Computer.java:28)
at org.junit.runner.Request.classes(Request.java:75)
at org.junit.runner.JUnitCore.run(JUnitCore.java:117)
at org.junit.runner.JUnitCore.runMain(JUnitCore.java:96)
at org.junit.runner.JUnitCore.runMainAndExit(JUnitCore.java:47)
at org.junit.runner.JUnitCore.main(JUnitCore.java:40)
FAILURES!!!
Tests run: 1, Failures: 1
You will get this exception, if you use the JUnit 4.4 core runner to execute a class that has no "@Test" method
.
Kindly consult the link for more info.
courtesy vipin8169
This solution will apply to a very small percentage of people, typically people implementing their own JUnit test runners and using a separate ClassLoader.
This can happen when you load a class from a different ClassLoader, then attempt to run that test from an instance of JUnitCore loaded from the system class loader. Example:
// Load class
URLClassLoader cl = new URLClassLoader(myTestUrls, null);
Class<?>[] testCls = cl.loadClass("com.gubby.MyTest");
// Run test
JUnitCore junit = new JUnitCore();
junit.run(testCls); // Throws java.lang.Exception: No runnable methods
Looking at the stack trace:
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)
at org.junit.runners.ParentRunner.<init>(ParentRunner.java:76)
at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:57)
at org.junit.internal.builders.JUnit4Builder.runnerForClass(JUnit4Builder.java:10)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:26)
at org.junit.runner.JUnitCore.run(JUnitCore.java:138)
The problem actually occurs at BlockJUnit4ClassRunner:169 (assuming JUnit 4.11):
https://github.com/junit-team/junit/blob/r4.11/src/main/java/org/junit/runners/BlockJUnit4ClassRunner.java#L95
Where it checks which methods are annotated with @Test
:
protected List<FrameworkMethod> computeTestMethods() {
return getTestClass().getAnnotatedMethods(Test.class);
}
In this case, Test.class
will have been loaded with the system ClassLoader (i.e. the one that loaded JUnitCore), therefore technically none of your test methods will have been annotated with that annotation.
Solution is to load JUnitCore in the same ClassLoader as the tests themselves.
Edit: In answer to the question from user3486675, you need to create a ClassLoader that doesn't delegate to the system class loader, e.g.:
private static final class IsolatedURLClassLoader extends URLClassLoader {
private IsolatedURLClassLoader(URL[] urls) {
// Prevent delegation to the system class loader.
super(urls, null);
}
}
Pass this a set of URLs that includes everything you need. You can create this by filtering the system classpath. Note that you cannot simply delegate to the parent ClassLoader, because those classes would then get loaded by that rather than the ClassLoader of your test classes.
Then you need to kick off the whole JUnit job from a class loaded by this ClassLoader. It gets messy here. Something like this utter filth below:
public static final class ClassLoaderIsolatedTestRunner {
public ClassLoaderIsolatedTestRunner() {
// Disallow construction at all from wrong ClassLoader
ensureLoadedInIsolatedClassLoader(this);
}
// Do not rename.
public void run_invokedReflectively(List<String> testClasses) throws BuildException {
// Make sure we are not accidentally working in the system CL
ensureLoadedInIsolatedClassLoader(this);
// Load classes
Class<?>[] classes = new Class<?>[testClasses.size()];
for (int i=0; i<testClasses.size(); i++) {
String test = testClasses.get(i);
try {
classes[i] = Class.forName(test);
} catch (ClassNotFoundException e) {
String msg = "Unable to find class file for test ["+test+"]. Make sure all " +
"tests sources are either included in this test target via a 'src' " +
"declaration.";
throw new BuildException(msg, e);
}
}
// Run
JUnitCore junit = new JUnitCore();
ensureLoadedInIsolatedClassLoader(junit);
junit.addListener(...);
junit.run(classes);
}
private static void ensureLoadedInIsolatedClassLoader(Object o) {
String objectClassLoader = o.getClass().getClassLoader().getClass().getName();
// NB: Can't do instanceof here because they are not instances of each other.
if (!objectClassLoader.equals(IsolatedURLClassLoader.class.getName())) {
throw new IllegalStateException(String.format(
"Instance of %s not loaded by a IsolatedURLClassLoader (loaded by %s)",
cls, objectClassLoader));
}
}
}
THEN, you need to invoke the runner via reflection:
Class<?> runnerClass = isolatedClassLoader.loadClass(ClassLoaderIsolatedTestRunner.class.getName());
// Invoke via reflection (List.class is OK because it just uses the string form of it)
Object runner = runnerClass.newInstance();
Method method = runner.getClass().getMethod("run_invokedReflectively", List.class);
method.invoke(...);
In my case I had wrong package imported:
import org.testng.annotations.Test;
instead of
import org.junit.Test;
Beware of your ide autocomplete.
I got this error because I didn't create my own test suite correctly:
Here is how I did it correctly:
Put this in Foobar.java
:
public class Foobar{
public int getfifteen(){
return 15;
}
}
Put this in FoobarTest.java
:
import static org.junit.Assert.*;
import junit.framework.JUnit4TestAdapter;
import org.junit.Test;
public class FoobarTest {
@Test
public void mytest() {
Foobar f = new Foobar();
assert(15==f.getfifteen());
}
public static junit.framework.Test suite(){
return new JUnit4TestAdapter(FoobarTest.class);
}
}
Download junit4-4.8.2.jar
I used the one from here:
http://www.java2s.com/Code/Jar/j/Downloadjunit4jar.htm
Compile it:
javac -cp .:./libs/junit4-4.8.2.jar Foobar.java FoobarTest.java
Run it:
el@failbox /home/el $ java -cp .:./libs/* org.junit.runner.JUnitCore FoobarTest
JUnit version 4.8.2
.
Time: 0.009
OK (1 test)
One test passed.
In Eclipse, I had to use New > Other > JUnit > Junit Test
. A Java class created with the exact same text gave me the error, perhaps because it was using JUnit 3.x.
The simplest solution is to add @Test annotated method to class where initialisation exception is present.
In our project we have main class with initial settings. I've added @Test method and exception has disappeared.