Make Espresso等待WebView完成加载

时间:2015-08-18 10:51:00

标签: android testing webview android-espresso

是否有一种可靠的方法让Espresso等待WebViews完成加载?

我已经尝试了here概述的方法,但发现它不可靠。它还有其他缺点:

  • 它依赖于替换WebView的WebChromeClient。任何现有的WebChromeClient都不能被包装,因为WebViewrt由于某种原因没有getWebChromeClient()方法。
  • 它需要一个特定的WebView实例,因此每次我使用WebView启动一个Activity时,我必须获取WebView实例并为其注册一个新的WebviewIdlingResource。

我希望某人有一个没有任何这些缺点的解决方案。我希望espresso-web软件包可以提供解决方案,但它似乎没有提供与加载有关的任何内容。

2 个答案:

答案 0 :(得分:5)

正如您所提到的,有一个名为espresso-web的espresso插件,用于处理网页视图及其内容。

"完成加载"是一个模糊的概念。它将取决于您想要完成的

如果您使用的onWebView().check(<the you want to finish is in your webview>)仅在加载网络视图且check成功后才会返回。

  

Espresso-web是在Android上使用WebViews的切入点。它使用来自流行的WebDriver API的Atoms来内省和控制WebView的行为。

     

与onData类似,WebView交互实际上由几个View Atoms组成。 Atom可以看作是一个ViewAction,一个在UI中执行操作的自包含单元。但是,它们需要妥善编排,并且非常冗长。 Web和WebInteraction包装了这个样板,并提供了与WebViews交互的类似Espresso的感觉。

https://google.github.io/android-testing-support-library/docs/espresso/web/index.html

答案 1 :(得分:0)

如果Wait for it...a deep dive into Espresso's Idling Resources遇到的不可靠性是由于使用WebChromeClient引起的,请考虑改用WebViewClient

我发现,当网页完成加载后,WebViewClient会可靠地触发onPageFinished()WebChromeClientWebViewClient相似,但是WebViewClient更普遍,因为WebChromeClient处理WebView特定于Chrome的方面(请参见What's the difference between setWebViewClient vs. setWebChromeClient?)。

在示例项目https://github.com/mosofsky/how-to-coredux中,我将onPageFinished()函数注册到WebView如下:

playVideoWebView.webViewClient = object : WebViewClient() {
    override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
        return false
    }

    override fun onPageFinished(view: WebView?, url: String?) {
        if (null != url && url != ABOUT_URL) {
            // the next line dispatches an action that calls decrement()
            howToViewModel.dispatchAction(LoadVideo_Finish)
        }
    }
}

我希望这会有所帮助,尽管诚然我没有解决您提到的其他缺点。至于缺少getWebChromeClient()的问题,现在似乎可以解决。至于需要特定的WebView实例,我不知道如何避免。完成加载后,必须以某种方式使WebView减少空闲资源计数器。似乎任何解决方案都必须以某种方式触摸WebView的特定实例才能完成此注册过程。一些开发人员可能会觉得,CountingIdlingResourceincrement()decrement()的调用会浪费他们的生产代码。

为最大程度地减少空闲资源计数调用所检测的代码量,您可以将这些调用隔离为异步代码的“副作用”。为此,我发现使用Redux数据存储非常有用,例如CoRedux。当异步动作开始时,您可以将状态更新为“进行中”。当结束时,清除“进行中”标志。 “副作用”可以是侦听“进行中”的任何机制。 CoRedux确实具有可以使用的称为“副作用”的构造,但是任何响应状态更改的机制都可以。

how-to-coredux示例项目的副作用中,它像这样调用increment()decrement()

when (action) {

    is Initialize_Start, is ShowVideoFragment_Start, LoadVideo_Start, HideVideoFragment_Start -> {
        espressoTestIdlingResource.increment()
    }

    Initialize_Finish, ShowVideoFragment_Finish, LoadVideo_Finish, HideVideoFragment_Finish -> {
        espressoTestIdlingResource.decrement()
    }
}

通过将空闲资源逻辑隔离开来,副作用是,整个Android项目可以分别依赖于每次异步UI事件开始/结束时都调用increment() / decrement()的单个代码