Search code examples
javajavafxtestfx

How to use TestFX to test a scene's contents using JavaFXML


I'm wondering how I'm supposed to be testing contents of certain scenes in JavaFXML when using TestFX. Examples include these links: https://github.com/TestFX/TestFX/blob/master/subprojects/testfx-junit5/src/test/java/org/testfx/framework/junit5/ApplicationRuleTest.java

https://medium.com/@mglover/java-fx-testing-with-testfx-c3858b571320

The first link constructs the scene within the test class, and the latter uses a pre-defined scene stored in its own class. How am I supposed to do something similar to this when using JavaFXML instead of JavaFX where the scenes' structures are defined in an fxml file instead of java code?


Solution

  • First step is giving your components fx:id-s in your fxml files, and then something like:

    public class ChangeProfilesMenuControllerTest extends ApplicationTest {
        Pane mainroot;
        Stage mainstage;
    
        @Override
        public void start(Stage stage) throws IOException {
          mainroot = (Pane) FXMLLoader.load(Main.class.getResource("ChangeProfilesMenU.fxml"));
          mainstage = stage;
          stage.setScene(new Scene(mainroot));
          stage.show();
          stage.toFront();
    
       }
    
        @Before
        public void setUp() throws Exception{
    
        }
    
       @After
       public void tearDown () throws Exception {
         FxToolkit.hideStage();
         release(new KeyCode[]{});
         release(new MouseButton[]{});
       }
    
       @Test
       public void addingAndDeletingProfiles() {
          @SuppressWarnings("unchecked")
          ListView<String> listview = (ListView<String>) mainroot.lookup("#listview");
          clickOn("#textfield");
          write("This is a test");
          clickOn("#createnewprofile");
          ...
      }
    

    If you want to acces your controller class instance:

        @Override
        public void start(Stage stage) throws IOException {
            this.mainstage = stage;
            FXMLLoader loader = new FXMLLoader(getClass().getResource("GameOn2.fxml"));
            this.mainroot = loader.load();
            this.controller = loader.getController();
            stage.setScene(new Scene(mainroot));
            stage.show();
            stage.toFront();
        }