Espresso和postDelayed

Mat*_*att 11 android android-espresso

我有一个使用postDelayed调用的活动:

public class SplashActivity extends Activity {
    private Handler handler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(...);
        handler.postDelayed(new Runnable() { 
            public void run() { finish(); }
        }, 3000L);
    }
 }
Run Code Online (Sandbox Code Playgroud)

这在app启动时运行,我需要导航它和我的登录屏幕.但是,UIController的loopMainThreadUntilIdle似乎并未将处理程序中的基础MessageQueue考虑在内.因此,当队列中仍有消息时,此操作立即结束.

onView(withId(R.id.splash_screen)).perform(new ViewAction() {
    @Override
    public Matcher<View> getConstraints() {
        return isAssignableFrom(View.class);
    }

    @Override
    public String getDescription() {
        return "";
    }

    @Override
    public void perform(final UiController uiController, final View view) {
        uiController.loopMainThreadUntilIdle();
    }
});
Run Code Online (Sandbox Code Playgroud)

在队列耗尽之前,我一直无法弄清楚如何阻止.Android本身阻止我做很多我想尝试的事情(比如扩展Handler并覆盖postDelayed方法等等)

任何人对如何处理postDelayed有任何建议?

我宁愿避免使用uiController.loopMainThreadForAtLeast,这看起来很hacky(就像Thread.sleep一样)

Gil*_*ach 11

当Espresso等待时,它实际上确实考虑到了MessageQueue,但与您的想法不同.要空闲,队列必须为空,或者 从现在开始在15毫秒以内运行任务.

您可以检查自己的代码,尤其是法loopUntil()UiControllerImpl.java和文件QueueInterrogator.java.在后一个文件中,您还将找到Espresso如何检查MessageQueue(方法determineQueueState())的逻辑.

现在,如何解决您的问题?有很多方法:

  1. 使用AsyncTask而不是Handler,在后台线程上休眠并执行操作onPostExecute().这样做是因为Espresso会等待AsyncTask完成,但你可能不喜欢另一个线程的开销.

  2. 睡在你的测试代码中,但你不喜欢这种方法.

  3. 编写自定义IdlingResource:这是一种通用机制,让Espresso知道什么时候空闲,以便它可以运行操作和断言.对于这种方法,您可以:

    • 使用CountingIdlingResourceEspresso附带的课程

    • 在逻辑运行后increment()发布runnable并decrement()在runnable内部调用

    • 注册您的IdlingResource测试设置,并在撕裂注销下来

另请参阅:docs和sample,另一个示例