有一个现有的基于JavaFX的应用程序,我应该为其编写自动化测试.我刚开始使用TestFX(版本4.0.13-alpha)并寻找建议,如何记录和识别应用程序的UI对象.我尝试使用代码来初始化按钮,但无法单击它.
Button button = new Button("click me!");
Run Code Online (Sandbox Code Playgroud)
我找到了这些 GUI检查工具,但不确定哪一个可以与TestFX一起使用.
我正在使用带有 JavaFX 的 Spring Boot 进行测试(基于一些解释这一点的优秀 YouTube 视频)。
为了使它与TestFX 一起工作,我需要创建这样的上下文:
@Override
public void init() throws Exception {
SpringApplicationBuilder builder = new SpringApplicationBuilder(MyJavaFXApplication.class);
builder.headless(false); // Needed for TestFX
context = builder.run(getParameters().getRaw().stream().toArray(String[]::new));
FXMLLoader loader = new FXMLLoader(getClass().getResource("main.fxml"));
loader.setControllerFactory(context::getBean);
rootNode = loader.load();
}
Run Code Online (Sandbox Code Playgroud)
我现在想测试这个 JavaFX 应用程序,为此我使用:
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class MyJavaFXApplicationUITest extends TestFXBase {
@MockBean
private MachineService machineService;
@Test
public void test() throws InterruptedException {
WaitForAsyncUtils.waitForFxEvents();
verifyThat("#statusText", (Text text ) -> text.getText().equals("Machine stopped"));
clickOn("#startMachineButton");
verifyThat("#startMachineButton", …Run Code Online (Sandbox Code Playgroud) 我有一个JavaFX应用程序,我想测试它是否启动.我该怎么做呢?是否可以使用JUnit,或者TestFX可以帮助我吗?
我的主要问题是:如何在(成功)启动后立即关闭应用程序?
示例应用程序类:
public class MovieDB extends Application {
@Override
public void start(final Stage primaryStage) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(MovieDBController.class.getResource("MovieDB.fxml"), ResourceBundle.getBundle("bundles/bundle", new Locale("en")));
Parent root = fxmlLoader.load();
Scene scene = new Scene(root, 1024, 768);
StyleManager.getInstance().addUserAgentStylesheet(getClass().getResource("/css/MovieDB.css").getPath());
primaryStage.setTitle("MovieDB");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Run Code Online (Sandbox Code Playgroud) 我有一个简单的JavaFx应用程序(Java 8),它使用TestFx进行单元测试.但是,运行测试时,应用程序窗口会启动并移动鼠标以执行我的测试中的任何操作.这些测试能否以应用程序不弹出的方式运行,我仍然可以在自动构建和测试运行时将鼠标用于其他事情?
我们如何为 JavaFX 控制器逻辑正确编写单元/集成测试?假设我正在测试的 Controller 类名为LoadController,它的单元测试类是LoadControllerTest,我的困惑源于:
如果LoadControllerTest该类LoadController通过LoadController loadController = new LoadController();I实例化一个新对象,则
可以通过(许多)setter 将值注入控制器。这似乎是不使用反射(遗留代码)的唯一方法。如果我不将值注入 FXML 控件,则控件显然尚未初始化,返回 null。
如果我改用FXMLLoader'sloader.getController()方法来检索loadController它,它将正确初始化 FXML 控件,但initialize()因此调用了控制器的方法,这会导致运行非常缓慢,并且由于无法注入模拟依赖项,因此它更像是一个写得不好的集成测试.
我现在正在使用前一种方法,但有更好的方法吗?
测试效果
这里的答案涉及 TestFX,它@Tests基于主应用程序的start方法而不是Controller 类。它显示了一种测试控制器的方法
verifyThat("#email", hasText("test@gmail.com"));
Run Code Online (Sandbox Code Playgroud)
但是这个答案涉及DataFX - 而我只是询问 JavaFX 的 MVC 模式。大多数 TestFX 讨论都集中在它的 GUI 功能上,所以我很好奇它是否也适合控制器。
以下示例显示了我如何使用 a 注入控制器,VBox以便在测试期间它不为空。有没有更好的办法?请具体点
public class LoadControllerTest {
@Rule
public JavaFXThreadingRule javafxRule = new JavaFXThreadingRule();
private LoadController …Run Code Online (Sandbox Code Playgroud) 我有一个 JavaFx 应用程序,我尝试在无头模式下运行 TestFX junit。(在正常模式下工作)。在 Gradle 中,我配置了 openjfx-monocle:
compile group: 'org.testfx', name: 'openjfx-monocle', version: '8u76-b04'
Run Code Online (Sandbox Code Playgroud)
作为我启动 junit 时的参数,我使用以下内容:
-Djava.awt.headless=true -Dtestfx.robot=glass -Dtestfx.headless=true -Dprism.order=sw -Dprism.text=t2k -Dtestfx.setup.timeout=2500 -Dheadless.geometry=1920x1080-64
Run Code Online (Sandbox Code Playgroud)
我的操作系统是 Windows 7 Proffesional 64 位,jdk 是“1.8.0_152”。
我试图改变参数 -Dheadless.geometry 但没有结果。任何的想法?
收到的错误是:
java.nio.BufferOverflowException
at java.nio.DirectIntBufferU.put(DirectIntBufferU.java:363)
at com.sun.javafx.tk.quantum.UploadingPainter.run(UploadingPainter.java:153)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
at com.sun.javafx.tk.RenderJob.run(RenderJob.java:58)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:125)
at java.lang.Thread.run(Thread.java:748)`
Run Code Online (Sandbox Code Playgroud) 在Eclipse photon和fx9或fx11中使用TestFX 4.0.14(无关紧要),来自TestFX Wiki 的简单示例测试失败了should_click_on_button(),
Expected: Labeled has text "clicked!"
but: was "click me!"
Run Code Online (Sandbox Code Playgroud)
当查看屏幕时,将显示窗格及其包含的按钮,但是鼠标会移动到其他地方:因此,永远不会单击该按钮,因此其文本也不会改变。
任何想法有什么问题/如何解决?
测试代码(为方便起见,全部从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() …Run Code Online (Sandbox Code Playgroud) 我正在编写一个 TestFX 测试用例来覆盖 Java 桌面应用程序。其中一项交互调用 showDocument() 以使用浏览器显示 html 文档。当使用 Gradle 在本地运行测试时,我的测试工作正常。但是当我在 Jenkins(使用 MacOS 代理)上运行它时,测试失败了。
14:55:10 java.awt.HeadlessException
14:55:10 at java.desktop/java.awt.Desktop.getDesktop(Desktop.java:301)
14:55:10 at javafx.graphics/com.sun.javafx.application.HostServicesDelegate$StandaloneHostService.showDocument(HostServicesDelegate.java:133)
14:55:10 at javafx.graphics/javafx.application.HostServices.showDocument(HostServices.java:115)
Run Code Online (Sandbox Code Playgroud)
该问题是在 Desktop 检查 GraphicsEnvironment.isHeadless() 时引起的
为什么会发生这个错误?我读到,当没有可以使用的 GUI(显示器、键盘、鼠标)时会发生 HeadlessException,但我的代理确实有 GUI。此测试在 Windows 代理上可以正常工作,但在 MacOS 上则不行。如何避免此错误并在 Jenkins 上执行自动化测试?
我在使用Oracle的JavaFx HelloWorld应用程序时遇到一些问题:
public class HelloWorld extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Hello World!");
Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("Hello World!");
}
});
StackPane root = new StackPane();
root.getChildren().add(btn);
primaryStage.setScene(new Scene(root, 300, 250));
primaryStage.show();
}
}
Run Code Online (Sandbox Code Playgroud)
TestFx junit测试:
class MyTest extends GuiTest {
public Parent getRootNode() {
return nodeUnderTest;
}
Run Code Online (Sandbox Code Playgroud)
nodeUnderTest这个例子应该是什么?
我ArithmeticProblem在 TestFX 中为类编写了一个单元测试。
public class ArithmeticProblemTextFx extends TestFxBase {
@Test(expected = FxRobotException.class)
public void fxIdNotExist() {
clickOn("#test123");
}
@Test
public void allComponentsShouldHaveRightText() {
verifyThat("#jfxButtonCheck", hasText("PRÜFEN"));
verifyThat("#jfxButtonNextArithmeticProblem", hasText("NÄCHSTE AUFGABE"));
verifyThat("#jfxButtonSave", hasText("SPEICHERN"));
verifyThat("#jfxTextFieldResult", hasText(""));
}
@Test
public void checkTextFieldResult() {
JFXTextField jfxTextFieldResult = find("#jfxTextFieldResult");
JFXButton jfxButtonCheck = find("#jfxButtonCheck");
jfxTextFieldResult.setText("5");
assertFalse(
"Der Button ist darf NICHT disable sein, da eine Zahl in TextFieldResult steht.",
jfxButtonCheck.isDisable()
);
jfxTextFieldResult.setText("g");
assertTrue(
"Der Button muss disable sein, da KEINE Zahl in TextFieldResult steht.",
jfxButtonCheck.isDisable()
); …Run Code Online (Sandbox Code Playgroud) testfx ×10
javafx ×9
java ×8
unit-testing ×4
javafx-8 ×2
controller ×1
gradle ×1
headless ×1
jenkins ×1
jfoenix ×1
spring-boot ×1
spring-test ×1
testing ×1