JavaFX TestFX JUnit - Liste de noeuds

Maven pom.xml et configuration

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>fr.ronanlefichant</groupId>
	<artifactId>testjavafx</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<maven.compiler.source>11</maven.compiler.source>
		<maven.compiler.target>11</maven.compiler.target>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.openjfx</groupId>
			<artifactId>javafx-controls</artifactId>
			<version>17.0.0.1</version>
		</dependency>
		<dependency>
			<groupId>org.testfx</groupId>
			<artifactId>testfx-core</artifactId>
			<version>4.0.16-alpha</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.testfx</groupId>
			<artifactId>testfx-junit5</artifactId>
			<version>4.0.16-alpha</version>
			<scope>test</scope>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.8.0</version>
				<configuration>
					<release>11</release>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.openjfx</groupId>
				<artifactId>javafx-maven-plugin</artifactId>
				<version>0.0.6</version>
				<executions>
					<execution>
						<!-- Default configuration for running -->
						<!-- Usage: mvn clean javafx:run -->
						<id>default-cli</id>
						<configuration>
							<mainClass>fr.ronanlefichant.testjavafx.App</mainClass>
						</configuration>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</project>

Important

Pour Ă©viter l'erreur suivante :

java.lang.IllegalAccessError: class org.testfx.toolkit.impl.ToolkitServiceImpl cannot access class com.sun.javafx.application.ParametersImpl (in module javafx.graphics) because module javafx.graphics does not export com.sun.javafx.application to unnamed module

Arguments VM :

--add-exports javafx.graphics/com.sun.javafx.application=ALL-UNNAMED

L'application JavaFX

package fr.ronanlefichant.testjavafx;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

/**
 * JavaFX App
 */
public class App extends Application {

  @Override
  public void start(Stage stage) {

    // Élément racine
    VBox root = new VBox();

    VBox listVBox = new VBox();
    listVBox.setId("list-vbox");

    // Élément contenant champ texte et le bouton
    HBox formHbox = new HBox();

    // Le champ texte
    TextField wordTextField = new TextField();
    wordTextField.setId("word-textfield");

    // Le bouton
    Button addButton = new Button("Ajouter");
    addButton.setId("add-btn");

    // Ajoute les composants
    formHbox.getChildren().add(wordTextField);
    formHbox.getChildren().add(addButton);

    // Action lors d'un clic sur le bouton
    addButton.setOnAction(event -> {
      listVBox.getChildren().add(new Label(wordTextField.getText()));
    });

    // Ajoute le formulaire et le libellé
    root.getChildren().add(formHbox);
    root.getChildren().add(listVBox);

    // La scène et la fenêtre
    Scene scene = new Scene(new ScrollPane(root), 400, 300);
    stage.setScene(scene);
    stage.show();
  }

  public static void main(String[] args) {
    launch();
  }

}

Test JUnit et TestFX JavaFX

package fr.ronanlefichant.testjavafx;

import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.testfx.api.FxAssert;
import org.testfx.api.FxRobot;
import org.testfx.framework.junit5.ApplicationExtension;
import org.testfx.framework.junit5.Start;

import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

@ExtendWith(ApplicationExtension.class)
class AppTestFx {

  /**
   * Méthode d'initialisation appelée avant chaque test
   *
   * @param stage La fenêtre (stage) injectée
   */
  @Start
  private void start(Stage stage) {
    App app = new App();
    app.start(stage);
  }

  /**
   * Vérifie si les libellés sont ajoutés
   * 
   * @param robot Le FxRobot injecté
   */
  @Test
  void should_display_list_labels(FxRobot robot) {
    robot.clickOn("#word-textfield");
    robot.write("Test");
    robot.clickOn("#add-btn");
    FxAssert.verifyThat("#list-vbox", node -> {
      VBox vbox = (VBox) node;
      Label label = (Label) vbox.getChildren().get(0);
      return label.getText().equals("Test");
    });

    robot.clickOn("#word-textfield");
    robot.eraseText("Test".length());
    robot.write("Test 2");
    robot.clickOn("#add-btn");
    FxAssert.verifyThat("#list-vbox", node -> {
      VBox vbox = (VBox) node;
      Label label = (Label) vbox.getChildren().get(0);
      Label label2 = (Label) vbox.getChildren().get(1);
      return label.getText().equals("Test") && label2.getText().equals("Test 2");
    });

  }

  /**
   * Vérifie si les libellés de la liste sont ajoutés
   * 
   * @param robot Le FxRobot injecté
   */
  @Test
  void should_display_list_all_labels_from_list(FxRobot robot) {
    List < String > listLabelTextExpected = Arrays.asList("Hello", "World", "Bye");

    IntStream.range(0, listLabelTextExpected.size()).forEach(i -> {

      String text = listLabelTextExpected.get(i);
      robot.clickOn("#word-textfield");

      if (i != 0) {
        String oldText = listLabelTextExpected.get(i - 1);
        robot.eraseText(oldText.length());
      }

      robot.write(text);
      robot.clickOn("#add-btn");
      FxAssert.verifyThat("#list-vbox", node -> {
        VBox vbox = (VBox) node;
        Label label = (Label) vbox.getChildren().get(i);
        return label.getText().equals(text);
      });

    });

  }

}

Commentaires