1

可能重复:
使 FEST 等待应用程序加载

注意:这个问题与这个问题基本相同。由于该问题没有答案,我决定将示例从那里扩展到可运行的 SSCE,并提供一些额外的信息,希望能得到一些帮助。

所以,问题是当寻找的组件可能还不存在时,您应该如何处理组件查找。看看这个简单的单标签 GUI。

public class MyFrame extends JFrame {
    JLabel theLabel;

    public MyFrame() {
        this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        theLabel = new JLabel();
        theLabel.setName("theLabelName");
        computeLabelContentOnWorkerThread();
    }

    private void computeLabelContentOnWorkerThread() {
        new SwingWorker<String, Void>() {
            @Override
            protected String doInBackground() throws Exception {
                Thread.sleep(5000);
                return "Info from slow database connection";
            }

            @Override
            protected void done() {
                try {
                    theLabel.setText(get());
                    add(theLabel);
                    pack();
                    setVisible(true);
                } catch (InterruptedException ignore) {
                } catch (ExecutionException ignore) {
                }
            }
        }.execute();
    }
}

而这个测试用例:

public class TestOfDelayedComponent extends FestSwingJUnitTestCase {

    FrameFixture frameWrapper;

    @Before
    public void onSetUp() {
        MyFrame frame = GuiActionRunner.execute(new GuiQuery<MyFrame>() {
            protected MyFrame executeInEDT() {
                return new MyFrame();
            }
        });
        frameWrapper = new FrameFixture(robot(), frame);
        frameWrapper.show();
    }

    @Test
    public void testLabelContent() {
        String labelContent = frameWrapper.label("theLabelName").text();
        assertTrue(labelContent.equals("Info from slow database connection"));
    }
}

怎么了?标签组件的构建被委托给一个缓慢的工作线程。因此,当 GUI 出现时,标签不会立即出现。运行测试用例时,标签还没有出现,所以在执行组件查找时frameWrapper.label("theLabelName"),会抛出 ComponentLookupException。

问题是如何防止抛出此异常?如果它是一个顶级组件,我可以做WindowFinder.findFrame("title").withTimeout(10000)一个 FrameFinder 对象,即使它们出现之前有延迟,它也可以找到可以找到的帧。我想要的是与此类似的东西,但对于其他类型的组件,例如 JLabel。


注意:当然,自己实现该功能并不难。这样做会很简单:

while(noComponentFound and notReachedTimeout){
    look for component using FEST
    sleep for a short delay
}

但是,最好不要被迫用这样的循环使测试脚本混乱。感觉好像等待组件在测试脚本中并不是一个太不寻常的任务。所以,在我看来,应该支持在 FEST 中这样做。也许事实并非如此?难道不能等待组件吗?

4

2 回答 2

1

有一种方法可以编写暂停和等待的条件。这是您需要的示例 while(noComponentFound 和 notReachedTimeout)。这可以通过 Pause.pause(new ComponentFoundCondition(...),timeout_milis) 来完成。例子:

    frame = WindowFinder.findFrame("frame0").using(robot); 
   //Wait for the event of loading tables in the GUI before we fail looking for them concurrently
    final GenericTypeMatcher<JTable> matcher = new GenericTypeMatcher<JTable>(JTable.class) {
          @Override protected boolean isMatching(JTable table){ return (table instanceof myTable && table.getColumnCount()<20); }  //Condition has to be totally identitary for one particular component. If not, we will never reach condition and so a timeout will be thrown in next line
    };                                                                                                                                     

    Pause.pause(new ComponentFoundCondition("Waiting for myTable to load before I look for it...", frame.robot.finder(), matcher, frame.target), 50000); //frame.target argument can be omitted. We also put an associated 50 sec timeout even if the condition is never satisfied
    fixedTable = frame.table(matcher); //Look finally for the table now we are sure its loaded

您可以与不同的匹配器一起玩。例如,如果框架下只有一种类型的表 myTable,那就很简单了:

    final ComponentMatcher matcher = new TypeMatcher(myTable.class); // We could use an easier TypeMatcher, because we would not need to add any additional distinction apart from the class type 
    Pause.pause(new Condition("Waiting for myTable to load...") { // If we are totally sure that there will be only one occurrence, we can use here the simplest form like above new ComponentFoundCondition("DebugMsg", frame.robot.finder(), matcher, frame.target)
        @Override public boolean test() { return !frame.robot.finder().findAll(frame.target, matcher).size().isEmpty(); } // If not we need a custom condition that checks for >0 instead of =1 results like ComponentNotFound.
     }, 50000); 

问题也是 (component->frame).table(matcher) 不接受 TypeMatcher,而只是一个 GenericMatcher,所以无论如何我们都应该创建 GenericMatcher

如果您找不到任何东西,总是可以选择静态修复 Pause.pause(5, TimeUnit.SECONDS);

于 2012-07-31T10:54:23.007 回答
0

我不使用 Fest,但 Pause.pause 在此页面上看起来很有趣: http ://www.pushing-pixels.org/2009/09/23/using-fest-swing-to-test-flamingo-components.html

于 2012-01-31T01:59:04.800 回答