Skip to content
Jurgen edited this page Oct 21, 2020 · 20 revisions

Goals

  • Provide TestFX classes in a JavaFX project.
  • Add and run a JavaFX application class.
  • Add and run a TestFX application test class.

Project Integration

Artifacts

TestFX consists of modules (see next section) which are published in the form of artifact files. These artifacts have unique identifiers (i.e. a group, name and version), and can be used by a project.

              Gradle ─┐  ┌─ Maven    Maven  ─┐  ┌─ jCenter   jar ─┐  ┌─ sources
                      │  │          Central  │  │                 │  │
╔═════════╗      ╔════════════╗      ╔═════════════════╗      ╔══════════╗
║ Project ║------║ Build tool ║------║  Artifact Repo  ║------║ Artifact ║
╚═════════╝      ╚════════════╝      ╚═════════════════╝      ╚══════════╝
                      │  │                   │  │                    │
                 Ant ─┘  └─ IDE     Bintray ─┘  └─ GitHub            └─ javadoc

Figure 1: General overview of a project that uses artifacts.

  • Project: A new or existing project.
  • Build tool: Is used by the project. The Java compiler gathers information on which artifact files are used from it.
  • Artifact hoster: Hosts the artifact files which can be automatically (e.g. via Gradle or Maven) or manually downloaded.
  • Artifact: The classes for the Java compile process are provided in jar artifact files. Additionally for TestFX a sources.jar and javadoc.jar is provided (e.g. to use it in an IDE).

TestFX is deployed to Sonatype's Maven Central, Bintray, Bintray's jCenter, and to the GitHub release page of the project.

Modules

TestFX is organized in to modules that consist of a core module and several other modules that provide support for specific testing framework (JUnit 4, JUnit 5, and Spock).

testCompile(group: "org.testfx", name: "testfx-core", version: "4.0.13-alpha")
testCompile(group: "org.testfx", name: "testfx-junit", version: "4.0.13-alpha")
testCompile(group: 'junit', name: 'junit', version: '4.12')

Figure 2: Excerpt build file for Gradle (build.gradle)

The core module testfx-core is mandatory. It contains public API classes under the package org.testfx.api which cover all essentials needed to test JavaFX applications. The core module itself depends on the Hamcrest (hamcrest-core) and AssertJ (assertj-core) APIs.

Framework modules provide support classes to test JavaFX using a specific test runner and framework. The module testfx-junit, for instance, provides support for JUnit 4 under the package org.testfx.framework.junit. This module itself also depends on the JUnit 4 artifact. There is also testfx-junit5 which provides support for JUnit 5 under the package org.testfx.framework.junit5.

Simple JavaFX application

The following example application is written for JUnit 4 only. Here is an example of a test with testfx-junit5.

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);
        }
    }
}

Simple TestFX application test

import static org.testfx.api.FxAssert.verifyThat;
import static org.testfx.matcher.control.LabeledMatchers.hasText;

import org.testfx.framework.junit.ApplicationTest;
import org.testfx.robot.Motion;

import javafx.scene.control.Button;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

import org.junit.Test;

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!"));
    }
}