You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在本地及Travis上运行含JavaFX元素的测试并实例化组件?

我之前也踩过这个坑!要在测试里实例化JavaFX组件(比如ProgressIndicator),核心问题就是测试环境默认没初始化JavaFX的Toolkit,不管是本地跑还是在Travis上,都得先把这一步搞定。下面给你几个实用的解决办法:

本地测试的解决方案

方法1:手动初始化JavaFX Toolkit

这是最直接的办法,在测试类的初始化方法里触发Toolkit加载就行。JFXPanel是Swing和JavaFX的桥接类,创建它会自动初始化Toolkit,我们可以利用这一点:

import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import org.junit.jupiter.api.BeforeAll;
import javafx.scene.control.ProgressIndicator;
import org.junit.jupiter.api.Test;

public class YourTestClass {
    @BeforeAll
    static void initJavaFXRuntime() {
        // 创建JFXPanel触发Toolkit初始化
        new JFXPanel();
        // 等待Toolkit完全就绪
        Platform.runLater(() -> {});
    }

    @Test
    void testWithProgressIndicator() {
        // 现在可以正常创建ProgressIndicator了
        ProgressIndicator indicator = new ProgressIndicator();
        // 执行你的测试逻辑
        assert indicator != null;
    }
}

注意:如果用的是JUnit 4,把@BeforeAll换成@BeforeClass,保持方法为静态即可。

方法2:使用TestFX框架(更适合复杂UI测试)

如果你的测试涉及更多JavaFX交互,TestFX是专门为JavaFX测试打造的框架,它会自动帮你处理Toolkit初始化,还支持模拟用户操作。
首先在build.gradle里添加依赖:

testImplementation 'org.testfx:testfx-core:4.0.16-alpha'
testImplementation 'org.testfx:testfx-junit5:4.0.16-alpha'

然后测试类继承ApplicationTest或者使用@TestFX注解:

import org.junit.jupiter.api.Test;
import org.testfx.framework.junit5.ApplicationTest;
import javafx.scene.control.ProgressIndicator;

public class YourFxTest extends ApplicationTest {
    @Test
    void testProgressIndicatorCreation() {
        ProgressIndicator indicator = new ProgressIndicator();
        // 这里可以放心执行测试逻辑
    }
}
Travis CI环境的配置

Travis是无头环境(没有图形界面),而且默认的JDK可能不带JavaFX运行时,需要额外配置:

  1. 配置带JavaFX的JDK
    .travis.yml里指定包含JavaFX的OpenJDK版本:
language: java
jdk:
  - openjdk17-jfx  # 对应你的项目Java版本,比如openjdk11-jfx
script:
  - ./gradlew test
  1. Gradle中配置JavaFX依赖(模块化项目)
    如果你的项目是模块化的,用OpenJFX插件来管理JavaFX依赖:
plugins {
    id 'java'
    id 'org.openjfx.javafxplugin' version '0.0.13'
}

javafx {
    version = '17'  // 和JDK版本对应
    modules = ['javafx.controls']  // 引入需要的模块,ProgressIndicator在javafx.controls里
}
  1. 无头模式运行TestFX(如果用TestFX)
    build.gradle的test任务里添加无头参数,避免因为没有显示设备报错:
test {
    jvmArgs = [
        '-Dtestfx.headless=true',
        '-Dprism.order=sw',
        '-Dprism.text=t2k'
    ]
}
额外小提示
  • 所有JavaFX组件的操作最好放在JavaFX应用线程里,用Platform.runLater()包裹,避免线程安全问题:
Platform.runLater(() -> {
    ProgressIndicator indicator = new ProgressIndicator();
    // 对组件的修改操作放在这里
});

内容的提问来源于stack exchange,提问作者PHPirate

火山引擎 最新活动