用户端app自动化测试(iOS)-L3

一、Xcode 基础使用

1、Xcode 安装

2、 模拟器安装 App

模拟器运行:

3、 查看应用的 bundleID

  • BundleID 概念:一个应用的唯一标识

4、 查看应用路径

提取app:

5、 扩展

  • 苹果的开发者需要开发者证书,才可以将开发的 app 发布到 AppStore
    • 开发证书, 开发证书用于真机调试
    • 发布证书, 发布证书用于提交到 appStore

6、 真机运行

  • 所以如果想用 Xcode 运行 App 到真机上,要满足几个条件:
    • 成为 Apple Developer 计划的成员
    • 需要设置认证书和应用 ID(开发证书和发布证书)

二、iOS 自动化测试环境安装

1、 硬件环境

  • Mac 系统电脑
  • iOS 系统手机或模拟器

2、 软件环境

  • Xcode
  • 依赖工具(libimobiledevice,WDA,ideviceinstaller 等)
  • 被测应用

3、 依赖工具

工具名 描述
libimobiledevice 跨平台的软件协议库和工具,用来支持 iphone 等苹果设备的协议
ideviceinstaller 命令行工具,用于管理 iOS 设备上应用程序的安装、卸载、升级等,也可以查看 app 相关的信息
Carthage 是一个 iOS 项目依赖管理工具,可以很方便的管理三方依赖,WDA 使用这个工具管理项目依赖
ios-deploy 终端安装和调试 iPhone 应用的第三方开源库
ios-webkit-debug-proxy 通过 websocket 连接代理来自 usbmuxd 守护进程的请求,允许开发人员在真实和模拟的 iOS 设备上向 MobileSafari 和 UIWebViews 发送命令,appium 依赖此工具进行 webview 控件的操作

4、 依赖安装

# libimobiledevice 是一个跨平台的软件库,可以管理已安装应用,获取通讯录、日程、备注和书签等信息
brew install --HEAD libimobiledevice
# ideviceinstaller 是一个命令行工具,主要用于管理iOS设备上应用程序的安装与卸载,以及查看相关信息
brew install ideviceinstaller
# WDA 依赖
brew install carthage
# 是一个终端安装和调试iPhone应用的第三方开源库
brew install ios-deploy
# 又名 iwdp,通过websocket连接代理来自usbmuxd守护进程的请求,允许开发人员在真实和模拟的iOS设备上向MobileSafari和UIWebViews发送命令,appium 依赖此工具进行webview控件的操作
brew install ios-webkit-debug-proxy

三、iOS 自动化相关工具

1、 常用命令

  • 查看设备
  • 启动模拟器
  • 安装应用
  • 卸载应用
  • 查看应用 bundleID

2、 介绍

  • 操作模拟器命令:xcrun simctl
  • 操作真机命令:idevice<xxx>

3、 查看设备

  • 查看模拟器列表
  • 查看真机设备列表
# 查看已安装的模拟器
xcrun simctl list devices

# 查看已经开机的模拟器
xcrun simctl list devices |grep Booted

# 查看已连接的真机设备的 udid 信息
idevice_id -l

4、 启动模拟器

  • 启动模拟器命令:
  • xcrun simctl boot <device>
# 查看 模拟器列表
xcrun simctl list devices
# 启动模拟器
xcrun simctl boot 模拟器id

5、 安装应用

  • 模拟器安装应用
  • 真机安装应用
# 模拟器安装应用
## 单设备
xcrun simctl install booted demo.app
## 多设备
xcrun simctl install <device> demo.app

# 真机安装应用
ideviceinstaller --install </path/to/file/xxx.app>
ideviceinstaller -i </path/to/file/xxx.app>

6、 卸载应用

  • 模拟器卸载应用
  • 真机卸载应用
# 模拟器卸载应用
xcrun simctl uninstall <device> <bundleID>

# 真机卸载应用
ideviceinstaller --uninstall <appid>
ideviceinstaller -U <appid>

7、 查看应用的 bundleid

  • 模拟器查看应用 bundleid
    • 找到 app 的安装包
    • 右键点击
    • 显示包内容
    • 找到 Info.plist 文件
    • 双击打开,就可以找到对应的 Bundle identifier
  • 真机查看应用的 bundleid : ideviceinstaller -l

8、 总结

  • 模拟器使用xcrun simctl命令来操作,比如启动模拟器,安装应用,卸载应用等,真机使用 idevice_xxxx 来操作。
  • 可以通过命令来完成很多事情,比如:查看设备、启动模拟器、安装应用、卸载应用、截图命令、查看应用 bundleID 等。

四、iOS 元素定位

1、 页面结构分析

  • 启动 Appium Server Version: 1.22.0
  • Inspector App Version: 2021.12.2
  • 配置 Desire Capability
{
  "platformName": "iOS",
  "platformVersion": "15.2",
  "deviceName": "iPhone 13 Pro",
  "automationName": "XCUITest",
  "app": "/path/to/appfile/UIKitCatalog.app"
}

2、 定位表达式结构

  • iOS Predicate String 定位表达式结构:属性+运算符+值
# == 运算符:属性label 的值 与 字符串 "SYSTEM (TEXT)"相等
label == "SYSTEM (TEXT)"

# AND 运算符:同时满足多个条件
label == "SYSTEM (TEXT)" AND enabled == true

3、 元素属性

属性名 属性值
type 元素类型,等同于 className
name 元素的文本内容,可用作 AccessibilityId 定位方式
label 绝大多数情况下,与 name 一致
enabled 元素是否可点击,一般为 true 或 false
visible 元素是否可见,一般为 true 或 false

4、 运算符

运算符名 运算符 描述 举例
比较运算符 ==>=<=><!=<> 可用来比较数值或字符串 如:name>=128
name == ‘霍格沃兹’
范围运算符 IN,BETWEEN 可用于数值和字符串的范围核对 如:name BETWEEN {1,5}
name IN {‘hogwarts’,‘appium’}
字符串相关的运算符 CONTAINSBEGINSWITHENDSWITH 可用于字符串运算,包含,以某个字符开头,以某个字符结尾 包含某个字符串,如:label CONTAINS ‘测试’
逻辑运算符 ANDORNOTAND 当需要使用多个条件时,可以用逻辑运算符 如:label == "SYSTEM (TEXT)" AND enabled == true
模糊匹配 LIKE ?匹配一个字符,*匹配多个字符 如:label LIKE 'SYSTEM?TEXT?'
正则表达式 MATCHES 可以使用正则表达式 如:label MATCHES '^h.+兹

5、比较运算符

  • 常用的比较运算符:==>=<=><!=<>
    • 可用来比较数值或字符串
label == "SYSTEM (TEXT)"
label != "SYSTEM (TEXT)"

6、范围运算符

  • 常用的范围运算符:IN,BETWEEN
    • 可用于数值和字符串的范围核对
# 关键字 IN 用于字符串范围比对
label IN {'SYSTEM (TEXT + SYMBOL)','appium'}

# 关键字 BETWWEN 用于数值范围比对
name BETWEEN {1,5}

7、逻辑运算符

  • 常用的逻辑运算符:ANDORNOT
    • 逻辑与:AND(等同于&&
    • 逻辑或:OR(等同于||
    • 逻辑非:NOT(等同于!
label == "SYSTEM (TEXT)" AND enabled == true
label == "SYSTEM (TEXT)" OR name == "SYSTEM (TEXT)"
label == "SYSTEM (TEXT)" && NOT enabled != true

8、模糊匹配 LIKE

  • 模糊匹配使用 LIKE 关键字
    • ? 和 * 都可以作为通配符
    • ?匹配一个字符
    • *匹配多个字符。
label LIKE "SYSTEM (TEXT)"
label LIKE "?YSTEM (TEXT)"
label LIKE "SYSTEM??TEXT)"
label LIKE "* (TEXT)"
label LIKE "SYSTEM*"

9、字符串运算

  • CONTAINS 字符包含
  • BEGINSWITH 以某个字符开头
  • ENDSWITH 以某个字符结尾
# 匹配属性为 label ,value包含 TEXT 结尾的元素
label CONTAINS "TEXT"
# 匹配属性为 label ,value为 SYSTEM 开头的元素
label BEGINSWITH "SYSTEM"
# 匹配属性为 label ,value为 (TEXT) 结尾的元素
label ENDSWITH "(TEXT)"

10、正则表达式

  • 使用正则表达式匹配想要的内容
# 匹配 IMAGE 项
label MATCHES '^I.+E$'

11、总结

  • iOS 中常用元素定位器 predicate string
  • predicate String的定位表达式格式【属性+运算符+ 值】
  • 属性包括 type,name,label,enable,visible
  • 运算符分很多种,比如:比较运算符,范围运算符,逻辑运算符,模糊匹配,正则匹配等等
  • 值就是预期值

五、iOS 模拟器自动化测试

1、WebDriverAgent 简介

  • 简称 WDA。它是由 Facebook 推出的一款移动端测试框架。
  • Xcode8 移除 UIAutomation ,使用 WebDriverAgent

2、WebDriverAgent 工作原理

3、WDA 安装

  • Appium >=1.22 自动编译安装 WebDriverAgent 到 iOS 设备
# 一般 Appium 自带的 WebDriverAgent 目录为
/Applications/Appium.app/Contents/\
  Resources/app/node_modules/appium/\
  node_modules/appium-webdriveragent```

---

## Appium 的 Capability 设置

| Capability name | value         | describe      |
| --------------- | ------------- | ------------- |
| platformName    | iOS           | 操作系统      |
| platformVersion | 11.3          | 系统版本      |
| deviceName      | iPhone 11 Pro | 设备名        |
| automationName  | XCUITest      | 工作引擎名字  |
| app             | demo.ipa      | apk/.ipa 路径 |
|                 |               |               |

```python
{
  "platformName": "iOS",
  "platformVersion": "15.2",
  "deviceName": "iPhone 13 Pro",
  "automationName": "XCUITest",
  "app": "/path/to/app/UICatalog.app",
}

4、日志分析

# appium 使用的 app 路径,也就是 Capability 里的 app 参数内容
[BaseDriver] Using local app '/Users/jaxon/Library/Developer/Xcode/DerivedData/UICatalog-gtrrtpstbyqplpfjswetykmbzsgz/Build/Products/Debug-iphonesimulator/UICatalog.app'
# Appium 使用 WebDriverAgent 的路径
Using WDA path: '/Users/jaxon/.nvm/versions/node/v16.13.0/lib/node_modules/appium/node_modules/appium-webdriveragent'
# appium 开始编译 WebDriverAgent
[debug] [WebDriverAgent] Beginning test with command 'xcodebuild build-for-testing test-without-building -project /Users/jaxon/.nvm/versions/node/v16.13.0/lib/node_modules/appium/node_modules/appium-webdriveragent/WebDriverAgent.xcodeproj -scheme WebDriverAgentRunner -destination id=75C3F174-DE09-4419-9948-9BF9104D5DFC IPHONEOS_DEPLOYMENT_TARGET=15.2 GCC_TREAT_WARNINGS_AS_ERRORS=0 COMPILER_INDEX_STORE_ENABLE=NO' in directory '/Users/jaxon/.nvm/versions/node/v16.13.0/lib/node_modules/appium/node_modules/appium-webdriveragent'
# Appium 等待 WebDriverAgent 启动成功
Got derived data root: '/Users/jaxon/Library/Developer/Xcode/DerivedData/WebDriverAgent-bhlyxxersdxpchdjvevjzspftqnx'
[debug] [WD Proxy] Matched '/status' to command name 'getStatus'
[debug] [WD Proxy] Proxying [GET /status] to [GET http://127.0.0.1:8100/status] with no body

5、验证启动成功

{
  "value": {
    "message": "WebDriverAgent is ready to accept commands",
    "state": "success",
    "os": {
      "testmanagerdVersion": 28,
      "name": "iOS",
      "sdkVersion": "15.2",
      "version": "15.2"
    },
    "ios": {
      "simulatorVersion": "15.2",
      "ip": "10.1.1.217"
    },
    "ready": true,
    "build": {
      "upgradedAt": "1635853789278",
      "time": "Mar 17 2022 14:28:41",
      "productBundleIdentifier": "com.facebook.WebDriverAgentRunner"
    }
  }
}

六、iOS 真机自动化测试

1、连接真机

  • 使用 USB 线
  • 真机需要连接网络(验证证书)

2、安装应用

  • 方法一:build 应用到手机上
    • 信任证书:设置->通用->设备管理->信任开发者证书
  • 方法二:ideviceinstaller –install/-i xx.app

3、配置 capability-未安装应用

{
  "platformName": "iOS",
  "platformVersion": "15.2",
  "automationName": "XCUITest",
  "deviceName": "iPhone",
  "udid": "设备UDID",
  "app": "/path/to/app/UICatalog.app",
  "xcodeOrgId": "xxxxxx",
  "xcodeSigningId": "iPhone Developer"
}

4、配置 capability-已安装应用

{
  "platformName": "iOS",
  "platformVersion": "15.2",
  "automationName": "XCUITest",
  "deviceName": "iPhone",
  "udid": "设备UDID",
  "bundleId": "com.example.apple-samplecode.UICatalog",
  "xcodeOrgId": "xxxxx",
  "xcodeSigningId": "iPhone Developer"
}

5、使用 Appium Desktop 验证环境

6、相关问题和解决方法

  • 问题1:appium inspector 启动 session 的时候,报错,提示没有相应的模拟器设备
  • 解决1:设置真机的 Desired Capability 没有设置 udid
Failed to create session. An unknown \
  server-side error occurred while processing \
  the command. Original error: '14.2' does not \
  exist in the list of simctl SDKs. Only the \
  following Simulator SDK versions are \
  available on your system: 13.3, 6.1, 15.2, 8.3
  • 问题2:appium inspector 启动 session 的时候,报错,提示应用不被认可,
  • 解决2:因为设置的是模拟器的 app 路径 , 要设置真机 build 出来的 app 路径
Error
Failed to create session. An unknown \
  server-side error occurred while processing \
  the command. Original error: Real device \
  architecture is unsupported by the\
  '/Users/juanxu/Library/Developer/Xcode/DerivedData\
  /UIKitCatalog-acwpqjdjdboqzfhavakcbzlzttdd/Build\
  /Products/Debug-iphonesimulator/UIKitCatalog.app'\
    application. Make sure the correct deployment \
    target has been selected for its compilation in Xcode.
  • 问题3:不能启动 WDA
  • 解决3:需要根据日志找到 WDA 的路径,手动打开 WDA 项目,build 成功之后(中间需要输入几次密码授权),再运行 inspector 就可以了。
Error
Failed to create session. An unknown \
  server-side error occurred while processing \
  the command. Original error: Unable to launch \
  WebDriverAgent because of xcodebuild failure: \
  xcodebuild failed with code 65 xcodebuild error \
  message: . Make sure you follow the tutorial at \
  https://github.com/appium/appium-xcuitest-driver\
  /blob/master/docs/real-device-config.md. Try to \
  remove the WebDriverAgentRunner application from \
  the device if it is installed and reboot the device.

七、iOS Safari / WebView 手机浏览器自动化测试

1、网页 app 测试

  • iOS 模拟器 15.2
  • Appium-server 版本:1.22.0
  • Appium inspector 版本: 2021.12.2
from time import sleep
from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy

desire_caps = {
  "platformName": "iOS",
  "platformVersion": "15.2",
  "deviceName": "iPhone 13 Pro",
  "automationName": "XCUITest",
  "browserName": "Safari"
}

driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub",desire_caps)
driver.get("http://m.baidu.com")
driver.find_element(AppiumBy.ID,"index-kw").send_keys("hogwarts")

2、混合 app 测试

  • iOS 模拟器 15.2
  • Appium-server 版本:1.22.0
  • Appium inspector 版本: 2021.12.2
class TestWebView:
    def setup(self):
        caps = {}
        caps["platformName"] = "iOS"
        caps["appium:platformVersion"] = "15.2"
        caps["appium:deviceName"] = "iPhone 13 Pro"
        caps["appium:automationName"] = "XCUITest"
        caps["appium:bundleId"] = \
            "xxx.com.example.apple-samplecode.UICatalog"
        self.driver = webdriver.Remote(\
            "http://127.0.0.1:4723/wd/hub", caps)
        self.driver.implicitly_wait(5)

    def teardown(self):
        self.driver.quit()

    def test_web(self):
        self.driver.find_element(AppiumBy.XPATH, \
            '//XCUIElementTypeStaticText[@name="Web View"]').click()
        sleep(5)
        self.driver.find_element_by_accessibility_id(\
            "Buy iPhone 13 Pro").click()
        sleep(5)

3、真机测试- WebView 调试

  • 手机设置
    • 设置 > Safari 浏览器 > 高级 > 打开网页检查器
  • 真机调试工具 ios-webkit-debug-proxy
    • 安装:brew install ios-webkit-debug-proxy
    • 启动:ios_webkit_debug_proxy -f chrome-devtools://devtools/bundled/inspector.html
    • 访问:http://127.0.0.1:9221/
# 出现如下提示信息,说明启动连接成功
Hogwarts $ ios_webkit_debug_proxy -f \
chrome-devtools://devtools/bundled/inspector.html
Listing devices on :9221
Connected :9222 to iPhone \
(587520157a11c0365e65612ecb3954c63b991fed)

4、真机 web view 实战

  • 环境:
    • Appium Server 版本:1.22.0
    • Appium Inspector 版本: 2021.12.2
    • 手机版本:iPhone 14.2
  • 用例
    • 打开 UICatalog App
    • 点击 Web View 项,进入到 webview 界面
    • 点击 Buy iPhone 13 Pro 项
class TestWebView:
    def setup(self):
        caps = {}
        caps["platformName"] = "iOS"
        caps["appium:platformVersion"] = "14.2"
        caps["appium:deviceName"] = "auto"
        caps["appium:automationName"] = "XCUITest"
        caps["appium:bundleId"] = \
          "xxx.com.example.apple-samplecode.UICatalog"
        caps["appium:xcodeOrgId"] = "34DA528KZV"
        caps["appium:xcodeSigningId"] = "iPhone Developer"
        caps["appium:udid"] = \
          "587520157a11c0365e65612ecb3954c63b991fed"

        self.driver = webdriver.Remote(\
          "http://127.0.0.1:4723/wd/hub", caps)
        self.driver.implicitly_wait(5)

    def teardown(self):
        self.driver.quit()

    def test_web(self):
        self.driver.find_element(AppiumBy.XPATH,\
           '//XCUIElementTypeStaticText[@name="Web View"]').click()
        sleep(5)
        self.driver.find_element_by_accessibility_id(\
          "Buy iPhone 13 Pro").click()
        sleep(5)

5、总结

  • Appium 支持 iOS 的 webview 测试
  • Appium 新版本不需要任何配置,也可以直接测试 iOS
  • Appium 会自动将 web 页面解析转化成原生页面转件,可以直接识别进行用例编写