2013-08-25 64 views
17

Tôi muốn tạo thử nghiệm JUnit cơ bản cho ứng dụng JavaFX 8. Tôi có mẫu mã đơn giản này:Kiểm tra JUnit cơ bản cho JavaFX 8

public class Main extends Application { 
    public static void main(String[] args) { 
     Application.launch(args); 
    } 
    @Override 
    public void start(Stage primaryStage) { 
     primaryStage.setTitle("Tabs"); 
     Group root = new Group(); 
     Scene scene = new Scene(root, 400, 250, Color.WHITE); 
     TabPane tabPane = new TabPane(); 
     BorderPane borderPane = new BorderPane(); 
     for (int i = 0; i < 5; i++) { 
      Tab tab = new Tab(); 
      tab.setText("Tab" + i); 
      HBox hbox = new HBox(); 
      hbox.getChildren().add(new Label("Tab" + i)); 
      hbox.setAlignment(Pos.CENTER); 
      tab.setContent(hbox); 
      tabPane.getTabs().add(tab); 
     } 
     // bind to take available space 
     borderPane.prefHeightProperty().bind(scene.heightProperty()); 
     borderPane.prefWidthProperty().bind(scene.widthProperty()); 

     borderPane.setCenter(tabPane); 
     root.getChildren().add(borderPane); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 
} 

tôi chỉ có mã này cho đến nay:

import javafx.application.Application; 
import javafx.stage.Stage; 
import org.junit.BeforeClass; 

public class BasicStart extends Application { 

    @BeforeClass 
    public static void initJFX() { 
     Thread t = new Thread("JavaFX Init Thread") { 
      @Override 
      public void run() { 
       Application.launch(BasicStart.class, new String[0]); 
      } 
     }; 
     t.setDaemon(true); 
     t.start(); 
    } 

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     // noop 
    } 
} 

Bạn có thể cho tôi biết làm thế nào tôi có thể tạo thử nghiệm JUnit cho mã trên?

+2

tôi sẽ khuyên bạn sử dụng JemmyFX - phải mất một chút thời gian và công sức để thiết lập và làm quen với, nhưng nó là rất mạnh mẽ. Bạn có thể sẽ dành rất nhiều thời gian và công sức để làm một cái gì đó không tốt nếu bạn bắt đầu từ đầu anyway. – assylias

Trả lời

3

Các aproach đơn giản nhất là như sau:

import javafx.application.Platform; 
import javafx.embed.swing.JFXPanel; 
import javafx.stage.Stage; 

import org.junit.Test; 

public class BasicStart { 

    @Test 
    public void testA() throws InterruptedException { 
     Thread thread = new Thread(new Runnable() { 

      @Override 
      public void run() { 
       new JFXPanel(); // Initializes the JavaFx Platform 
       Platform.runLater(new Runnable() { 

        @Override 
        public void run() { 
         new Main().start(new Stage()); // Create and 
                 // initialize 
                 // your app. 

        } 
       }); 
      } 
     }); 
     thread.start();// Initialize the thread 
     Thread.sleep(10000); // Time to use the app, with out this, the thread 
           // will be killed before you can tell. 
    } 

} 

Hy vọng nó sẽ giúp!

+6

Tôi muốn tránh Thread.sleep() nếu bạn có thể. Nó không phải là một vấn đề lớn với vài bài kiểm tra, nhưng nó thực sự chậm lại khi bạn có hàng trăm bài kiểm tra. Xem nếu bạn có thể sử dụng một số loại chốt để thay thế. –

+0

Vì nó đứng này không xuất hiện để báo cáo một xác nhận không thành công (bên trong 'run') bằng cách sử dụng các cơ chế báo cáo JUnit bình thường, vì' Runnable' không thể truyền một 'Exception'. –

26

Tôi sử dụng Quy tắc Junit để chạy thử nghiệm đơn vị trên chuỗi JavaFX. Chi tiết nằm trong số this post. Chỉ cần sao chép lớp từ bài đăng đó và sau đó thêm trường này vào các bài kiểm tra đơn vị của bạn.

@Rule public JavaFXThreadingRule javafxRule = new JavaFXThreadingRule(); 

Mã này hoạt động cho cả JavaFX 2 và JavaFX 8.

+1

Điều này làm việc khá độc đáo tuy nhiên chạy thử nghiệm trên thread có nghĩa là bạn không thể có bất kỳ giấc ngủ hoặc chờ đợi và bất kỳ mã nào sử dụng platform.runLater không thể được kiểm tra - trừ khi bạn có thể đề xuất một công việc xung quanh? – Adam

+0

@Adam Tại sao bạn không thể sử dụng bất kỳ giấc ngủ hoặc chờ đợi nào? Họ thường không được khuyến cáo sử dụng trong các bài kiểm tra đơn vị, nhưng tôi không thấy lý do tại sao bạn sẽ không thể sử dụng chúng nếu bạn thực sự cần thiết. Nếu bạn muốn sử dụng Platform.runLater() thì bạn chỉ có thể chạy trên thread chính, nếu không thì tại sao bạn cần gọi Platform.runLater() nếu bạn đã ở trên chủ đề javafx? –

+1

Để thử và giải thích tốt hơn .... Tôi đang nói về các bài kiểm tra tích hợp ở đây, không thực sự kiểm tra đơn vị mặc dù sử dụng JUnit. Nếu hiển thị được cập nhật từ một luồng khác, giả sử một máy khách mạng thì Platform.runLater (runnable) phải được sử dụng, tuy nhiên runnable đó không được thực hiện cho đến sau khi kiểm tra (chạy trên chuỗi fx) đã hoàn thành và trả về điều khiển trở lại chính Chuỗi FX sau đó sẽ phục vụ công việc tiếp theo trong hàng đợi. – Adam

2

Dựa trên Brian Blonski 's answer Tôi tạo ra một JUnit-Testrunner, mà không thực chất điều tương tự, nhưng là một chút đơn giản để sử dụng theo ý kiến ​​của tôi . Sử dụng nó, kiểm tra của bạn sẽ trông như thế này:

@RunWith(JfxTestRunner.class) 
public class MyUnitTest 
{ 
    @Test 
    public void testMyMethod() 
    { 
    //... 
    } 
} 
+1

Dường như liên kết của bạn bị hỏng. Đã có thể yêu thích để xem TestRunner! – MikaelF

+1

Tôi đã sửa liên kết. Nhưng tôi nên cảnh báo bạn; Tôi thấy mã không an toàn chỉ. –