【问题标题】:How does JUnit find the eclipse plug-in being tested?JUnit如何找到正在测试的eclipse插件?
【发布时间】:2015-04-23 16:02:06
【问题描述】:

我正在编写一个插件 (ClassRefactoringPlugin),用于检查 Eclipse 3.6.1 中的源代码。该插件包含一个 CallData 类,该类检查 Java 源文件并确定从使用 JDT 操作的方法中调用了哪些 Java 元素。我为这个类编写了一个 JUnit 4 测试,它也位于 ClassRefactoringPlugin 项目中。当我将它作为 JUnit 插件测试运行时,我得到了:

Java Model Exception: Java Model Status [ClassRefactoringPlugin does not exist]

我做错了什么?配置指定使用所有工作区和启用的目标插件启动,ClassRefactoringPlugin 位于我的 dropins 目录中。 (虽然生成的工作区不应该识别项目的插件版本吗?)

这是堆栈跟踪:

!MESSAGE CallData.calculateCalledMethods: Java Model Exception: Java Model Status [ClassRefactoringPlugin does not exist]
Java Model Exception: Java Model Status [ClassRefactoringPlugin does not exist]
        at org.eclipse.jdt.internal.core.JavaElement.newJavaModelException(JavaElement.java:502)
        at org.eclipse.jdt.internal.core.Openable.generateInfos(Openable.java:246)
        at org.eclipse.jdt.internal.core.Openable.openAncestors(Openable.java:504)
        at org.eclipse.jdt.internal.core.Openable.generateInfos(Openable.java:240)
        at org.eclipse.jdt.internal.core.Openable.openAncestors(Openable.java:504)
        at org.eclipse.jdt.internal.core.Openable.generateInfos(Openable.java:240)
        at org.eclipse.jdt.internal.core.Openable.openAncestors(Openable.java:504)
        at org.eclipse.jdt.internal.core.CompilationUnit.openAncestors(CompilationUnit.java:1170)
        at org.eclipse.jdt.internal.core.Openable.generateInfos(Openable.java:240)
        at org.eclipse.jdt.internal.core.SourceRefElement.generateInfos(SourceRefElement.java:107)
        at org.eclipse.jdt.internal.core.JavaElement.openWhenClosed(JavaElement.java:515)
        at org.eclipse.jdt.internal.core.JavaElement.getElementInfo(JavaElement.java:252)
        at org.eclipse.jdt.internal.core.JavaElement.getElementInfo(JavaElement.java:238)
        at org.eclipse.jdt.internal.core.JavaElement.getChildren(JavaElement.java:193)
        at org.eclipse.jdt.internal.core.JavaElement.getChildrenOfType(JavaElement.java:207)
        at org.eclipse.jdt.internal.core.SourceType.getMethods(SourceType.java:403)
        at nz.ac.vuw.ecs.kcassell.utils.EclipseSearchUtils.addDesiredMethods(EclipseSearchUtils.java:333)
        at nz.ac.vuw.ecs.kcassell.utils.EclipseSearchUtils.getMethods(EclipseSearchUtils.java:210)
        at nz.ac.vuw.ecs.kcassell.callgraph.CallData.collectMethodCallData(CallData.java:203)
        at nz.ac.vuw.ecs.kcassell.callgraph.CallData.calculateCalledMethods(CallData.java:176)
        at nz.ac.vuw.ecs.kcassell.callgraph.CallData.collectCallData(CallData.java:151)
        at nz.ac.vuw.ecs.kcassell.callgraph.CallDataTest.testCollectCallData(CallDataTest.java:67)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at junit.framework.TestCase.runTest(TestCase.java:168)
        at junit.framework.TestCase.runBare(TestCase.java:134)
        at junit.framework.TestResult$1.protect(TestResult.java:110)
        at junit.framework.TestResult.runProtected(TestResult.java:128)
        at junit.framework.TestResult.run(TestResult.java:113)
        at junit.framework.TestCase.run(TestCase.java:124)
        at junit.framework.TestSuite.runTest(TestSuite.java:232)
        at junit.framework.TestSuite.run(TestSuite.java:227)
        at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
        at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
        at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
        at org.eclipse.pde.internal.junit.runtime.RemotePluginTestRunner.main(RemotePluginTestRunner.java:62)
        at org.eclipse.pde.internal.junit.runtime.UITestApplication$1.run(UITestApplication.java:116)
        at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
        at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:134)
        at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3515)
        at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3164)
        at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2640)
        at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2604)
        at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2438)
        at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:671)
        at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
        at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:664)
        at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
        at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:115)
        at org.eclipse.pde.internal.junit.runtime.UITestApplication.start(UITestApplication.java:47)
        at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
        at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
        at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
        at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:369)
        at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:619)
        at org.eclipse.equinox.launcher.Main.basicRun(Main.java:574)
        at org.eclipse.equinox.launcher.Main.run(Main.java:1407)
        at org.eclipse.equinox.launcher.Main.main(Main.java:1383)

我想知道错误消息是否可能是红鲱鱼。调用时出现错误 IMethod[] methods = type.getMethods();

如果我在那里设置断点并在调试器的变量视图中查看type,我会看到:

CallDataTest (not open) [in CallDataTest.java [in nz.ac.vuw.ecs.kcassell.callgraph [in test [in ClassRefactoringPlugin]]]]

我想知道我是否省略了一些重要的初步步骤以使项目可供检查。首先,我尝试激活工作台,如下所示:

public static void activateWorkbench() {
    // possible for PlatformUI.getWorkbench to throw an IllegalStateException
    // if the workbench is not yet started e.g createAndRunWorkbench() has not yet been called
    IWorkbench workbench = PlatformUI.getWorkbench();
    IWorkbenchWindow workbenchWindow =
        workbench.getActiveWorkbenchWindow();
    workbenchWindow.getActivePage();
}

然后我尝试使用它的句柄获取类型:

protected IType iType = EclipseUtils.getTypeFromHandle(
        "=ClassRefactoringPlugin/test<nz.ac.vuw.ecs.kcassell.callgraph{CallDataTest.java[CallDataTest");

public static IType getTypeFromHandle(String handle) {
IType type = null;
IJavaElement element = JavaCore.create(handle);
if (element == null) {
    System.err.println("  No element created from " + handle);
} else if (element instanceof IType) {
    type = (IType) element;
}
    return type;
}

我是插件开发的新手,非常感谢任何帮助。

干杯, 基思

【问题讨论】:

  • 我确认您不需要将导出的插件放​​在 dropins 文件夹中,因为 Eclipse 在运行 JUnit Launch 配置时正在使用您正在编写的插件的项目版本。您能否粘贴完整的堆栈跟踪,因为我认为问题与 Junit 运行配置无关。如果您能够启动它,我猜测试类在主要的 Junit Run 配置选项卡中可用?
  • 我不完全确定您所说的“主 Junit 运行配置选项卡”是什么意思?在 Eclipse 中,如果我执行 Run->Run Configurations,我会得到一个“Run Configurations”窗口,其中将 CallDataTest 列为“JUnit Plug-in Test”。这是你想知道的吗?我正在编辑原始帖子以包含堆栈跟踪。
  • 我已经更新了主帖中的信息,以反映迁移到更新的 Eclipse 版本。
  • 你好 kc2001。对于与您的解决方案类似的问题,您提供了赏金并投票赞成我的回答。请将我的问题标记为已接受的答案。把这些分数浪费掉是一种耻辱。谢谢。

标签: junit eclipse-plugin eclipse-jdt


【解决方案1】:

我有点不确定您究竟想在这里做什么,但看起来您正在尝试为您的插件编写 JUnit 测试。是这样吗?

根据您正在创建的 java 元素句柄标识符,您的工作区中应该有一个名为 ClassRefactoringPlugin 的项目,其中有一个名为 test 的源文件夹,一个名为 CallDataTest 的 java 类位于名为nz.ac.vuw.ecs.kcassell.callgraph.

我猜测情况并非如此,您想在刚刚创建的插件中引用一个类文件。

在您执行上述任何操作之前,您需要将一个项目导入您的测试工作区,设置其类路径,然后您可以使用句柄标识符访问其内容。

我可能误解了您要执行的操作,但您似乎正在尝试访问工作区中不存在的 java 文件。如果您能确认这是您想要做的,我可以为您指出一些完全符合您要求的测试代码。


有一些开源项目正是这样做的,您可以借用它们的一些源代码来达到您的目的。我熟悉的一个项目是 Groovy-Eclipse http://groovy.codehaus.org/Eclipse+Plugin(因为我是那个项目的负责人)。

这是我们用来创建和管理测试项目的类的链接:

https://svn.codehaus.org/groovy/eclipse/trunk/ide-test/org.codehaus.groovy.eclipse.tests/src/org/codehaus/groovy/eclipse/test/TestProject.java

您可以将部分或全部代码用于您自己的测试。请记住在每次测试结束时删除所有项目。

【讨论】:

  • 我相信您提到的所有前提条件都设置正确。我不明白您对“测试工作区”的引用。我有一个包含我的 ClassRefactoringPlugin 的工作区,其中包含 src 和 test 文件夹。当我右键单击 CallDataTest 和“作为 JUnit 插件测试运行”时,会生成一个新的工作台。如果我在调试模式下这样做,我实际上可以使用调试器单步执行测试中的代码。这就是为什么我想知道错误消息是否可能具有误导性。顺便说一句,当我调试它时,我的插件代码在生成的工作区中运行良好,而不是在我尝试运行 JUnit 测试时。
  • 对。 JUnit 插件测试会生成一个新的工作区,但这个工作区最初是空的。您正在尝试访问存在于常规工作区中的项目(及其源代码),而不是您的运行时 JUnit 工作区。我假设当您启动运行时(不是 JUnit 运行时)工作区时,您在该工作区中有一个名为 CallDataTest 的项目。如果您想基于它创建一个IJavaElements,您需要将CallDataTest 导入您的JUnit 工作区。没有简单的 API 可以做到这一点,但是有很多开源项目需要做类似的事情。
  • 更新了我的答案以包含指向一些示例源代码的链接。
  • 我认为我的主要问题是未能在 junit-workspace 中设置项目。虽然我还没有让它工作,但我觉得你的帮助应该足以让我得到它。除非超级答案很快到来,否则您将获得赏金。干杯!
  • 这不是件容易的事。 :) 我们花了很长时间才把它弄好。因此,如果您有更多问题,请随时回来。
【解决方案2】:

由于不同的原因出现了类似的错误。重命名项目中的目标包后,我的错误开始了。在我尝试了 paskster 的解决方案但没有成功后,我开始挖掘。

实际的问题是,从清单文件重命名包名没有按预期工作。我认为它会改变所有地方的一切。但是,旧的包名仍在 test 目录的清单文件中,以及资源中的某些视图中。手动重命名并重建项目后,错误消失了。

这是另一个问题的公认答案: Java Model Exception: Java Model Status [gen [in MyApp] does not exist] after Eclipse Android project Clean

由于此问题的所有者将此答案作为带有此问题链接的解决方案投票赞成,因此我想我也将其发布在这里。

【讨论】:

  • 不幸的是,我最初阅读您的帖子的乐趣还为时过早。我使我能想到的每个名字都保持一致,但仍然有问题。但是,我没有注意到 MANIFEST 中有任何具体的“测试”信息。
猜你喜欢
  • 2010-10-31
  • 2013-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-21
  • 2020-04-11
  • 2011-03-01
相关资源
最近更新 更多