java.lang.Exception: No runnable methods exception in running JUnits

JavaJunitUbuntu 12.04Junit4

Java Problem Overview


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

Java Solutions


Solution 1 - Java

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

Solution 2 - Java

In my case I had wrong package imported:

import org.testng.annotations.Test;

instead of

import org.junit.Test;

Beware of your ide autocomplete.

Solution 3 - Java

My controller test in big shortcut:

@RunWith(SpringRunner.class)
@SpringBootTest
public class TaskControllerTest {
   //...
   //tests
   //
}

I just removed "public" and magically it worked.

Solution 4 - Java

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(...);

Solution 5 - Java

I had to change the import statement:

import org.junit.jupiter.api.Test;

to

import org.junit.Test;

Solution 6 - Java

I had the same problem now with testing code. That was caused in spring boot because of the @RunWith annotation. I have used:

@RunWith(SpringRunner.class)

With that annotation there is JUnit Vintage running which can't find any tests and gives you the error. I have removed that and only JUnit Jupiter is running and everything is fine.

Solution 7 - Java

In my case, I was using the wrong Test import. The correct one was import org.junit.Test;

Solution 8 - Java

If you are using import org.junit.jupiter.api.Test (Junit 5) and @RunWith(SpringRunner.class), SpringRunner is on Junit4, junit gets confused. Removing public before class name will work as Junit 5 complains about public test classes. From Docs: JUnit5 is more tolerant regarding the visibilities of Test classes than JUnit4, which required everything to be public. In this context, JUnit5 test classes can have any visibility but private, however, it is recommended to use the default package visibility, which improves readability of code.

Solution 9 - Java

For me, replacing import org.junit.jupiter.api.Test; with import org.junit.Test; helped.

Solution 10 - Java

in my case i just disabled //@RunWith(SpringRunner.class)

and there is no exception

Solution 11 - Java

I also faced this issue and failed to figure out the reason for the same for sometimes. Later i found that auto import issue using IDE. That is imports of the program.

Basically i was using eclipse IDE. And I was importing a wrong class "org.junit.jupiter.api.Test" into the program instead of required class "org.junit.Test". Hence check your imports before running any programs.

Solution 12 - Java

You can also get this if you mix org.junit and org.junit.jupiter annotations inadvertently.

Solution 13 - Java

I had similar issue/error while running JunitCore along side with Junit Jupiter(Junit5) JUnitCore.runClasses(classes); after removing @RunWith(SpringRunner.class) and
ran with @SpringBootTest @FixMethodOrder(MethodSorters.NAME_ASCENDING) i am able to resolve the issue for my tests as said in the above comments. https://stackoverflow.com/a/59563970/13542839

Solution 14 - Java

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.

Solution 15 - Java

If you're running test Suite via @RunWith(Suite.class) @Suite.SuiteClasses({}) check if all provided classes are really test classes ;).

In my case one of the classes was an actual implementation, not a test class. Just a silly typo.

Solution 16 - Java

if the class annotated with @RunWith(SpringRunner.class) But we class doesn't contain any test methods then we will face this issue. Solution: if we make to abstract we will not get this or if remove public then also we will not face this issue.

Solution 17 - Java

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.

Solution 18 - Java

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.

Solution 19 - Java

I was able to fix by manually adding the junit jar to my project classpath. The easiest way I found to do this was by adding a /lib directory in the project root. Then i just put the junit.jar inside /lib and junit tests starting working for me.

Solution 20 - Java

I faced the same with my parent test setUp class which has annotation @RunWith(SpringRunner.class) and was being extended by other testClasses. As there was not test in the setUpclass , and Junit was trying to find one due to annotation @RunWith(SpringRunner.class) ,it didn't find one and threw exception

No runnable methods exception in running JUnits

I made my parent class as abstract and it worked like a charm .

I took help from here https://stackoverflow.com/a/10699141/8029525 . Thanks for help @froh42.

Solution 21 - Java

the solution is simple if you importing

import org.junit.Test;

you have to run as junit 4

right click ->run as->Test config-> test runner-> as junit 4

Solution 22 - Java

For me I added JUnit4.12 and Hamcrest1.3 on the classpath and changed import org.testng.annotations.Test; or import org.testng.annotations.*; to import org.junit.Test;. It finally works fine!

Solution 23 - Java

A bit of heuristic/experience here, I am running a Spring Boot project, and I was getting JUnit Jupiter tests appearing alongside JUnit Vintage. The JUnit Vintage ones were failing, when I removed the public access modifier the Junit Vintage tests disappeared, as a result achieving the behaviour I wanted.

@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles(profiles = {"test"})
public class TestSuiteName {

||

@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles(profiles = {"test"})
class TestSuiteName {

https://stackoverflow.com/questions/38822189/why-were-junit-jupiter-and-junit-vintage-separated-when-i-running-testcase-in-in

Solution 24 - Java

If there is,take out of pom.xml

       <exclusions>
			<exclusion>
				<groupId>org.junit.vintage</groupId>
				<artifactId>junit-vintage-engine</artifactId>
			</exclusion>
		</exclusions>

Solution 25 - Java

I got the same error when I missed to add access modifier public to this test-case-method, after added it works. I used JUnit 4. For Junit 5, same test-case works without access specifier to test-case-method.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionVipin VermaView Question on Stackoverflow
Solution 1 - Java4aRk Kn1gh7View Answer on Stackoverflow
Solution 2 - JavaawasikView Answer on Stackoverflow
Solution 3 - JavaFilip McKoView Answer on Stackoverflow
Solution 4 - JavagubView Answer on Stackoverflow
Solution 5 - JavasimibacView Answer on Stackoverflow
Solution 6 - JavaRené HöhleView Answer on Stackoverflow
Solution 7 - JavaPrashant SView Answer on Stackoverflow
Solution 8 - JavapinaciView Answer on Stackoverflow
Solution 9 - JavaPijushView Answer on Stackoverflow
Solution 10 - JavaKashif BashirView Answer on Stackoverflow
Solution 11 - JavaDeepak GuptaView Answer on Stackoverflow
Solution 12 - JavaTaylorView Answer on Stackoverflow
Solution 13 - Javanaveen chanderView Answer on Stackoverflow
Solution 14 - JavaEric LeschinskiView Answer on Stackoverflow
Solution 15 - JavaMichaƂ StochmalView Answer on Stackoverflow
Solution 16 - JavaNaiduView Answer on Stackoverflow
Solution 17 - JavaNoumenonView Answer on Stackoverflow
Solution 18 - JavaJackkobecView Answer on Stackoverflow
Solution 19 - JavaLarry EView Answer on Stackoverflow
Solution 20 - JavaNupurView Answer on Stackoverflow
Solution 21 - JavaArun Kumar TView Answer on Stackoverflow
Solution 22 - JavaGhebrehiywetView Answer on Stackoverflow
Solution 23 - JavaKonstantin GrigorovView Answer on Stackoverflow
Solution 24 - JavaAndresa PratesView Answer on Stackoverflow
Solution 25 - JavaGowthamView Answer on Stackoverflow