2013-08-25 14 views
17

JavaFX 8アプリケーションの基本的なJUnitテストを作成したいと思います。私はこの単純なコードサンプルがありますJavaFX 8の基本的なJUnitテスト

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

私はこれまでのところ、このコードを持っている:

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

は、私は上記のコードのためのJUnitテストを作成する方法を教えてもらえますか?

+2

私はJemmyFXを使用することをお勧めします - それはセットアップに時間と労力のビットを取り、に慣れるが、それは非常に強力です。とにかく最初からやり直すのであれば、時間と労力を費やすことになります。 – assylias

答えて

3

最も簡単なaproachは次のとおりです。

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. 
    } 

} 

はそれが役に立てば幸い!

+6

できれば私はThread.sleep()を避けたいと思います。いくつかのテストで大したことではありませんが、何百ものテストがある場合は本当に遅くなります。代わりに何らかの種類のラッチを使用できるかどうかを確認してください。 –

+0

これは、 'Runnable'が' Exception'を伝播することができないので、通常のJUnitの報告メカニズムを使って( 'run'の中で)失敗したアサーションを報告するようには見えません。 –

26

JavaFXスレッドでユニットテストを実行するには、Junitルールを使用します。詳細はthis postです。その投稿からクラスをコピーして、このフィールドを単体テストに追加してください。

@Rule public JavaFXThreadingRule javafxRule = new JavaFXThreadingRule(); 

このコードは、に基づいたJavaFX 2およびJavaFXの8

+1

これは非常にうまく動作しますが、スレッド上でテストを実行すると、スリープや待機を行うことができず、回避策を提案できない限り、platform.runLaterを使用するコードはテストできません。 – Adam

+0

@Adamなぜあなたは睡眠や待っていることができませんか?彼らは一般的に単体テストでの使用はお勧めしませんが、本当に必要な場合にそれらを使用できない理由はわかりません。もしあなたがPlatform.runLater()を使いたいのであれば、メインスレッド上で動かすことができます。そうでなければ、javafxスレッド上にある場合はなぜPlatform.runLater()を呼び出す必要がありますか? –

+1

もっと説明しようとすると....ここではJUnitを使用していますが、ユニットテストではなく、ここでの統合テストについて話しています。ディスプレイが別のスレッド、例えばネットワーククライアントから更新された場合は、Platform.runLater(runnable)を使用する必要がありますが、テスト(fxスレッド上で実行中)が完了してコントロールをメインに戻すまでrunnableは実行されませんFXスレッドはキュー内の次のジョブを処理します。 – Adam

2

の両方のために働くBrian Blonskianswer私は基本的に同じことを行いますが、私の意見で使用するビット簡単ですJUnit-Testrunnerを作成。 それを使用して、あなたのテストは次のようになります。

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

リンクが壊れているようです。 TestRunnerを見たことが大好きでしたか? – MikaelF

+1

私はリンクを修正しました。しかし、私はあなたに警告する必要があります。コードがスレッドセーフではないことが判明しました。 –