2016-04-24 8 views
1

Ich habe die folgende Testmethode:Was ist der beste Weg, um EDT/Nicht-EDT-Probleme mit JUnit zu behandeln?

@Test public void f3KeystrokeShowsHotkeysDialog() throws AWTException{ 
    App app = new App(); 

    Robot robot = new Robot(); 
    robot.keyPress(KeyEvent.VK_F3); 

    try { 
     Thread.sleep(1000L); 
    } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    assertTrue(app.mainFrame.hotkeysDlg.isVisible()); 
} 

Mit den sleep dieser assertTrue Pässe; ohne es scheitert es.

Der Grund ist offensichtlich: Robot, die in einem Nicht-EDT-Thread ausgeführt werden muss, und erzeugt hier eine KeyEvent, auf die der EDT eine begrenzte Zeit braucht, um darauf zu reagieren.

Die entsprechende Action ist wie folgt:

ActionMap am = mainFrame.getRootPane().getActionMap(); 
    Action f3Action = new AbstractAction(){ 
     @Override 
     public void actionPerformed(ActionEvent arg0) { 
      System.out.println("# blip..."); 

      mainFrame.hotkeysDlg.setVisible(true); 
     } 
    }; 
    am.put("show hotkeys", f3Action); 

... actionPerformed natürlich im EDT ausgeführt wird.

Kann jemand, der viel über das Testen kennt sagen Sie mir:

  1. soll ich tun es so, mit einem „beliebigen“ Schlaf beteiligt?

  2. Gibt es einen besseren Rahmen oder eine bessere Technik für die Handhabung dieser, die ich vermutet, ist eine ziemlich häufige Situation?

  3. sollte ich diese Art von Tests insgesamt vermeiden? NB Ich bin mir bewusst, das ist nicht "Unit Testing" als solches, aber es ist (glaube ich) Funktionstests: "drücken Sie F3: ein Hotkeys-Dialog erscheint" < - das ist eine Spezifikation der App ...

Antwort

0

Für jeden, der auf dieses Thema stieß und sich für diese Art von Dingen interessierte, dachte ich einfach, ich würde destillieren, was ich denke, dass ich in den letzten Tagen gelernt habe.

Zunächst scheint es, dass das Testen von GUI-Funktionalität ist etwas, was die „Profis“ am Ende hinzufügen auf: zuerst Sie den Mut der App bekommen arbeiten ...

Zweitens scheint es, dass GUI-Tests recht sind herausfordernd.

Drittens möchte ich den obigen Code durch diese ersetzen:

App app = new App(); 
    Robot robot = new Robot(); 
    robot.keyPress(KeyEvent.VK_F3); 
    robot.waitForIdle(); 
    EventQueue.invokeAndWait(new Runnable() { 
     @Override 
     public void run() { 
      assertTrue(app.mainFrame.hotkeysDlg.isVisible()); 
     } 
    }); 

... die Verwendung von Robot.waitForIdle() demonstrieren ... und auch richtig (ich glaube) im Thread einen Test der Sichtbarkeit setzen, wo es gehört, dh der EDT. Wie auch immer, es scheint zu funktionieren, was gut genug ist um damit klar zu kommen!

NB EventQueue.invokeAndWait sind die weniger bekannten Geschwister von EventQueue.invokeLater, aber in einem Test Kontext wie diese es scheint eigentlich ganz entscheidend zu sein: wenn Sie invokeLater verwenden eine hohe Wahrscheinlichkeit scheint, dass der Test beendet und aufzuräumen passieren wird, usw., bevor die assertTrue tatsächlich läuft ...