在测试Android UI时,等待UI准备好的正确方法是什么?

时间:2012-02-22 19:24:03

标签: android testing

测试看起来像那样(它是ActivityInstrumentationTestCase2):

public void testItShowsThreeRows() {
  activity = getActivity();

  activity.runOnUiThread(new Runnable() {
    public void run() {
      AccountsList accountsList = new AccountsList(activity, accounts);
      list.show();
    }
  });

  ListView listView = (ListView)activity.findViewById(R.id.list);
  assertEquals(3, listView.getChildCount());
}

我正在尝试测试的代码。但测试失败,因为activity.runOnUiThread立即返回。我可以插入Thread.sleep,测试变成绿色,但对我来说看起来有点笨拙。我是否必须使用某些线程同步,或者可能需要轮询某些UI元素才能准备好?

我尝试使用@UiThreadTest对其进行注释,但这也不起作用。 list.show()中的代码通过自定义适配器填充ListView,并在另一个线程上调用getView(不是一个测试运行 - 我与此无关,我没有线程或asynctasks,没有什么)。测试再次失败,因为它在UI准备好进行检查之前返回。

3 个答案:

答案 0 :(得分:14)

调用waitForIdleSync()比在一段固定时间内休眠更好。

答案 1 :(得分:3)

你必须做一个Thread.sleep。我认为没有办法解决这个问题。我不明白为什么那么“笨重”;你正在做一个测试,所以你必须等待系统显示你想要测试的UI元素。

但在我看来,您确实在尝试测试AccountsList或列表。除非你是偏执狂,否则没有理由测试ListView或findViewById。

您应该专注于测试AccountsList和您的自定义适配器。您不必使用UI来执行此操作。

答案 2 :(得分:0)

在文档之后,“ Espresso的关键部分之一是它能够同步所有测试操作。Espresso一直等到UI处于空闲状态,然后再进行下一个操作。同样,它等待AsyncTask后台操作完成。通常,这应该可以解决应用程序中的大多数测试同步问题。如果您以前编写过UI测试,您会喜欢此功能-无需在应用程序中添加等待或同步点!

但是,有时无法依靠自动同步,例如,当您的应用通过非标准方式(直接管理线程或使用自定义服务)进行后台操作时。如果遇到无法依靠Espresso自动为您处理同步的情况,则可以使用空闲资源,仍然依靠Espresso进行同步。”

您可以在testing codelab上阅读完整的示例,也可以在github中获得示例的源代码。