移动自动化 UI Hybrid-H5 之 Android 的 WebView 测试
Author:Juan Liu(XiaoHongshu Intern) Date: 2017/05/05
小红薯移动 UI 自动化框架 Cartier 开发完成了主要功能的之后,QA 团队想尝试利用之前编写的 UI 自动化框架 Cartier 做一些固定流程的自动化(之前的流程是 NATIVE),在做的过程中一些流程会涉及到关于 WebView(H5)的控件获取、事件的产生和页面。这也是我第一次接触到这个混合的自动化,因此,下面把自己如何一步一步去写一个 Python 的 Hybrid case 的过程与大家分享一下,同时也希望和大家进行讨论、学习(毕竟第一次使用,会踩到不少坑,也肯定有许多不足。)
主要分为以下两个步骤
如图所示,想获取小红书中某一个商品详情页下面的加入购物车按钮,如果用 uiautomatorviewer,只能看到图中一个 webview 控件,对应左面的就是整体的部分,而我们期望得到的是 “加入购物车” 的内容。
如果想在 uiautomatorviewer 中看到下面的元素。
需要做一些额外的工作,具体怎么做我忘了,步骤比较烦。
这个还是比较重要的一部分,但是新手一开始不知道怎么做,这里有一篇比较好的文章,希望大家可以认真读一下。
远程调试 Android 设备使用入门
如果你不想看原文,这里也可以看,不过非常建议看原文,原文有图。
要求
第 1 步:发现您的 Android 设备
发计算机上打开 Chrome。您应使用您的一个 Google 帐户登录到 Chrome。 远程调试在隐身模式或访客模式下无法运行。(结合下图一起看)
最后的结果
最后我们就可以看正常网页一下调试这个网页了。
在 APPIUM hybird 的官网上,看到如下 Python 代码。如果,你实际上在代码中使用是不可以的(这可能是伪代码?),需要自己进行去看 Selenium 的方法。
但是官网给的步骤是和规范的,第一步,获取你想切换到的环境(WEBVIEW 开头的)。第二步,使用 driver 的 switch_to 方法进行切换。第三步,获取所要的元素,并操作。
# python
# assuming we have an initialized `driver` object for an app
# switch to webview
webview = driver.contexts.last
driver.switch_to.context(webview)
# do some webby stuff
driver.find_element(:css, ".green_button").click
# switch back to native view
driver.switch_to.context(driver.contexts.first)
# do more native testing if we want
driver.quit()
我自己简单改写的代码。
def switch_context(driver, context=u"WEBVIEW_***"):
"""
1:环境不同,Native->To->Webview or Webview->to->Native
2:如果环境相同则不切换
"""
contexts = driver.contexts
if context in contexts:
logger.info(u"切换到相应的环境下面")
driver.switch_to.context(context)
return True
else:
logger.error(u"没有切换到相应的环境下面,当前的环境为" + str(driver.context))
return False
我所遇到的问题大概存在以下几种情况:
你所调试的 app 中的一个开关打开,这非常重要!!!否则,你只能得到 NATIVE_APP
setWebContentsDebuggingEnabled = True [这个需要找开发给你打包一个这个地方设置为 True 的包]
在形成一个 Des 的时候要设置 recreateChromeDriverSessions 为 true
@pytest.fixture(scope="session")
def desired_one_cap(request):
"""用于测试手机的效果"""
desired_caps = {}
desired_caps['platformName'] = 'Android'
desired_caps['platformVersion'] = '5.0'
desired_caps['app'] = '...'
desired_caps['deviceName'] = '....'
desired_caps['newCommandTimeout'] = 120
desired_caps['unicodeKeyboard'] = True
desired_caps['resetKeyboard'] = True
desired_caps['noReset'] = False
desired_caps['recreateChromeDriverSessions'] = True
return desired_caps
版本不对应,在实际的过程中,chromedirver 和 chrome 是有对应的。
chromedriver 版本 | 支持的 Chrome 版本 |
---|---|
v2.29 | v56-58 |
v2.28 | v55-57 |
v2.27 | v54-56 |
v2.26 | v53-55 |
v2.25 | v53-55 |
v2.24 | v52-54 |
v2.23 | v51-53 |
v2.22 | v49-52 |
v2.21 | v46-50 |
v2.20 | v43-48 |
v2.19 | v43-47 |
v2.18 | v43-46 |
v2.17 | v42-43 |
如果版本不对应,则需要进行相应的对应。这里基本的方法就是修改 appium 中原有的 chromedriver。
这个情况很复杂,Appium 官网也有解决方法。
这里我给出我解决的方法。
我的设备情况,可以从前面看到。我手机上的 Chrome 是 V52,计算机是 64 位的 58.0.3029.110 (64-bit)。
由于官网上和百度到的所有并没有解决我的问题,我就仔细读了 Appium 上所有的代码,最后发现是因为,早早地把 proxy 关了。
个人理解的原理是: 从 NATIVE 到 WEBVIEW 的过程中,会和原来的 session 不一致,这个时候 appium 会启动一个转换机制,这样在 NATIVE 和 WEBVIEW 环境下都可以拥有自己的 session。但是 appium 最后只认可一个(NATIVE)。
一旦这个转换机制早早地关了,就会导致一个 session appium 不认可。这个时候,如果在用这个 session 去作一些动作,显然会出现 NO SUCH SESSION 的问题。
解决方法:
降级 APPIUM 中的 Chromedriver
这个我查的时候,官网给出的是升级,因为对许多版本,协议没有非常清楚,最后只能降级试试,反而成功解决了。可能还是对应的问题。
遇到问题,可以去 google,appium 和 stackoverflow 上查一下,国内的话,testerhome 上还是有不少好的学习资料。
Hybird 自动化测试,随着 H5 的继续发展,肯定也会得到各个公司的认可。
感觉自己在再闭门造车,想知道实际中各个公司,遇到 hybrid 怎么办?希望看到的兄弟姐妹能给个建议,一起讨论。