Вопрос:

java.lang.Exception: нет исключений запускаемых методов при запуске JUnits

java junit ubuntu-12.04 junit4

72898 просмотра

7 ответа

1531 Репутация автора

Я пытаюсь запустить JUnit в командной строке Linux, которая /opt/junit/содержит необходимые файлы JARS (hamcrest-core-1.3.jar и junit.jar) и классы, и я использую следующую команду для запуска JUnit:

java -cp hamcrest-core-1.3.jar:junit.jar:. org.junit.runner.JUnitCore  TestRunner

Класс TestJunit:

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

Я получаю следующее исключение при запуске этого

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
Автор: vipin8169 Источник Размещён: 20.06.2014 03:57

Ответы (7)


82 плюса

2815 Репутация автора

Решение

Вы получите это исключение, если будете использовать ядро ядра JUnit 4.4 для выполнения класса, который не имеет "@Test" method. Пожалуйста, обратитесь к ссылке для получения дополнительной информации.

любезно предоставлено vipin8169

Автор: 4aRk Kn1gh7 Размещён: 20.06.2014 04:14

1 плюс

92885 Репутация автора

Я получил эту ошибку, потому что я не создал свой собственный набор тестов правильно:

Вот как я сделал это правильно:

Поместите это в Foobar.java:

public class Foobar{
    public int getfifteen(){
        return 15;
    }
}

Поместите это в 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);
    }
}

Скачать junit4-4.8.2.jarя использовал один из здесь:

http://www.java2s.com/Code/Jar/j/Downloadjunit4jar.htm

Скомпилируйте это:

javac -cp .:./libs/junit4-4.8.2.jar Foobar.java FoobarTest.java

Запустить его:

el@failbox /home/el $ java -cp .:./libs/* org.junit.runner.JUnitCore FoobarTest
JUnit version 4.8.2
.
Time: 0.009    
OK (1 test)

Один тест пройден.

Автор: Eric Leschinski Размещён: 18.09.2014 08:49

15 плюса

3765 Репутация автора

Это решение будет применяться к очень небольшому проценту людей, обычно к людям, которые внедряют свои собственные тестеры JUnit и используют отдельный ClassLoader.

Это может произойти, когда вы загружаете класс из другого ClassLoader, а затем пытаетесь запустить этот тест из экземпляра JUnitCore, загруженного из системного загрузчика классов. Пример:

// 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

Глядя на трассировку стека:

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)

Проблема действительно возникает в BlockJUnit4ClassRunner: 169 (при условии, что JUnit 4.11):

https://github.com/junit-team/junit/blob/r4.11/src/main/java/org/junit/runners/BlockJUnit4ClassRunner.java#L95

Где он проверяет, какие методы помечены @Test:

protected List<FrameworkMethod> computeTestMethods() {
    return getTestClass().getAnnotatedMethods(Test.class);
}

В этом случае Test.classбудет загружен системный ClassLoader (то есть тот, который загружал JUnitCore), поэтому технически ни один из ваших методов тестирования не будет аннотирован этой аннотацией.

Решение состоит в том, чтобы загрузить JUnitCore в тот же ClassLoader, что и сами тесты.


Изменить : В ответ на вопрос от пользователя user3486675, вам нужно создать ClassLoader, который не делегирует системный загрузчик классов, например:

private static final class IsolatedURLClassLoader extends URLClassLoader {
    private IsolatedURLClassLoader(URL[] urls) {
        // Prevent delegation to the system class loader.
        super(urls, null);
    }
}

Передайте этот набор URL-адресов, который включает в себя все, что вам нужно. Вы можете создать это, отфильтровав системный путь к классам. Обратите внимание, что вы не можете просто делегировать родительскому ClassLoader, потому что эти классы будут загружаться этим, а не ClassLoader ваших тестовых классов.

Затем вам нужно запустить всю работу JUnit из класса, загруженного этим ClassLoader. Здесь становится грязно. Что-то вроде этой полной грязи ниже:

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));
        }
    }
}

Затем вам нужно вызвать бегуна с помощью отражения:

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(...);
Автор: gubby Размещён: 25.04.2015 01:10

10 плюса

111 Репутация автора

В моем случае я импортировал неправильный пакет:

import org.testng.annotations.Test;

вместо

import org.junit.Test;

Остерегайтесь ваших идей автозаполнения.

Автор: awasik Размещён: 19.04.2016 12:31

0 плюса

2148 Репутация автора

В Eclipse мне пришлось пользоваться New > Other > JUnit > Junit Test. Класс Java, созданный с точно таким же текстом, дал мне ошибку, возможно, потому что он использовал JUnit 3.x.

Автор: Noumenon Размещён: 08.12.2016 02:42

0 плюса

754 Репутация автора

Самое простое решение - добавить аннотированный метод @Test в класс, где присутствует исключение инициализации.

В нашем проекте у нас есть основной класс с начальными настройками. Я добавил метод @Test, исключение исчезло.

Автор: Jackkobec Размещён: 15.12.2018 02:19

0 плюса

1 Репутация автора

Мой тестовый контроллер в большом ярлыке:

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

Я просто удалил "public" и волшебным образом это сработало.

Автор: Filip McKo Размещён: 13.06.2019 09:11
Вопросы из категории :
32x32