是否有一种可靠的方法让Espresso等待WebViews完成加载?
我已经尝试了here概述的方法,但发现它不可靠。它还有其他缺点:
我希望某人有一个没有任何这些缺点的解决方案。我希望espresso-web软件包可以提供解决方案,但它似乎没有提供与加载有关的任何内容。
答案 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()
。 WebChromeClient
和WebViewClient
相似,但是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的特定实例才能完成此注册过程。一些开发人员可能会觉得,CountingIdlingResource
对increment()
和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()
的单个代码