由于某些后台线程没有空闲,我的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)
答案 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)
您可以创建一个线程转储来查看阻止您的应用的内容。有时,当您创建多个线程转储时,它会有所帮助。