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

Art*_*rov 9 testing android

测试看起来像那样(它是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());
}
Run Code Online (Sandbox Code Playgroud)

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

我试着用它注释,@UiThreadTest但这也不起作用.代码list.show()填充一个ListViewvia自定义适配器,并getView在另一个线程上调用(不是一个测试运行 - 我与之无关,我没有线程或asynctasks,没有任何东西).测试再次失败,因为它在UI准备好进行检查之前返回.

Mik*_*yle 15

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


Joe*_*lin 3

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

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

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

  • 我可以告诉你为什么我不喜欢`Thread.sleep`。您睡得太多 - 您浪费了宝贵的时间来进行测试。你睡得太少——你的测试失败了。睡多少时间才合适呢?这得看情况。在您正在测试的代码上以及您正在测试它的工作站上。您将项目移至另一台计算机,测试开始失败。这就是适合您的“Thread.sleep”。 (13认同)
  • 我刚刚重读了昨天的评论,现在看来它们对我来说不太礼貌。不管是什么情况,我向你保证,这都是因为英语不是我的母语。我非常重视您的回答,并且会接受它(如果没有更好的消息出现:)。 (3认同)