代码之家  ›  专栏  ›  技术社区  ›  kleopatra Aji kattacherry

简单TestFX示例失败

  •  3
  • kleopatra Aji kattacherry  · 技术社区  · 6 年前

    使用Eclipse photon中的testfx4.0.14和fx9或fx11(无所谓)时 simple example test should_click_on_button() 具有

    Expected: Labeled has text "clicked!"
             but: was "click me!"
    

    知道怎么了吗?

    测试代码(为了方便起见,全部从wiki复制):

    import org.junit.Test;
    import org.testfx.framework.junit.ApplicationTest;
    
    import static org.testfx.api.FxAssert.*;
    import static org.testfx.matcher.control.LabeledMatchers.*;
    
    import javafx.scene.Parent;
    import javafx.scene.Scene;
    import javafx.stage.Stage;
    
    /**
     * Simple testfx example from testfx wiki:
     * https://github.com/TestFX/TestFX/wiki/Getting-Started
     * 
     */
    public class ClickApplicationTest extends ApplicationTest {
        @Override
        public void start(Stage stage) {
            Parent sceneRoot = new ClickApplication.ClickPane();
            Scene scene = new Scene(sceneRoot, 100, 100);
            stage.setScene(scene);
            stage.show();
        }
    
        @Test
        public void should_contain_button() {
            // expect:
            verifyThat(".button", hasText("click me!"));
        }
    
        @Test
        public void should_click_on_button() {
            // when:
            clickOn(".button");
    
            // then:
            verifyThat(".button", hasText("clicked!"));
        }
    
    
    }
    

    import javafx.application.Application;
    import javafx.scene.Parent;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Stage;
    
    /**
     * Simple testfx example from testfx wiki:
     * https://github.com/TestFX/TestFX/wiki/Getting-Started
     * 
     */
    public class ClickApplication extends Application {
        // application for acceptance tests.
        @Override public void start(Stage stage) {
            Parent sceneRoot = new ClickPane();
            Scene scene = new Scene(sceneRoot, 100, 100);
            stage.setScene(scene);
            stage.show();
        }
    
        // scene object for unit tests
        public static class ClickPane extends StackPane {
            public ClickPane() {
                super();
                Button button = new Button("click me!");
                button.setOnAction(actionEvent -> button.setText("clicked!"));
                getChildren().add(button);
            }
        }
    }
    

    更新:

    TestFX 可能是匹配的。它提到了一个 core fx bug 这可能是原因-但似乎不是:它在fx11中是固定的(验证了核心bug报告中的代码通过了),但是testfx问题占了上风。。

    2 回复  |  直到 6 年前
        1
  •  3
  •   transgressoft    6 年前

    这对我很有用。

    无论如何,您可能会在UI更改发生之前检查它,因为它是在FX应用程序线程中完成的,而不是在执行测试的线程中完成的。

    用这条线

    WaitForAsyncUtils.waitForFxEvents()
    

    clickOn verifyThat 电话。

        2
  •  3
  •   kleopatra Aji kattacherry    6 年前

    原来是有几个原因的问题:

    • 最底层是一个 core bug -机器人在win(仅10?)HiDPI屏幕上不能正确移动,所以不是每个人都会经历失败
    • fx11(在本机win代码中)修复了核心bug,因此现在的公共fx Robot表现良好
    • 默认情况下,TestFX使用仍然失败的AWTRobot(至少在TestFX的上下文中,核心bug报告中的示例通过了)
    • 为了使TestFX测试在win-HiDPI屏幕上可靠运行,我们需要通过设置系统属性来强制使用fx robot 玻璃
    • 最后一个怪癖:通过编程设置属性时 System.getProperties().put("testfx.robot", "glass") 在测试代码中,必须在tests类启动之前执行此操作,即在@BeforeClass注释的方法中(不在@before或@BeforeClass中) testApp.init() )! 否则,直接或间接涉及mouseMove的第一个测试将失败,随后的测试就可以了(让我困惑了一段时间,因为失败是假的;)。

    public class ClickTest extends ApplicationTest {
    
        @Test
        public void testClick() {
            verifyThat(".button", hasText("click me!"));
            clickOn(".button");
            verifyThat(".button", hasText("clicked!"));
        }
    
        /**
         * Use glass robot.
         * Note: this must happen once before the class is loaded. Otherwise,
         * the very first test run uses the awt robot
         */
        @BeforeClass
        public static void config() throws Exception {
            System.getProperties().put("testfx.robot", "glass");
        }
    
        @Override
        public void start(Stage stage) {
            Parent sceneRoot = new ClickPane();
            Scene scene = new Scene(sceneRoot, 100, 100);
            stage.setScene(scene);
            stage.show();
        }
    
        // scene object for unit tests
        public static class ClickPane extends StackPane {
            public ClickPane() {
                super();
                Button button = new Button("click me!");
                button.setOnAction(actionEvent -> button.setText("clicked!"));
                getChildren().add(button);
            }
        }
    
        @SuppressWarnings("unused")
        private static final Logger LOG = Logger
                .getLogger(ClickTest.class.getName());
    }