Espresso测试用背景线程阻止。应用程序不空闲异常:" AppNotIdleException。"

时间:2016-09-14 07:51:54

标签: android multithreading android-asynctask android-espresso

由于某些后台线程没有空闲,我的android espresso单元测试被阻止了。我怎样才能找出阻止我的应用程序执行的线程?

        android.support.test.espresso.AppNotIdleException: Looped for 246 iterations over 60 SECONDS. The following Idle Conditions failed ASYNC_TASKS_HAVE_IDLED.
        at dalvik.system.VMStack.getThreadStackTrace(Native Method)
        at java.lang.Thread.getStackTrace(Thread.java:580)
        at android.support.test.espresso.base.DefaultFailureHandler.getUserFriendlyError(DefaultFailureHandler.java:92)
        at android.support.test.espresso.base.DefaultFailureHandler.handle(DefaultFailureHandler.java:56)
        at android.support.test.espresso.ViewInteraction.runSynchronouslyOnUiThread(ViewInteraction.java:184)
        at android.support.test.espresso.ViewInteraction.doPerform(ViewInteraction.java:115)
        at android.support.test.espresso.ViewInteraction.perform(ViewInteraction.java:87)
        at android.support.test.espresso.Espresso.closeSoftKeyboard(Espresso.java:159)

2 个答案:

答案 0 :(得分:1)

作为开始:

  

Espresso for Android是完美而快速的测试自动化框架,   但它有一个重要的限制 - 你只能操作   在测试环境下的应用内部。

     

自:   http://qathread.blogspot.com/2015/05/espresso-uiautomator-perfect-tandem.html

这意味着执行任何操作的Espresso需要在app的主线程上运行。它检查UI线程何时为idle(),如果不是,则等待UI线程再次空闲。

如果UI线程空闲时间过长,则会产生AppNotIdleException之类的Espressso IdlingResources错误,这意味着:

  

一个异常,表示即使在指定的持续时间后应用程序也没有变为空闲状态。

要处理此问题,您需要创建自己的IdlingResource方法,以便在UI线程为Espresso时为idle()说明。

让我们更深入地了解问题:

  

Espresso引入了IdlingResource的概念,这很简单   界面:

     
    

表示正在测试的应用程序的资源     这可能导致在测试期间发生异步后台工作     执行

  
     

界面定义三个方法:

     
      
  • getName():必须返回标识空闲资源的非空字符串。
  •   
  • isIdleNow():返回空闲资源的当前空闲状态。如果返回true,则onTransitionToIdle()方法   注册的ResourceCallback必须先前已被调用。
  •   
  • registerIdleTransitionCallback(IdlingResource.ResourceCallback callback):通常这个方法用于存储对的引用   回调以通知它空闲状态的变化。
  •   
     

例如,等待a的空闲资源的实现   要在WebView中完全加载的页面将如下所示:

public class WebViewIdlingResource extends WebChromeClient implements IdlingResource {

    private static final int FINISHED = 100;

    private WebView webView;
    private ResourceCallback callback;

    private WebViewIdlingResource(WebView webView) {
        this.webView = checkNotNull(webView,
                String.format("Trying to instantiate a \'%s\' with a null WebView", getName())));
        // Shall we save the original client? Atm it's not used though.
        this.webView.setWebChromeClient(this);
    }

    @Override public void onProgressChanged(WebView view, int newProgress) {
        if (newProgress == FINISHED && view.getTitle() != null && callback != null) {
            callback.onTransitionToIdle();
        }
    }

    @Override public void onReceivedTitle(WebView view, String title) {
        if (webView.getProgress() == FINISHED && callback != null) {
            callback.onTransitionToIdle();
        }
    }

    @Override public String getName() {
        return "WebView idling resource";
    }

    @Override public boolean isIdleNow() {
        // The webView hasn't been injected yet, so we're idling
        if (webView == null) return true;
        return webView.getProgress() == FINISHED && webView.getTitle() != null;
    }

    @Override public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
        this.callback = resourceCallback;
    }
}
     

创建自己的自定义空闲资源后,需要这样做   通过致电在Espresso注册   Espresso.registerIdlingResource(webViewIdlingResource)

     

自:http://dev.jimdo.com/2014/05/09/wait-for-it-a-deep-dive-into-espresso-s-idling-resources/

如果它失败了,请尝试使用Espresso另一个名为[uiatomator的Google测试框架,它可以帮助您解决此问题。

希望它会有所帮助

答案 1 :(得分:0)

您可以创建一个线程转储来查看阻止您的应用的内容。有时,当您创建多个线程转储时,它会有所帮助。