测试基础 移动自动化 UI Hybrid-H5 之 Android 的 WebView 测试

刘大头 · May 25, 2017 · Last by 刘大头 replied at August 22, 2018 · 2406 hits
本帖已被设为精华帖!

移动自动化 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 的过程与大家分享一下,同时也希望和大家进行讨论、学习(毕竟第一次使用,会踩到不少坑,也肯定有许多不足。)

主要流程

主要分为以下两个步骤

  1. 获取到一个界面中 webview 下面的元素。
  2. 通过本地的 usb 方式用 python 编写一个 case,在该 case 下可以进行 NATIVE_APP 和 WEBVIEW 的切换。

获取 webview 下的元素

问题 1-->直接使用 uiautomatorviewer 获取不到

如图所示,想获取小红书中某一个商品详情页下面的加入购物车按钮,如果用 uiautomatorviewer,只能看到图中一个 webview 控件,对应左面的就是整体的部分,而我们期望得到的是 “加入购物车” 的内容。

如果想在 uiautomatorviewer 中看到下面的元素。
需要做一些额外的工作,具体怎么做我忘了,步骤比较烦。

问题 2-->如何远程调控调试 WebView

这个还是比较重要的一部分,但是新手一开始不知道怎么做,这里有一篇比较好的文章,希望大家可以认真读一下。
远程调试 Android 设备使用入门

如果你不想看原文,这里也可以看,不过非常建议看原文,原文有图。

要求

  1. 计算机上和 andriod 设备上已经安装了 Chrome。
  2. Andriod 的版本是 4.0 以上
  3. 将 android 设备和计算机通过 usb 连接。

第 1 步:发现您的 Android 设备

  1. 在您的 Android 设备上,选择 Settings > Developer Options > Enable USB Debugging。 在运行 Android 4.2 及更新版本的设备上,Developer options 默认情况下处于隐藏状态。 请参阅启用设备上的开发者选项以了解如何启用它。

发计算机上打开 Chrome。您应使用您的一个 Google 帐户登录到 Chrome。 远程调试在隐身模式或访客模式下无法运行。(结合下图一起看)

  1. 在 DevTools 中,点击 Main Menu 主菜单,然后选择 More tools > Remote devices。
  2. 在 DevTools 中,点击 Settings 标签(如果正在显示另一个标签)。
  3. 确保已启用 Discover USB devices。
  4. 如果您尚未在 Android 设备上打开 Chrome,则现在打开它。
  5. 返回 DevTools,点击与设备的型号名称匹配的标签。 在此页面的顶部,您会看到 Android 设备的型号名称,后面紧跟着其序列号。 在型号名称下面,您可以看到在设备上运行的 Chrome 的版本,版本号在括号里。每个打开的 Chrome 标签都会有自己的区域。您可以从此区域与该标签交互。 如果有任何使用 WebView 的应用,您也会看到针对每个应用的区域。
  6. 在 New tab 旁输入一个网址,然后点击 Open。此页面将在 Android 设备上的新标签中打开
  7. 点击您刚刚打开的网址旁的 Inspect。这将打开一个新的 DevTools 实例。 您的 Android 设备上运行的 Chrome 的版本决定在开发计算机上打开的 DevTools 的版本。因此,如果您的 Android 设备正在运行一个非常旧的 Chrome 版本,则 DevTools 实例看上去可能与您常用的实例有很大的差别。

最后的结果

最后我们就可以看正常网页一下调试这个网页了。

问题 3-->python 如何从 NATIVE_APP 切换到 WEBVIEW.****

在 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

问题 3-1-->按照如上方法,还是切换不到相应的环境怎么办?

我所遇到的问题大概存在以下几种情况:

  1. 你所调试的 app 中的一个开关打开,这非常重要!!!否则,你只能得到 NATIVE_APP

    setWebContentsDebuggingEnabled = True [这个需要找开发给你打包一个这个地方设置为 True 的包]

  2. 在形成一个 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

  3. 版本不对应,在实际的过程中,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。

问题 4 可以切换到 WEBVIEW 下,但是不能经常会遇到 No Such Session 问题

这个情况很复杂,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 怎么办?希望看到的兄弟姐妹能给个建议,一起讨论。

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 23 条回复 时间 点赞
刘大头 #1 · May 25, 2017 Author

请问怎么 对图片进行格式限制,中间的两张图片好大

刘大头 回复

参考 https://testerhome.com/markdown
用这样的语法

![](xxx.img =600x)
思寒_seveniruby 将本帖设为了精华贴 26 May 11:05

问一下 chrome 上点 inspect,不 *** 能出来?我看到的都是白的。

chen 回复

我的实践是第一次必须 ***~空白了半天后得出的教训。。。。

我到目前为止,测的都是 native 的。借这个帖子,我想问问大家,hybrid 的 H5 页面不就没有办法定位吗?难道每一位测试人员要测试 hybrid app 都得买个软件。

刘大头 #7 · May 27, 2017 Author
chen 回复

可是我并没有。我之前没有注意到这个问题,刚刚看你提了,我就关掉了,结果还是可以的。

刘大头 #8 · May 27, 2017 Author
莫离 回复

为什么需要 *** 呢,有什么原理在里面吗?

刘大头 回复

原理肯定没有,就是国内对外有墙。也其他人说第一次需要 ***,不知道你的为啥不用,我试了就是出不来

刘大头 #10 · May 27, 2017 Author
chen 回复

第一次的时候,我当时是开着代理的。刚刚是切了代理之后试的,完全没问题。想问一下你们现在移动自动化做的怎么样了,实际用的多吗?

刘大头 #11 · May 27, 2017 Author

非常感谢。

刘大头 回复

我自己是公司电脑和家里电脑开始都是空白的~ 然后在别的地方看到有人说这次第一次启动要访问一次谷歌的某个连接~ 导致第一次,于是后一切正常。

刘大头 #13 · May 27, 2017 Author
莫离 回复

那可能是我平时习惯开着代理,让我避免了这个坑,哈哈!

学习了

刘大头 #15 · May 31, 2017 Author

幸福的你

org.openqa.selenium.WebDriverException: An unknown server-side error occurred while processing the command. Original error: session not created exception: Chrome version must be >= 56.0.2884.0

(Driver info: chromedriver=2.29.461585 (0be2cd95f834e9ee7c46bcc7cf405b483f5ae83b),platform=Mac OS X 10.12.3 x86_64) (WARNING: The server did not provide any stacktrace information)

手机上下载了 59.0 的 Chrome,appium 用了 2.29 的 chromedriver,还是报错...

@haifengrundadi 你好,我用高版本的 chromedriver 就可以获取到 WEBVIEW 和 NATIVE 两个 context,但是降级到低版本的 chromedriver,只能获取到 NATIVE 的 context

测试例子选的图片不错😏

这个要吧?不都登陆不了

请问下,同时操作 在 webview 模式下,操作 native,应该 怎么做? 或者说怎么同时 在一个页面内获取 webview 和 native 元素?

主要是小红书上的姑娘们都很漂亮

qianjian yang 回复

这个我做的过程中,没有需要这样做,因而我也没有测试过。不过应该还是切换到 native 模式下。如果想同时获取 webview 和 native 元素,应该也要在获取其中一个下面做切换。

zhoufan 回复

不好意思,很久没看 testerhome 了。由于现在我没做这一块,当时也没有遇到这个问题,因而给不了好的建议。

笑哼 回复

事情过去很久了,有点忘记了哈。

需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up