JavaFX + maven + TestFX +单片机不能一起工作

我在maven下有一个用于恶魔JavaFX + TestFX的小项目。 我用:

  1. Java(TM)SE运行时环境(版本1.8.0_40-b26)
  2. Apache Maven 3.2.5(12a6b3acb947671f09b81f49094c53f426d8cea1; 2014-12-14T21:29:23 + 04:00)

完整来源: https : //github.com/alevohin/testfx-maven-example

我有两个我无法解决的问题:

1)当我从IDE(IDEA)启动AppFXTest时,测试失败

java.lang.ClassNotFoundException: com.sun.glass.ui.monocle.MonoclePlatformFactory at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:264) at com.sun.glass.ui.PlatformFactory.getPlatformFactory(PlatformFactory.java:42) at com.sun.glass.ui.Application.run(Application.java:146) at com.sun.javafx.tk.quantum.QuantumToolkit.startup(QuantumToolkit.java:263) at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:211) at com.sun.javafx.application.LauncherImpl.startToolkit(LauncherImpl.java:675) at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:695) at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$152(LauncherImpl.java:182) at com.sun.javafx.application.LauncherImpl$$Lambda$4/367732825.run(Unknown Source) at java.lang.Thread.run(Thread.java:745) Failed to load Glass factory class 

如果我禁用Monocle,它可以工作。 但我看到真正的JavaFX窗口和真正的光标点击按钮(“非无头”模式)

2)当我尝试通过maven执行测试(evecute mvn clean test )时,我得到了另一个错误

 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.18.1:test (default-test) on project testfx-maven-example: Execution default-test of goal org.apache.maven.plugins:maven-surefire-plugin:2.18.1:test failed: java.lang.NoClassDefFoundError: javafx/stage/Stage: javafx.stage.Stage -> [Help 1] org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.18.1:test (default-test) on project testfx-maven-example: Execution default-test of goal org.apache.maven.plugins:maven-surefire-plugin:2.18.1:test failed: java.lang.NoClassDefFoundError: javafx/stage/Stage at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:224) at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153) at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145) at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116) at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80) at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51) at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:120) at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:355) at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:155) at org.apache.maven.cli.MavenCli.execute(MavenCli.java:584) at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:216) at org.apache.maven.cli.MavenCli.main(MavenCli.java:160) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289) at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229) at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415) at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356) at org.codehaus.classworlds.Launcher.main(Launcher.java:47) ... Caused by: java.lang.ClassNotFoundException: javafx.stage.Stage at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) at org.apache.maven.surefire.booter.IsolatedClassLoader.loadClass(IsolatedClassLoader.java:97) ... 48 more 

我的pom.xml看起来像

   4.0.0 com.alevohin testfx-maven-example 1.0-SNAPSHOT https://github.com/alevohin/javafx-maven-example   org.hamcrest hamcrest-all 1.3 test   junit junit 4.10 test   org.mockito mockito-all 1.9.0 test   org.testfx testfx-core 4.0.1-alpha test   org.testfx testfx-junit 4.0.1-alpha test   org.jfxtras openjfx-monocle 1.8.0_20 test      maven-compiler-plugin  1.7 1.7    org.apache.maven.plugins maven-surefire-plugin 2.18.1  1 false 1  Monocle Headless sw       

AppFXTest

 public final class AppFXTest extends ApplicationTest { @Override public void start(final Stage stage) throws Exception { new AppFX().start(stage); } @Test public void showsButtons() throws Exception { MatcherAssert.assertThat( lookup(".button").queryAll().size(), Matchers.is(2) ); } @Test public void showsBottom() throws Exception { final Label label = lookup("BOTTOM").queryFirst(); MatcherAssert.assertThat( label.isVisible(), Matchers.is(true) ); } @Test public void clicksButtons() throws Exception { clickOn("A").clickOn("B"); } } 

应用

 public final class AppFX extends Application { /** * Program entry point. * @param args Program arguments. */ public static void main(final String... args) { Application.launch(AppFX.class, args); } @Override public void start(final Stage stage) throws Exception { stage.setTitle("TEST"); final Scene scene = new Scene(this.centralPane()); scene.getStylesheets().add( AppFX.class.getResource("App.css").toExternalForm() ); stage.setScene(scene); stage.setMinWidth(800.0D); stage.setMinHeight(600.0D); stage.show(); } private Pane centralPane() { final BorderPane border = new BorderPane(); border.setTop(this.buttonsPane()); border.setCenter(this.centerPane()); border.setBottom(this.bottomPane()); return border; } private Pane buttonsPane() { final HBox controls = new HBox(); controls.setSpacing(5.0D); controls.setAlignment(Pos.BASELINE_CENTER); controls.getChildren().add(new Label("BUTTONS")); controls.getChildren().add(new Button("A")); controls.getChildren().add(new Button("B")); return controls; } private Pane centerPane() { final VBox pane = new VBox(); pane.setAlignment(Pos.CENTER); pane.getChildren().add(new Label("CENTER")); pane.setMinSize(600.0D, 400.0D); return pane; } private Pane bottomPane() { final VBox bottom = new VBox(); final HBox status = new HBox(); status.setAlignment(Pos.BASELINE_RIGHT); bottom.getChildren().add(status); status.getChildren().add(new Label("BOTTOM")); return bottom; } } 

更新

问题

 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.18.1:test (default-test) on project testfx-maven-example: Execution default-test of goal org.apache.maven.plugins:maven-surefire-plugin:2.18.1:test failed: java.lang.NoClassDefFoundError: javafx/stage/Stage: javafx.stage.Stage -> [Help 1] 

通过像这样添加到pom.xml additionalClasspathElements来解决

   org.apache.maven.plugins maven-surefire-plugin 2.18.1  ...  ${java.home}/lib/ext/jfxrt.jar    

Failed to load Glass factory class

我曾经也有过这个错误,在我的情况下,我手动构建Monocle .jar并将其复制到JVM(jre / lib / ext)。

根据https://github.com/TestFX/Monocle上的文档构建Monocle,或者从OpenJDK存储库构建它。

所以以下对我有用:

  • 将您构建的Monocle .jar复制到JDK的jre / lib / ext。
  • 使用以下JVM参数运行应用程序:
 -Dtestfx.robot=glass -Dglass.platform=Monocle -Dmonocle.platform=Headless -Dprism.order=sw 

-Dtestfx.robot=glass是必要的,因为TestFX否则使用AWTRobot,它使用系统事件队列移动鼠标。 也许这足以使您的测试正常工作。

看看你的pom.xml ,junit带来了它自己的hamcrest-core版本,所以你应该排除它以避免问题(如果你想导入几个hamcrest匹配器)。 我以前使用两者都有错误。

对于进一步的研究,@ ItachiUchiha提供的链接以及https://zentrieredich.wordpress.com/2014/12/23/javafx-testen-mit-monocle/上的post帮助我使用Monocle与TestFX合作。

我建议使用TestFX 3.x,因为4.x仍然是alpha版本。

关于如何测试应用程序和TestFX的工作的一个非常好的博客在下面给出:

TestFX内部解释

对于单片眼镜使用,您可以遵循:

使用TestFX和JavaFX 8进行无头UI测试