很多 apk 会在原生的 app 中内嵌如 web 页面,以减小开发工作量,增加兼容性,所以当我们使用 appium 对此类 apk 进行自动化测试时,就不可避免的会遇到需要在原生应用和 h5 界面中进行切换的操作,下面对这一过程中遇到的问题分别从 android 应用和 ios 应用两个方面进行总结。

appium 如何切换 Native 和 WebView

方法一:

Set<String>contexts=driver.getContextHandles();
driver.context((String)contexts.toArray()[1]);  //选取webview开头的context

方法二(官方示例):

driver.getContextHandles().forEach((handle) -> {
                if (handle.contains("WEBVIEW")) {
                    driver.context(handle);
                }
            });

android 设备切换 Native 和 WebView 时遇到的问题

问题一:无法获取 webView 上下文

使用方法一获取 contexts 时,发现只能获取到原生的 context,不能获取到 WebView 的 context。如下:

经过在网上查找方法,发现 android4.4 以上需要开启 webView 的远程调试开关。方法如下:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        WebView.setWebContentsDebuggingEnabled(true);}

一般情况下 RD 会将上述开关设置在 apk 包中,作为一个 debug 的总开关,此时我们只需要找 RD 要一个开启 debug 模式的 aok 安装包就可以了。

问题二:ChromeDriver 版本问题

解决了 WebView 上下文的问题之后,以为就可以顺利运行了,没想到还是报错,内容如下:

错误内容是:Chrom version must be >=60.0.3112.0。提示我们谷歌浏览器的版本比较低。
看到这个提示的时候我也很疑惑,我也没有用到 Chrome,为什么会提示这样的错误呢?原因是 android 系统底层是通过 ChromeDriver 来调用 WebView 的。
所以上述错误的原因是因为 ChromeDriver 的版本不匹配导致。那么应该是什么和什么匹配,又应该如何匹配呢?
答案:
需要 android 系统的 Android Sysytem WebView 版本和 ChromeDriver 的版本相匹配。其中 Android Sysytem WebView 是指 android 系统的 web 应用,可以在手机上查看气其当前版本(如果在系统应用中找不到,可以在手机的应用市场上搜索)。
匹配规则如下:其中 “支持的 Chrome 版本” 就是指 Android Sysytem WebView 的版本
相同问题:https://testerhome.com/topics/8493
https://www.cnblogs.com/sao-fox/p/6396984.html
版本匹配:http://blog.csdn.net/cz9025/article/details/70160273

解决方法
既然知道了问题出现的原因,那么就有方法解决。解决方法如下:
查看当前 Android Sysytem WebView 的版本,下载对应的 ChromeDriver,放到如下目录 (mac):
/Applications/Appium 2.app/Contents/Resources/app/node_modules/appium/node_modules/appium-xcuitest-driver/

ios 设备切换 Native 和 WebView 时遇到的问题

问题一:无法获取 webView 上下文

在进行 ios 设备的上下文切换时,也出现了无法获取 WebView 的现象(同 android)。一开始也以为 ios 可以通过带代码中设置 webview 的 debug 开关来解决此问题,但是后来和几个 RD 沟通过后发现 ios 并没有类似的支持,所以只能另寻他法。
通过查看 log,发现 ios_webkit_debug_proxy 没有被调起,如果想要真机调试 WebView,就必须通过 ios_webkit_debug_proxy。
通过如下命令进行安装

brew install ios-webkit-debug-proxy

安装之后运行如下命令查看是否能够调起 ios-webkit-debug-proxy

ios_webkit_debug_proxy -c XXXXXXXXXX:27753 -d            XXXXXXXXXX表示设备UDID

运行上述命令发现报错如下:

Could not connect to lockdownd. Exiting.: Permission denied

通过查找资料,发现网上大部分的解决方案是执行如下命令:

sudo chmod -R 777 /var/db/lockdown/

但是,执行该命令之后还有可能出现其他问题,并且该命令只能在本期启动 ios-webkit-debug-proxy 时起作用,不能永久生效。
解决方案如下:

brew uninstall ideviceinstaller
brew uninstall libimobiledevice
brew install --HEAD libimobiledevice
brew link --overwrite libimobiledevice
brew install ideviceinstaller
brew link --overwrite ideviceinstaller

过程中如果出现失败的现象,可以根据 log 的提示进行处理。

问题二:appium 如何启动 ios-webkit-debug-proxy

经过上述处理,已经解决了 ios-webkit-debug-proxy 无法启动的问题,但是 appium 如何获取 WebView 上下文的问题仍然存在。
解决方法就是先启动 ios-webkit-debug-proxy,在调用 appium 的自动化脚本,就可以获取 WebView 了。
注意:ios 真机需要启动 web 检查器
位置:设置—》Safari—》高级—》web 检查器
注意:在获取 WebView 之前,最后先 Thread.sleep(1000) 几秒,保证 apk 中内嵌的 WKWebView 已经加载出来。
解决上述问题之后,如果直接运行测试脚本会报出如下错误:

是因为我没没有开启 ios-webkit-debug-proxy。而每次手动开启 ios-webkit-debug-proxy 是一件很麻烦的事情,我们作自动化的目的就是解放双手嘛。
后来阅读了官方的解释之后,发现 ios-webkit-debug-proxy 可以通过设置 DesiredCapabilities 来调起,代码如下:

cap.setCapability("startIWDP",true); 

好啦,至此,我的 ios 设备和 android 设备都能够完美兼容 WebView 啦


↙↙↙阅读原文可查看相关链接,并与作者交流