千锋教育-做有情怀、有良心、有品质的职业教育机构

Appium 移动端自动化测试:一套脚本跑通 iOS 和 Android

来源:千锋教育
发布时间:2026-05-09 16:08:01

千锋教育品牌logo

01 Appium 的核心架构:为什么它能跨平台

理解 Appium 之前,先搞清楚一个根本问题:为什么移动端自动化比 Web 端难?

Web 端有统一的 DOM 结构,Selenium 通过 WebDriver 协议操控浏览器。但 iOS 和 Android 是两套完全不同的系统:不同的渲染引擎、不同的控件体系、不同的交互方式。

Appium 的解决方案:**不直接操控设备,而是翻译指令**。

```

你的测试脚本

↓(WebDriver 协议)

Appium Server

↓(翻译为平台原生命令)

├── iOS:XCUITest(Apple 官方测试框架)

└── Android:UiAutomator2 / Espresso(Google 官方测试框架)

```

**Before**:用 Xcode Instruments 测 iOS,用 Espresso 测 Android,两套代码,两套维护。

**After**:用 Appium 写一套脚本,Server 自动翻译为各平台的原生命令。

Appium 2.0 的架构改进:

| 特性 | Appium 1.x | Appium 2.0 |

|------|-----------|-----------|

| 驱动安装 | 内置 | 插件化,按需安装 |

| 扩展性 | 有限 | 支持自定义插件 |

| 多会话 | 麻烦 | 原生支持 |

| 维护 | 整体升级 | 驱动独立升级 |

> Appium 不是另一套测试框架,是翻译官。你用一种语言表达,它翻译成两种系统都能听懂的指令。

---

02 环境搭建:2026年最省心的配置方案

Appium 环境搭建历来是新手噩梦。Appium 2.0 大幅简化了流程。

**Android 端准备**:

```bash

# 1. 安装 JDK 17

# 2. 安装 Android SDK(通过 Android Studio)

# 3. 安装 Appium Doctor 检查环境

npm install -g appium-doctor

appium-doctor --android

```

**iOS 端准备**(需要 Mac):

```bash

# 1. 安装 Xcode

# 2. 安装 XCUITest 驱动

appium driver install xcuitest

# 3. 检查环境

appium-doctor --ios

```

**安装 Appium 2.0 Server**:

```bash

npm install -g appium

appium driver install uiautomator2 # Android 驱动

appium driver install xcuitest # iOS 驱动

appium server # 启动服务

```

**Python 客户端安装**:

```bash

pip install Appium-Python-Client

```

**验证环境**:

```python

from appium import webdriver

# Android 配置

android_caps = {

"platformName": "Android",

"appium:deviceName": "Pixel 7",

"appium:platformVersion": "14",

"appium:automationName": "UiAutomator2",

"appium:app": "/path/to/app.apk"

}

# iOS 配置(Mac 上运行)

ios_caps = {

"platformName": "iOS",

"appium:deviceName": "iPhone 15",

"appium:platformVersion": "17.0",

"appium:automationName": "XCUITest",

"appium:app": "/path/to/app.ipa"

}

# 切换平台只需要改配置

driver = webdriver.Remote("http://127.0.0.1:4723", android_caps)

```

**Before**:搭环境花3天,报错50个,查 StackOverflow 查到崩溃。

**After**:Appium 2.0 + Appium Doctor,30分钟搞定环境,哪里有问题 Doctor 直接告诉你。

> 环境问题不值得研究。工具能自动解决的,就不要手动折腾。

---

03 元素定位:移动端与 Web 端的核心差异

Web 端用 ID、CSS Selector、XPath 定位元素。移动端的定位方式有所不同,但也有规律可循。

**移动端常用定位方式**:

| 定位方式 | 说明 | Android | iOS |

|---------|------|---------|-----|

| Accessibility ID | 无障碍标识(推荐) | content-desc | accessibility-id |

| ID | 原生资源 ID | resource-id | name |

| XPath | 路径定位 | 支持 | 支持(较慢) |

| Class Name | 控件类名 | UI 组件类 | XCUIElementType |

| iOS Predicate | iOS 专属谓词 | 不支持 | 支持 |

| iOS Class Chain | iOS 专属链式 | 不支持 | 支持 |

```python

from appium.webdriver.common.appiumby import AppiumBy

# 1. Accessibility ID(跨平台推荐)

element = driver.find_element(AppiumBy.ACCESSIBILITY_ID, "login_button")

# 2. Android 专用:resource-id

element = driver.find_element(AppiumBy.ID, "com.example.app:id/username")

# 3. XPath(跨平台,但慢)

element = driver.find_element(AppiumBy.XPATH, '//android.widget.EditText[@text="用户名"]')

# 4. iOS 专用:Predicate

element = driver.find_element(AppiumBy.IOS_PREDICATE, "label == '登录' AND type == 'XCUIElementTypeButton'")

# 5. iOS 专用:Class Chain

element = driver.find_element(AppiumBy.IOS_CLASS_CHAIN, "**/XCUIElementTypeButton[`label == '登录'`]")

```

**实战建议**:

- 优先使用 Accessibility ID,双平台通用且稳定

- 让开发给关键控件加 `content-desc`(Android)和 `accessibilityIdentifier`(iOS)

- 少用 XPath,移动端 DOM 渲染慢,XPath 遍历更慢

> 移动端定位的黄金法则:让开发加标识。你省一天,他只多5分钟。

---

04 跨平台测试策略:写一次跑两次

真正的跨平台不是"一套代码硬跑两个平台",而是**合理的抽象层设计**。

**Page Object Model(页面对象模式)**:

```python

# base_page.py - 跨平台基类

class BasePage:

def __init__(self, driver):

self.driver = driver

def find(self, locator):

return self.driver.find_element(*locator)

def click(self, locator):

self.find(locator).click()

def type_text(self, locator, text):

self.find(locator).clear()

self.find(locator).send_keys(text)

# login_page.py - 登录页(平台差异在这里处理)

class LoginPage(BasePage):

# Android 定位器

ANDROID = {

"username": (AppiumBy.ID, "com.example.app:id/username"),

"password": (AppiumBy.ID, "com.example.app:id/password"),

"login_btn": (AppiumBy.ID, "com.example.app:id/login"),

}

# iOS 定位器

IOS = {

"username": (AppiumBy.ACCESSIBILITY_ID, "username_field"),

"password": (AppiumBy.ACCESSIBILITY_ID, "password_field"),

"login_btn": (AppiumBy.ACCESSIBILITY_ID, "login_button"),

}

def __init__(self, driver, platform):

super().__init__(driver)

self.locators = self.ANDROID if platform == "android" else self.IOS

def login(self, username, password):

self.type_text(self.locators["username"], username)

self.type_text(self.locators["password"], password)

self.click(self.locators["login_btn"])

```

**测试用例**:

```python

import pytest

@pytest.fixture(params=["android", "ios"])

def login_page(request):

platform = request.param

caps = ANDROID_CAPS if platform == "android" else IOS_CAPS

driver = webdriver.Remote(SERVER_URL, caps)

yield LoginPage(driver, platform)

driver.quit()

def test_login_success(login_page):

login_page.login("testuser", "password123")

# 验证登录成功(跨平台断言)

assert is_logged_in(login_page.driver)

```

**Before**:Android 和 iOS 各写一套测试用例,改业务逻辑要改两遍。

**After**:业务逻辑写一遍,定位器分开管理。改逻辑一处搞定,改定位器互不影响。

> 跨平台测试的核心不是技术,是抽象。把"变的部分"和"不变的部分"分开,维护成本降一半。

---

05 实战避坑:Appium 最常见的6个坑

**坑1**:元素定位不到 → 用 Appium Inspector 检查元素属性

```bash

# Appium 2.0 Inspector

appium inspector

```

**坑2**:隐式等待不够导致不稳定 → 用显式等待

```python

from appium.webdriver.common.appiumby import AppiumBy

from selenium.webdriver.support.ui import WebDriverWait

from selenium.webdriver.support import expected_conditions as EC

element = WebDriverWait(driver, 10).until(

EC.presence_of_element_located((AppiumBy.ACCESSIBILITY_ID, "submit"))

)

```

**坑3**:真机连接不稳定 → 检查 adb devices / idevice list

```bash

# Android

adb devices

# iOS

xcrun xctrace list devices

```

**坑4**:键盘弹不出来 → 使用 `send_keys` 前 `click` 输入框

```python

input_field.click() # 先点击获取焦点

input_field.send_keys("文本")

```

**坑5**:上下文切换(WebView 混合应用)

```python

# 获取所有上下文

contexts = driver.contexts

# 切换到 WebView

driver.switch_to.context("WEBVIEW_com.example.app")

# 切回原生

driver.switch_to.context("NATIVE_APP")

```

**坑6**:手势操作(滑动、长按)

```python

from appium.webdriver.common.touch_action import TouchAction

# 向上滑动

TouchAction(driver).press(x=500, y=1500).move_to(x=500, y=500).release().perform()

# 长按

TouchAction(driver).long_press(element).release().perform()

```

> 每个坑踩一次就够了。记下来,下次绕过去。经验是最贵的学费。

---

Appium 2.0 让移动端自动化比以前简单了多,但核心逻辑没变:**跨平台的关键是抽象层设计,稳定性的关键是显式等待,效率的关键是让开发配合加标识**。

掌握了架构理解、环境搭建、元素定位、跨平台策略和避坑技巧,你就能用一套代码覆盖 iOS 和 Android 两个平台。

**移动端自动化不是锦上添花,是标配。用户不会因为你说"我们只测了 Android"就原谅你 iOS 上的 bug。**

声明:本站部分稿件版权来源于网络,如有侵犯版权,请及时联系我们。

学习资源站

  • 免费全套视频教程
  • 企业实战项目源码
  • 大厂笔试真题题库
  • 行业前瞻发展趋势

相关推荐

  • Appium 移动端自动化测试:一套脚本跑通 iOS 和 Android
  • Jenkins Pipeline 自动化测试调度:代码提交即触发,测试报告自动出
  • 3步搭建混沌工程故障注入后系统韧性提升87%_千锋教育 3步搭建混沌工程,故障注入后系统韧性提升87% 你以为系统稳如磐石?那是你没见过它崩溃的样子。混沌工程不是搞破坏,是用主动故障来验证系统的真实韧性。 01 混沌工程:不是制造混乱,是提前排雷 传统测试只验证“正常情况”——用户点击、数据提交、API响应。但现实世界,故障是常态。网络延迟、磁盘满、服务宕机
  • 3小时从0找到第一个Bug,接口测试新手效率提升200%_千锋教育
  • 软件测试面试中的缺陷管理流程问答_千锋教育
  • 你还在以为压力测试就是拼命加并发?面试官一听就摇头