如何在TestFX中测试多个场景
How to test multiple scenes in TestFX
我在 TestFX 中为 ArithmeticProblem
class 编写了单元测试。
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()
);
}
@Test
public void checkJfxButtonSaveClick() {
clickOn("#jfxButtonSave");
verifyThat("#labelTotalResults", hasText("0"));
verifyThat("#labelNumberOfRightResults", hasText("0"));
verifyThat("#labelAmountOfRightResults", hasText("(0%)"));
verifyThat("#labelNumberOfWrongResults", hasText("0"));
verifyThat("#labelAmountOfWrongResults", hasText("(0%)"));
verifyThat("#labelTimePerArithmeticProblem", hasText(""));
verifyThat("#labelMark", hasText("-"));
verifyThat("#labelRightResult", hasText(""));
verifyThat("#jfxTextFieldResult", hasText(""));
}
@Test
public void checkJfxButtonNextArithmeticProblemClick() {
clickOn("#jfxButtonNextArithmeticProblem");
verifyThat("#labelRightResult", hasText(""));
verifyThat("#jfxTextFieldResult", hasText(""));
verifyThat("#labelTimePerArithmeticProblem", hasText(""));
}
}
这里是"TestFxBase"
的代码
public class TestFxBase extends ApplicationTest {
@Before
public void setUpClass() throws Exception {
ApplicationTest.launch(Main.class);
}
@After
public void afterEachTest() throws TimeoutException {
FxToolkit.hideStage();
release(new KeyCode[]{});
release(new MouseButton[]{});
}
@Override
public void start(Stage stage) throws Exception {
stage.show();
}
public <T extends Node> T find(final String query) {
return (T) lookup(query).queryAll().iterator().next();
}
}
当我加载 Main.class 时,它只显示 ArithmeticProblem-Scene。这是它的样子。
所以我只能测试ArithmeticProblem.class,因为我不知道如何加载其他场景。
在我的菜单里有一些其他的点,比如评价或设置,我该如何加载这个场景?
实际上你不应该在一次测试中测试所有的场景class。它违反了 SRP(单一职责原则)。相反,您应该分离您的组件,以便您可以单独测试它们。即 ArithmeticProblem
应该在 ArithmeticProblemTest
class 中测试,Settings
class 应该在 SettingsTest
class 中测试等等
TestFX
github 存储库中有一个很好的示例。
public class DesktopPaneTest extends ApplicationTest {
@Override
public void start(Stage stage) {
Scene scene = new Scene(new DesktopPane(), 800, 600);
stage.setScene(scene);
stage.show();
}
@Test
public void should_drag_file_into_trashcan() {
// given:
rightClickOn("#desktop").moveTo("New").clickOn("Text Document");
write("myTextfile.txt").push(ENTER);
// when:
drag(".file").dropTo("#trash-can");
// then:
verifyThat("#desktop", hasChildren(0, ".file"));
}
}
在 start
方法中,您可以将您的组件 (JavaFX Node
) 添加到场景中,这个示例是 new DesktopPane()
,在您的情况下它将是 new ArithmeticProblem()
, new Settings()
等
ApplicationTest.launch(Main.class);
将不再需要。
@Before
public void setUpClass() throws Exception {
ApplicationTest.launch(Main.class);
}
请注意,在此示例中,仅使用 Given-When-Then 场景测试行为。我建议您在测试中使用此场景。
我想这些测试也是多余的:
@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(""));
}
因为第一个测试只是测试不存在,第二个测试只是测试文本,什么都不做。如果您使用这些文本创建了文本字段,那么它们必须存在并且应该在某些行为后进行检查。
希望我的回答对你有用。如果您有任何问题,请随时给我写信。
我在 TestFX 中为 ArithmeticProblem
class 编写了单元测试。
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()
);
}
@Test
public void checkJfxButtonSaveClick() {
clickOn("#jfxButtonSave");
verifyThat("#labelTotalResults", hasText("0"));
verifyThat("#labelNumberOfRightResults", hasText("0"));
verifyThat("#labelAmountOfRightResults", hasText("(0%)"));
verifyThat("#labelNumberOfWrongResults", hasText("0"));
verifyThat("#labelAmountOfWrongResults", hasText("(0%)"));
verifyThat("#labelTimePerArithmeticProblem", hasText(""));
verifyThat("#labelMark", hasText("-"));
verifyThat("#labelRightResult", hasText(""));
verifyThat("#jfxTextFieldResult", hasText(""));
}
@Test
public void checkJfxButtonNextArithmeticProblemClick() {
clickOn("#jfxButtonNextArithmeticProblem");
verifyThat("#labelRightResult", hasText(""));
verifyThat("#jfxTextFieldResult", hasText(""));
verifyThat("#labelTimePerArithmeticProblem", hasText(""));
}
}
这里是"TestFxBase"
的代码public class TestFxBase extends ApplicationTest {
@Before
public void setUpClass() throws Exception {
ApplicationTest.launch(Main.class);
}
@After
public void afterEachTest() throws TimeoutException {
FxToolkit.hideStage();
release(new KeyCode[]{});
release(new MouseButton[]{});
}
@Override
public void start(Stage stage) throws Exception {
stage.show();
}
public <T extends Node> T find(final String query) {
return (T) lookup(query).queryAll().iterator().next();
}
}
当我加载 Main.class 时,它只显示 ArithmeticProblem-Scene。这是它的样子。
所以我只能测试ArithmeticProblem.class,因为我不知道如何加载其他场景。 在我的菜单里有一些其他的点,比如评价或设置,我该如何加载这个场景?
实际上你不应该在一次测试中测试所有的场景class。它违反了 SRP(单一职责原则)。相反,您应该分离您的组件,以便您可以单独测试它们。即 ArithmeticProblem
应该在 ArithmeticProblemTest
class 中测试,Settings
class 应该在 SettingsTest
class 中测试等等
TestFX
github 存储库中有一个很好的示例。
public class DesktopPaneTest extends ApplicationTest {
@Override
public void start(Stage stage) {
Scene scene = new Scene(new DesktopPane(), 800, 600);
stage.setScene(scene);
stage.show();
}
@Test
public void should_drag_file_into_trashcan() {
// given:
rightClickOn("#desktop").moveTo("New").clickOn("Text Document");
write("myTextfile.txt").push(ENTER);
// when:
drag(".file").dropTo("#trash-can");
// then:
verifyThat("#desktop", hasChildren(0, ".file"));
}
}
在 start
方法中,您可以将您的组件 (JavaFX Node
) 添加到场景中,这个示例是 new DesktopPane()
,在您的情况下它将是 new ArithmeticProblem()
, new Settings()
等
ApplicationTest.launch(Main.class);
将不再需要。
@Before
public void setUpClass() throws Exception {
ApplicationTest.launch(Main.class);
}
请注意,在此示例中,仅使用 Given-When-Then 场景测试行为。我建议您在测试中使用此场景。
我想这些测试也是多余的:
@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(""));
}
因为第一个测试只是测试不存在,第二个测试只是测试文本,什么都不做。如果您使用这些文本创建了文本字段,那么它们必须存在并且应该在某些行为后进行检查。
希望我的回答对你有用。如果您有任何问题,请随时给我写信。