杰瑞科技汇

appium自动化测试教程

Appium 自动化测试完整教程

目录

  1. 第一部分:Appium 是什么?为什么选择它?
  2. 第二部分:核心概念与环境准备
  3. 第三部分:从零开始搭建你的第一个 Appium 测试项目
  4. 第四部分:编写你的第一个自动化测试脚本
  5. 第五部分:元素定位 - 自动化的核心
  6. 第六部分:常用 API 与操作
  7. 第七部分:进阶主题
  8. 第八部分:实战案例与最佳实践
  9. 第九部分:总结与学习资源

第一部分:Appium 是什么?为什么选择它?

1 Appium 的定义

Appium 是一个开源的、跨平台的自动化测试框架,主要用于原生移动应用、混合移动应用和移动 Web 应用的自动化测试。

核心思想: 你可以使用一套 API(如 WebDriver 协议)为不同平台(iOS, Android, Windows)编写测试脚本,而无需关心底层实现细节。

2 Appium 的核心优势

  • 跨平台: 一套 API 可以同时支持 iOS 和 Android。
  • 跨语言: 支持多种编程语言编写测试脚本,如 Java, Python, JavaScript (Node.js), Ruby, C# 等。
  • 开源免费: 拥有活跃的社区和持续更新。
  • 无需修改应用源码: Appium 通过 Instrumentation (Android) 和 UIAutomation/XCUITest (iOS) 与应用交互,不应用需要对 App 进行重新编译或打包。
  • 与现有框架集成: 可以轻松地与 TestNG, JUnit, PyTest, Mocha 等测试框架以及 Jenkins, GitLab CI 等 CI/CD 工具集成。
  • 强大的社区支持: 遇到问题很容易找到解决方案。

第二部分:核心概念与环境准备

在开始之前,你需要理解几个核心概念并搭建好开发环境。

1 核心概念

  1. Client (客户端): 你编写的测试脚本,可以是 Java, Python 等,它负责发送命令给 Appium Server。
  2. Appium Server: 一个用 Node.js 编写的服务,它接收来自 Client 的命令,并将其转换成具体的平台指令(如 Android 的 adb 命令,iOS 的 xcodebuild 命令)。
  3. Driver (驱动): Appium Server 通过平台特定的驱动(如 Android 的 UiAutomator2/XCUITest)来与设备上的应用进行交互。
  4. Desired Capabilities (期望能力): 一组键值对,用于告诉 Appium Server 你想要启动什么样的会话。
    • platformName: 平台名称,如 "Android", "iOS"。
    • deviceName: 设备名称,如 "Pixel_4_API_30" 或 "iPhone 12"。
    • app: 待测试应用的 .apk.app 文件路径。
    • automationName: 自动化引擎,如 "UiAutomator2" (Android), "XCUITest" (iOS)。

2 环境准备

你需要准备以下工具:

通用工具:

  • Java Development Kit (JDK): Appium Server 依赖 Java,推荐 JDK 8 或 11。
  • Node.js 和 npm: Appium Server 是基于 Node.js 的,从 Node.js 官网 下载并安装。
  • Appium Desktop: 可视化 Appium Server 的管理工具,非常方便,从 Appium.io 官网 下载。
  • IDE (集成开发环境): 如 IntelliJ IDEA, Eclipse (Java), PyCharm (Python), VS Code (通用)。

Android 环境特定工具:

  • Android SDK: 包含开发 Android 应用所需的工具。
  • Android SDK Platform-Tools: 包含 adb (Android Debug Bridge),这是与 Android 设备/模拟器通信的关键工具。
  • Android Emulator: Android 官方模拟器,或使用 Genymotion。
  • 配置环境变量:
    • ANDROID_HOME: 指向 Android SDK 的根目录。
    • PATH: 添加 %ANDROID_HOME%\platform-tools%ANDROID_HOME%\tools (如果需要)。

iOS 环境特定工具 (仅限 Mac):

  • Xcode: Apple 官方的 IDE,Appium 依赖 Xcode 中的编译器和测试框架。
  • 配置 Command Line Tools: 在 Xcode -> Preferences -> Locations 中,确保 Command Line Tools 已选中。

设备/模拟器/真机:

  • Android: 启用 USB 调试的开发者模式真机,或正在运行的 Android 模拟器。
  • iOS: 连接 Mac 的真机 (需开启开发者模式),或 Xcode 模拟器。

第三部分:从零开始搭建你的第一个 Appium 测试项目

我们以 Python + PyCharm 为例,因为 Python 语法简洁,非常适合入门。

1 安装 Python 依赖库

打开终端或命令行,安装 Appium Python 客户端库:

pip install Appium-Python-Client

2 下载一个测试 App

为了方便,我们使用 Google 官方的示例应用 "ApiDemos"。

3 启动 Appium Server

最简单的方式是使用 Appium Desktop

  1. 打开 Appium Desktop。
  2. 点击 "Start Server" 按钮,服务器默认在 http://127.0.0.1:4723 启动。

4 配置 Desired Capabilities

我们需要告诉 Appium 如何连接我们的设备和启动应用,在 Appium Desktop 中,你可以使用 "Desired Capabilities Helper" 来生成配置。

示例配置 (Android):

{
  "platformName": "Android",
  "deviceName": "Pixel_4_API_30", // 你的模拟器或设备名称
  "app": "/path/to/your/ApiDemos-debug.apk", // .apk 文件的绝对路径
  "automationName": "UiAutomator2",
  "noReset": true, // 不在测试后重置应用数据
  "fullReset": false // 不完全重置应用
}

如何获取 deviceName:

  • Android: 在终端运行 adb devices,列表中的设备名就是 deviceName
  • iOS: 在终端运行 xcrun simctl list devices,列表中的设备名就是 deviceName

第四部分:编写你的第一个自动化测试脚本

让我们用 Python 写一个脚本,实现以下操作:

  1. 打开 ApiDemos 应用。
  2. 点击 "Views" 菜单项。
  3. 验证是否成功跳转到新页面。

1 脚本代码 (first_test.py)

import time
from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy
# 1. 定义 Desired Capabilities
caps = {
    "platformName": "Android",
    "deviceName": "Pixel_4_API_30", # 替换成你的设备名
    "app": "/Users/yourname/Downloads/ApiDemos-debug.apk", # 替换成你的 .apk 路径
    "automationName": "UiAutomator2",
    "noReset": True,
    "fullReset": False
}
# 2. 初始化 Appium Driver
# Appium Server 默认运行在 4723 端口
driver = webdriver.Remote('http://127.0.0.1:4723', caps)
try:
    # 3. 查找并点击 "Views" 元素
    # 使用 accessibility_id 定位,这是最稳定的方式之一
    views_element = driver.find_element(by=AppiumBy.ACCESSIBILITY_ID, value="Views")
    views_element.click()
    print("成功点击 'Views'")
    # 等待 2 秒,让页面加载完成
    time.sleep(2)
    # 4. 验证是否成功跳转
    # 我们通过检查新页面上的一个元素是否存在来验证
    # 检查 "Animation" 是否存在
    animation_element = driver.find_element(by=AppiumBy.ACCESSIBILITY_ID, value="Animation")
    if animation_element:
        print("验证成功:已成功跳转到 Views 页面")
    else:
        print("验证失败:未能跳转到 Views 页面")
finally:
    # 5. 关闭会话
    # 无论测试成功与否,最后都会执行关闭操作
    driver.quit()
    print("测试会话已关闭")

2 运行脚本

  1. 确保你的 Android 模拟器/真机正在运行。
  2. 确保你的 Appium Server 已经启动。
  3. 在 PyCharm 中运行 first_test.py 脚本。

如果一切顺利,你将看到脚本在模拟器中自动操作,控制台会打印出相应的日志信息。


第五部分:元素定位 - 自动化的核心

自动化测试的核心就是找到屏幕上的元素并对其进行操作,Appium 提供了多种定位方式。

定位方式 Appium Python 语法 描述 示例
ID AppiumBy.ID 通过资源的 ID 定位,最常用、最稳定。 driver.find_element(AppiumBy.ID, 'android:id/button1')
Accessibility ID AppiumBy.ACCESSIBILITY_ID 通过元素的辅助功能 ID 定位,非常稳定,推荐。 driver.find_element(AppiumBy.ACCESSIBILITY_ID, 'Views')
XPath AppiumBy.XPATH 通过路径表达式定位,功能强大但性能较差。 driver.find_element(AppiumBy.XPATH, '//android.widget.TextView[@text="Views"]')
Class Name AppiumBy.CLASS_NAME 通过元素的类名定位,可能不唯一。 driver.find_element(AppiumBy.CLASS_NAME, 'android.widget.TextView')
Android UIAutomator AppiumBy.ANDROID_UIAUTOMATOR Android 特有,使用 UIAutomator 2 的语法,非常强大。 driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR, 'new UiSelector().text("Views")')
iOS UIAutomation AppiumBy.IOS_UIAUTOMATION iOS 特有,已不推荐,使用 XCUITest 代替。 (略)

如何获取元素信息? 强烈推荐使用 Appium Desktop 自带的 Inspector (元素检查器) 功能。

  1. 在 Appium Desktop 中,点击 "Start Inspector Session"。
  2. 填写你的 Desired Capabilities 并点击 "Start Session"。
  3. 一个窗口会显示你的应用界面,你可以点击界面上的任意元素,其定位信息(ID, XPath, Class Name 等)会实时显示在右侧,方便你复制使用。

第六部分:常用 API 与操作

1 元素操作

# 查找元素
element = driver.find_element(by=AppiumBy.ID, value="some_id")
# 点击
element.click()
# 输入文本 (适用于输入框)
element.send_keys("Hello Appium")
# 清空文本
element.clear()
# 获取元素属性
text = element.text  # 获取显示的文本
id_value = element.get_attribute("resource-id") # 获取 resource-id 属性

2 等待

等待是自动化测试中至关重要的一环,可以避免因页面加载慢而导致的元素找不到问题。

  • 隐式等待: 全局等待,在查找元素时,如果元素没找到,会等待指定的时间。

    driver.implicitly_wait(10) # 最多等待 10 秒

    缺点: 会对所有 find_element 生效,不够灵活。

  • 显式等待 (推荐): 针对特定元素进行等待,更精确、更可控。

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    # 等待最多 10 秒,直到 ID 为 "some_id" 的元素可见
    element = WebDriverWait(driver, 10).until(
        EC.visibility_of_element_located((AppiumBy.ID, "some_id"))
    )

3 手势操作

Appium 提供了 TouchAction 来模拟复杂的手势。

from appium.webdriver.common.touch_action import TouchAction
# 滑动示例
def swipe_up(driver, duration=800):
    """从屏幕底部向上滑动"""
    size = driver.get_window_size()
    width = size['width']
    height = size['height']
    start_x = width / 2
    start_y = height * 0.8
    end_x = width / 2
    end_y = height * 0.2
    TouchAction(driver).press(x=start_x, y=start_y).wait(duration).move_to(x=end_x, y=end_y).release().perform()
# 长按示例
def long_press(driver, element_id, duration=2000):
    """长按指定元素 2 秒"""
    element = driver.find_element(AppiumBy.ID, element_id)
    TouchAction(driver).long_press(element, duration=duration).release().perform()

4 页面切换 (Webview/Hybrid App)

对于混合应用(包含 WebView),你需要先切换到 Web 上下文。

# 1. 获取所有可用的上下文
contexts = driver.contexts
print("所有上下文:", contexts) # 通常会包含 'NATIVE_APP' 和 'WEBVIEW_com.example.app'
# 2. 切换到 WebView 上下文
webview_context = None
for context in contexts:
    if 'WEBVIEW' in context:
        webview_context = context
        break
if webview_context:
    driver.switch_to.context(webview_context)
    print("已切换到 WebView 上下文")
    # 3. 现在可以使用 Selenium 的方式操作 Web 元素
    driver.find_element(by=AppiumBy.XPATH, value="//a[text()='Click me']").click()
    # 4. 测试完成后,切回到原生应用上下文
    driver.switch_to.context('NATIVE_APP')
    print("已切回到原生应用上下文")

第七部分:进阶主题

1 测试框架集成

将 Appium 脚本与专业的测试框架结合,可以更好地组织测试用例、生成报告。

  • Python + PyTest:

    • 使用 pytest 来组织和运行测试用例。
    • 使用 pytest-htmlAllure 生成漂亮的 HTML 测试报告。
    • 使用 conftest.py 来管理 driversetup (初始化) 和 teardown (关闭),实现代码复用。
  • Java + TestNG:

    • 使用 TestNG@BeforeSuite, @BeforeMethod, @AfterMethod, @AfterSuite 等注解来管理测试生命周期。
    • TestNG 强大的报告功能和并行执行能力是大型项目的首选。

2 参数化

使用配置文件(如 .yaml, .json)或命令行参数来管理测试数据(如设备名、App 路径),使脚本更具灵活性。

3 并行执行

利用 pytest-xdist (PyTest) 或 TestNG 的并行执行功能,可以在多台设备或多线程上同时运行测试,大大提高测试效率。

4 持续集成 (CI/CD)

将 Appium 测试脚本集成到 Jenkins, GitLab CI, GitHub Actions 等工具中,实现代码提交后自动触发测试、报告生成和通知。


第八部分:实战案例与最佳实践

实战案例:一个简单的登录功能测试

假设我们有一个登录 App,用户名输入框 ID 为 com.example.app:id/et_username,密码输入框 ID 为 com.example.app:id/et_password,登录按钮 ID 为 com.example.app:id/btn_login

import pytest
from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
class TestLogin:
    @pytest.fixture
    def driver_setup(self):
        # 前置条件:启动 Driver
        caps = {
            "platformName": "Android",
            "deviceName": "Pixel_4_API_30",
            "app": "/path/to/your/app.apk",
            "automationName": "UiAutomator2",
            "noReset": True
        }
        driver = webdriver.Remote('http://127.0.0.1:4723', caps)
        yield driver  # 将 driver 传递给测试方法
        # 后置条件:关闭 Driver
        driver.quit()
    def test_successful_login(self, driver_setup):
        driver = driver_setup
        # 使用显式等待
        wait = WebDriverWait(driver, 10)
        # 1. 输入用户名
        username_input = wait.until(EC.visibility_of_element_located((AppiumBy.ID, "com.example.app:id/et_username")))
        username_input.send_keys("testuser")
        # 2. 输入密码
        password_input = driver.find_element(AppiumBy.ID, "com.example.app:id/et_password")
        password_input.send_keys("password123")
        # 3. 点击登录按钮
        login_button = driver.find_element(AppiumBy.ID, "com.example.app:id/btn_login")
        login_button.click()
        # 4. 验证登录成功 (检查是否出现了 "欢迎" 文本)
        welcome_text = wait.until(EC.visibility_of_element_located((AppiumBy.XPATH, "//*[contains(@text, '欢迎')]")))
        assert welcome_text is not None
        print("登录测试通过!")

最佳实践

  1. 稳定性第一: 优先使用 accessibility_idid 进行定位,XPath 是最后的手段。
  2. 多用显式等待: 避免使用 time.sleep(),除非在调试特定问题时,显式等待让你的脚本更健壮。
  3. Page Object Model (POM): 这是设计模式,核心思想是将页面元素定位和操作封装在独立的类中,测试脚本只调用这些方法,这极大地提高了代码的可维护性。
    • LoginPage.py -> 包含登录页面的所有元素和操作方法。
    • test_login.py -> 只关心测试逻辑,调用 LoginPage 的方法。
  4. 清晰的目录结构:
    /my_appium_project
    ├── /pages          # 存放 Page Object 模型
    │   ├── login_page.py
    │   └── home_page.py
    ├── /tests          # 存放测试用例
    │   └── test_login.py
    ├── /configs        # 存放配置文件
    │   └── desired_caps.yaml
    ├── /apps           # 存放测试用的 .apk 文件
    │   └── MyApp.apk
    ├── requirements.txt
    └── pytest.ini
  5. 良好的断言: 每个测试用例都应该有明确的断言,用来验证操作是否达到预期结果。
  6. 清晰的日志: 在关键步骤添加打印日志,方便调试和追踪问题。

第九部分:总结与学习资源

Appium 是一个非常强大且灵活的移动自动化测试工具,掌握它需要时间和实践,本教程为你提供了一个从零开始的完整路径,关键在于:

  1. 打好基础: 理解核心概念和定位方法。
  2. 动手实践: 从简单的脚本开始,逐步构建复杂的测试场景。
  3. 拥抱最佳实践: 使用 POM、显式等待、测试框架,让你的项目更专业、更易于维护。

学习资源

祝你学习愉快,早日成为移动自动化测试专家!

分享:
扫描分享到社交APP
上一篇
下一篇