JUnitCore 在 Eclipse 插件中给出 "No runnable methods" 错误

JUnitCore giving "No runnable methods" error in Eclipse plugin

我正在尝试编写一个 Eclipse 插件,它可以 运行 JUnit 测试并对结果进行一些处理。我的插件正确加载给定的 class,但无法 运行 JUnit 测试并给出错误:initializationError(className): No runnable methods。但是,当我在同一个 Eclipse 实例中使用 Result result = JUnitCore.runClasses(className.class); Failure failure : result.getFailures(); 运行 测试 class 时,我没有收到任何错误。

我认为我的问题是@gubby 在问题 java.lang.Exception: No runnable methods exception in running JUnits 中描述的问题,但我不知道如何将他的建议实施到一个解决方案中:"Solution is to load JUnitCore in the same ClassLoader as the tests themselves."

这是我的实现的简化版本(请假设除了加载 运行nable 方法之外的所有内容都有效):

ClassLoader classLoader = ClassLoaderHelper.getClassLoader(FileFinder.getCurrentProject());
Class clazz = classLoader.loadClass(fileName.substring(0, fileName.indexOf(".class")));
Result result = JUnitCore.runClasses(clazz);
Failure failure : result.getFailures()

获取ClassLoader的代码如下:

public static ClassLoader getClassLoader(IProject project) {
    String[] classPathEntries = null;
    try {
        project.open(null);
        IJavaProject javaProject = JavaCore.create(project);
        classPathEntries = JavaRuntime.computeDefaultRuntimeClassPath(javaProject);
    } catch (CoreException e1) {
        e1.printStackTrace();
    }

    List<URL> urlList = new ArrayList<URL>();
    for (String entry : classPathEntries) {
        IPath path = new Path(entry);
            URL url;
            try {
                url = path.toFile().toURI().toURL();
                urlList.add(url);
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }
    }
    ClassLoader parentClassLoader = project.getClass().getClassLoader();
    URL[] urls = (URL[]) urlList.toArray(new URL[urlList.size()]);
    URLClassLoader classLoader = new URLClassLoader(urls, parentClassLoader);

    return classLoader;
}

对于 Eclipse 插件,基本上有两个选项可以让一个插件与另一个插件共享一个 class 加载器。

  1. Buddy Class Loading。请注意,这打破了松耦合,但很容易 "implement" 因为您只需在两个相应的插件 MANIFEST.MF 中添加两个语句和一个 export 语句。以下规则适用(来自上面给出的link)。

    • 捆绑包Y必须指定注册好友策略(即Eclipse-BuddyPolicy:已注册)

    • 包 X 必须在 Eclipse-RegisterBuddy header 中指定 Y 的符号名称(即 Eclipse-RegisterBuddy: Y)

    • 包 X 必须依赖于包 Y 导出的包。这可以通过 Require-Bundle 或 Import-Package 约束来实现。

  2. Fragments: 你可以"attach"一个片段到一个插件。两者共享相同的 class 加载程序。通常,这种技术用于插件 i18n 之类的东西,但它也是向插件添加单元测试的推荐做法。这样,测试不必进入同一个插件,并且可能不需要的测试 classes 或依赖项不会进入生产代码。

    Eclipse 中有一个片段向导,但它们本身基本上是插件,声明了一个 "host plugin".

因此,您可以考虑将代码放入 片段 并将其附加到包含 code-under-test 的相应插件。或者,如果您需要为不同的插件重用您的代码并且不关心松散耦合,请使用 Buddy Class Loading.

此外,检查插件中是否具有所有正确的依赖项(例如,org.junit)。您需要包含在 Java 开发工具 .

中的 JUnit