Appium 自动化测试的学习

Appium 是什么

Appium 是一款用于测试 Mobile App 的开源自动化测试框架。它是通过使用 WebDriver[Facebook开源] 协议来测试 iOS,Android,Windows App 的。WebDriver 与 Selenium 有着千丝万缕的联系,很多方法的使用都很相似。

Appium 支持多种语言。

  1. Ruby
  2. Python
  3. Java
  4. JavaScript
  5. PHP
  6. C#
  7. Objective-C

根据先后顺序,官方的支持力度也不同。Ruby 官方支持的最好(Appium console 就是使用 Ruby 开发的)。

Appium iOS 测试环境搭建方法

Appium 分为 UI 版本与命令行版本两种。不同在于 UI 版本的自带有图形界面,用户体验相对于命令行版本好。

常见依赖库的搭建

  1. 安装 libimobiledevice

    brew install libimobiledevice --HEAD
    npm install -g ios-deploy #如果是iOS10以上的系统才需要安装
    
  2. 安装 appium-doctor

    npm install appium-doctor -g
    appium-doctor --ios // appium-doctor 安装完成后执行,查看 iOS 相关配置是否成功。如果存在红叉情况,安装对应的工具就可以了。
    
    ![appium_doctor_test.png](https://upload-images.jianshu.io/upload_images/2159939-f8cbccea99fc3bda.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
  3. 下载 WebDriverAgent

    • 进入下载后的 WebDriverAgent 文件夹

    • 执行 ./Scripts/bootstrap.sh

    • 直接用Xcode打开 WebDriverAgent.xcodepro 文件

    • 配置WebDriverAgentLibWebDriverAgentRunner的证书

      Appium 自动化测试的学习_第1张图片
      SignAgentRunner1.png

      Appium 自动化测试的学习_第2张图片
      SignAgentRunner2.png
      Appium 自动化测试的学习_第3张图片
      SignAgentRunner3.png
    • 连接并选择自己的iOS设备,然后按Cmd+U,或是点击Product->Test

    • 运行成功时,在Xcode控制台应该可以打印出一个Ip地址和端口号

命令行版本的搭建

  1. 安装 Appium

    npm install -g appium # get appium
    npm install wd # get appium client
    appium & # start appium
    
  2. 替换 WebDriverAgent

    使用上面修改过的 WebDriverAgent 替换/usr/local/lib/node_modules/appium/node_modules/appium-xcuitest-driver 此处的WebDriverAgent

UI 版本的搭建

  1. 下载Appium Desktop

  2. 替换 WebDriverAgent

    使用上面修改过的 WebDriverAgent 替换/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/appium-xcuitest-driver/ 此处的WebDriverAgent

开发环境搭建

  1. 安装 Appium Python 环境搭建

    brew install python
    git clone [email protected]:appium/python-client.git
    cd python-client
    python setup.py install
    

安装 Appium 的时候遇到的错误

  1. 未能载入软件包“WebDriverAgentRunner”,因为它已损坏或丢失必要的资源。 请尝试

    Go to TARGETS -> WebDriverAgentRunner -> Build Phases ->   Copy frameworks
    Add RoutingHTTPServer.framework
    
  2. AssertionError: Message: An unknown server-side error occurred while processing the command. Original error: Unknown device or simulator UDID: '*'

    brew install libimobiledevice --HEAD
    
  3. Could not initialize ios-deploy make sure it is installed (npm install -g ios-deploy) and works on your system

    npm install -g ios-deploy
    
  4. npm install -g ios-deploy 失败问题的解决方法

    sudo npm install -g ios-deploy --unsafe-perm=true
    

Appium 使用

Appium-Desktop 的使用

  1. 准备一个 ipa 或者 app 包。

  2. 运行Appium-Desktop

  3. 开启start server

    Appium 自动化测试的学习_第4张图片
    Appium_start_server.png
  4. 点击start new session

    Appium 自动化测试的学习_第5张图片
    Appium_start_session.png
  5. 在 Desired Capabilities 中输入相关的参数后点击Start Session

    Appium 自动化测试的学习_第6张图片
    Appium_Capabilitie_Input.png
  6. 运行成功后,会弹出一个控制界面,在该界面中可以控制手机上正在运行的程序

  7. 点击界面上方中心的录制按钮,可以将你对手机端的操作代码化。生成的代码可以直接放入指定的代码中去执行。

    Appium 自动化测试的学习_第7张图片
    Appium_Record_Input.png
  8. 在 UI 界面上我们可以查看App UI 层次结构,可以选择对应的控件。可以查看选中的 UI 控件的各种值(下图右下角所示),也可以对选中的空间进行点击,输入值,清空值操作

    Appium 自动化测试的学习_第8张图片
    Appium_Record_Operation.png
  1. 如上图所示。我们还可以针对需要使用坐标系统(不通用。因为不同的设备分辨率不同)点击,手势操作等。

关于在代码中如何使用 Appium

本例中使用 Python 为主要部分。

  1. 连接 Appium

    path = "/Users/jack/Desktop/xx/xx/xx.ipa"
    desired_caps = {
        'app': os.path.abspath(path),
        'platformName': 'iOS',
        'platformVersion': '11.2.2',
        'deviceName': 'iPad',
        'udid': 'xxx',
        'showIOSLog': 'true'
    }
    command_executor = 'http://127.0.0.1:4723/wd/hub'
    appium_driver = webdriver.Remote(command_executor=command_executor,     desired_capabilities=desired_caps)
    ```
    
    **appium_driver** 就是我们需要的接入点。
    
    
  2. 获取当前页面层次结构。

    page_source = appium_driver.page_source
    

    page_source 是 XML 文本。例子解析 XML 之后就可以看到整个页面的布局。
    注意: 论坛中有说过当页面数据过多的时候,可能会出现超时错误问题。

  3. 查找指定的 UI 元素

    查找 UI 元素的方式有很多种。

    • AccessibilityIdentifier 方式查找。推荐

      element = driver.find_element_by_accessibility_id(ele_id)
      
    • AccessibilityIdentifier 方式查找。不推荐,但是必须的时候还是要用

      element = driver.find_element_by_xpath(xpath)
      
  4. 获取查找到的控件的值

    text = element.text # 获取 element 在页面上的显示数据。如果是输入框的话,一般包括 Placeholder
    att = element.get_attribute(attribute) # 根据属性名查找对应属性的值
    
  5. 已经查找到的控件点击输入值清空值操作。

    element.send_keys(last) # 输入值
    element.clear() # 清空值
    element.click() # 点击
    
  6. 长按操作。

  7. 简单的手势滑动操作。

    window_size = driver.get_window_size()
    width = window_size.get("width")
    height = window_size.get("height")
    driver.swipe(width / 2, height / 4, width / 2, height * 3 / 4, 500)
    
  8. 等待页面消失

    try:
    # 在 60s 每隔 0.5s 检查是否 view 消失
        WebDriverWait(driver, 60, 0.5, ElementNotVisibleException).until_not(lambda x: x.find_element_by_accessibility_id(view).is_displayed())
    except TimeoutException, e:
        print("time out message")
        raise e
    
  9. 等待页面出现

    try:
    # 在 60s 每隔 0.5s 检查是否 view 出现
        WebDriverWait(driver, 60, 0.5, ElementNotVisibleException).until(lambda x: x.find_element_by_accessibility_id(view).is_displayed())
    except TimeoutException, e:
        print("time out message")
        raise e
    

iOS 设备获取对应的控件的方法

对于 iOS 端,WebDriver 使用了苹果提供的 Accessibility Inspector 来获取页面层次。因此,在编写代码的时候,需要设置
iOS 代码使用 Appium 建议条件满足 isAccessibilityElement 为 true。同时 accessibilityIdentifier 建议有值。这样查找的时候在编写代码会更加便捷。否则就需要如下的方式去查找:

driver.find_element_by_xpath("//XCUIElementTypeApplication[@name=\"LLL\"]/XCUIElementTypeWindow[1]/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeCollectionView/XCUIElementTypeCell")

上面的代码是去查找一个 tableview cell。当然我们可以使用 UI 工具获取到。但是当页面 ui 层次变更了,估计改动的时候会有想死的感觉了。

iOS 设备使用 Appium 的条件

  1. 运行 Mac 系统的电脑。
  2. 提供一个可以安装到真机上的 ipa 或者 app 包。
  3. Mac 系统建议安装 Xcode 环境。

iOS 设备使用 Appium 的限制

  1. 同一台电脑只能运行一个测试实例(没有研究出来多个测试)

  2. 测试 case 编写者必须清楚的知道自己在找什么,需要到哪里去找。

    Appium 只能针对已知的数据进行测试。对于未知的数据无法进行测试。例如:服务器端更新 server 的数据而没有通知 app 端。app 端仍然按照旧的数据去测试判断,就会出现错误。而这种错误不是 app 本身的错误。而由人测试的时候这里就会有主管判断为什么出现这种问题,中断去查找问题来源。

  3. 测试速度慢。目前来看可以接受

  4. 每次测试的时候都是重新安装 app。因此无法进行升级类的测试[对应的 install、uninstall api 不可用]

  5. 快速点击操作不可用,个别因为用户手速过快点击导致的问题会无法测试。因为Appium API 时延比较高。

  6. 设备横屏(在 iPad 上测试)的时候无法进行测试

  7. Scrollview/TableView/CollectionView 滚动的问题(swap 手势模拟有的时候很慢。一分钟都没反应完)。

  8. 关于通知推送,点击没有查到对应的测试资料。

  9. 内嵌,外部跳转 web 页面的测试没有验证过。

  10. Crash Log 以及运行时候的 log(设备的)无法收集。

  11. Emoji 表情输入没研究出来。目前看只能通过键盘点击达到这个效果,但是不方便。

  12. 因为时延较高,查找类页面在输入值的时候,应该清空页面显示,然后根据返回值显示。这部分不好测试。容易出现纰漏。

关于测试结果反馈

Appium 只是一款测试 Mobile 端 app 的框架。其本身的操作仅限于针对 App 进行测试,不具备生成测试结果,发送邮件等功能。如果想要该功能,需要在调用 Appium 的语言环境上思考。

由于 Demo 中使用的是 Python,因此使用 HTMLTestRunner 生成 html 格式的测试报告是最合适的方式。并且根据 Python 编程发送邮件给指定的用户。

  1. 在 case 中。如果断言错误,即已知结果不是想要的结果,可以使用断言使测试生成断言错误。这样就可以生成失败的测试 case 报告。
  2. 出现 Error 的时候有可能是由于 Python 代码本身不严谨造成的错误。因此当有 Error 错误的时候,首先考虑是否是 Python 代码的问题,其次考虑 App 错误。
  3. 没有错误,测试成功。

我研究 Appium 测试遇到的问题

可以解决的问题

  1. 当只显示服务器端数据的时候,本地测试可以通过 api 获取服务器端的数据进行测试。但是如果包含有离线数据的时候,不清楚应该怎么测试。

    解决方法:初步的想法是本地有特殊图标,并且本地缓存数据前置显示。这样可以根据特殊图标来查看是否有本地缓存数据。
    
  2. 二维码扫描(可以测试,但是需要固定)

  3. selection image、take photo 测试困难。原因在于 Apple 并没有对外暴漏页面层次

    解决方法:(需要使用 tap 坐标系的方法进行测试)。不同的设备坐标确定困难。
    
  4. 有的时候Appium 会因为线程通信问题自己崩溃。

    解决方法:每次进行通信的时候尽可能的等待 1s 左右。特别是跨页面跳转的时候。
    
  5. 关于验证码等测试的问题。

    解决方法:针对测试环境,需要服务器端提供对应的接口去获取验证码。
    
  6. 真机上如果使用企业证书签名的时候,需要手动信任证书。

    解决方法:提前下载一个 app,并设置证书信任
    
  7. iPad 上键盘收起操作 hide_keyboard 是可以使用的。但是在 iPhone 上不可用,因为原生没有提供对应的按键。

    解决方法:使用第三方框架,在键盘上添加 tool,可以使用 tool 上的 button 时间收起键盘。
    
  8. 有 placeholder 的时候,Field 和 TextView 获取到的值需要对 placeholder 做判断。

  9. 排序问题。

    解决方案:可以通过 page_source 函数获取到整个页面的层次。再根据层次上显示的数据进行分析排序问题。
    

    只能解决排序条件已经显式展现的 cell。隐形排序任然需要编写代码的人员在排序的时候就知道所有的序列,然后采用上述办法分析结果

  10. ScrollView 达到了顶端,底端

    操作步骤同上。通过分析 page_source 来判断第一个与最后一个元素
    
  11. 不可以断网测试[https://github.com/appium/appium/issues/8486]

    模拟手势上划,在 setting 页面上关闭、开启网络后,再下滑。
    

    driver.background_app(60) 进入后台 60s 后,操作 setting 页面达到断网。无法实现

  12. 有的时候打开外界 app 后再返回测试比较困难。只能在页面上点击坐标的方式进行测试。不好控制

关于 Python 环境的使用。

Python 环境下测试报告的生成问题。

Python 提供了 HTMLTestRunner 框架可以用于生成 HTML 报告。

安装HTMLTestRunner

  1. 下载 HTMLTestRunner.py 文件。中文HTMLTestRunner.py
  2. 拷贝文件到 python 安装路径下的 lib [/System/Library/Frameworks/Python.framework/Versions/2.7/lib/] 文件夹中。

之后测试文件中加入:

if __name__ == '__main__':
  suite = unittest.TestLoader().loadTestsFromTestCase(testCaseClassName) #定义一个单元测试容器
  filename = "./xxx.html" #定义个报告存放路径,支持相对路径
  f = file(filename,'wb') #结果写入HTML 文件
  runner = HTMLTestRunner.HTMLTestRunner(stream = f,title ='Report_title',description='Report_description',verbosity = 2) #使用HTMLTestRunner配置参数,输出报告路径、报告标题、描述
  runner.run(suite)

HTMLTestRunner 的 HTMLTestRunner 方法 跟 unittest.TextTestRunner 方法 一样,支持测试结果信息的收集。如下:

runner = HTMLTestRunner.HTMLTestRunner(stream = f,title ='Report_title',description='Report_description') #使用HTMLTestRunner配置参数,输出报告路径、报告标题、描述
result = runner.run(suite)
result.testsRun #运行测试用例的总数
result.success_count #运行成功的数目
result.failure_count #运行失败的数目
result.error_count #运行错误的数目

关于 Python 的错误记录

  1. python 怎么查看api文档呢?

    å首先打开命令行,输入:

    python -m pydoc -p 4895
    # python -m pydoc -- 打开pydoc模块
    # -p 4895 -- 在4895端口上启动server;
    

    在浏览器打开 http://localhost:4895/ 就可以查看python的所有modules.

  2. SyntaxError: Non-ASCII character '\xe7' in file CodeMakerTest.py on line 24, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

    在脚本文件(第一行)添加

    #coding:utf-8
    
  3. Python 关于 Emoji 表情的处理。

    Python 对于 Emoji 表情的支持不是很好。需要安装 emoji 工具包支持 Emoji。

参考页面

  1. Appium 官方网站
  2. Appium Github 官方
  3. Appium移动自动化测试系列
  4. 从0到1搭建移动App功能自动化测试平台系列
  5. python appium UI 自动化测试框架讨论
  6. appium+python自动化实践之查找元素的等待方式
  7. Python Logging 使用
  8. Log 收集1 Log 收集2

你可能感兴趣的:(Appium 自动化测试的学习)