news 2026/7/8 16:45:57

零基础入门Appium自动化测试:从环境搭建到框架实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
零基础入门Appium自动化测试:从环境搭建到框架实战

1. 项目概述:为什么零基础也能玩转Appium?

如果你对“自动化测试”这四个字感到既熟悉又陌生,觉得它好像是那些资深开发工程师的专属领域,那今天这篇内容就是为你准备的。我见过太多测试新人或者想转行做自动化的朋友,被网上各种复杂的教程、晦涩的术语和动不动就报错的环境配置劝退。其实,Appium自动化测试的门槛,远没有想象中那么高。它就像一个设计精良的乐高套装,只要你按照正确的步骤,一块一块地拼接,最终就能搭建出属于你自己的自动化测试城堡。

Appium的核心魅力在于它的“跨平台”和“开源”。简单来说,你可以用同一套测试脚本(比如用Python写的),去测试运行在iOS和Android两个完全不同系统上的App。这极大地减少了学习成本和维护成本。你不需要分别去学iOS的XCUITest和Android的Espresso/UIAutomator,Appium帮你封装好了与这些底层框架通信的桥梁。你只需要告诉Appium:“帮我点击这个按钮”或者“在这个输入框里输入文字”,它就会帮你翻译成手机系统能听懂的语言并执行。

那么,谁适合从零开始学Appium呢?第一类,当然是手工测试工程师,你想提升效率,把重复性的回归测试交给机器,让自己有更多时间去做更有价值的探索性测试。第二类,是刚入门编程的朋友,Python语法相对简单,结合Appium你能立刻看到自己写的代码操控手机App的成就感,这种正向反馈是学习的最佳动力。第三类,甚至是对技术感兴趣的产品经理或项目经理,了解自动化测试的流程和边界,能让你更好地与技术团队沟通。接下来,我们就抛开那些让人望而生畏的理论,直接从最实在的环境搭建和第一个脚本开始。

2. 环境搭建:避开坑点,一次配成“开箱即用”的环境

万事开头难,而Appium学习的“开头”,十有八九都卡在了环境配置上。网上教程很多,但版本迭代快,稍有不慎就会掉进“环境地狱”。别担心,我会带你走一条最清晰、坑最少的路径。我们的目标是搭建一个支持Android自动化测试的环境(iOS环境需要Mac电脑和开发者账号,门槛较高,我们后续再谈),核心就四样东西:Java、Android SDK、Appium Server、Python客户端库。

2.1 基础依赖安装:JDK与Android SDK

Java Development Kit (JDK)是必须的,因为Android的构建工具链依赖Java。不要去官网下最新版,我建议安装JDK 8 或 JDK 11(LTS长期支持版本),兼容性最好。安装后,需要配置系统环境变量JAVA_HOME,指向你的JDK安装目录(例如C:\Program Files\Java\jdk1.8.0_301),并在Path变量中添加%JAVA_HOME%\bin。打开命令行输入java -version能显示版本信息,第一步就成功了。

注意:很多同学在这里出错,是因为只安装了JRE(运行环境),没装JDK(开发工具包)。务必确认安装的是JDK。

接下来是重头戏Android SDK。现在谷歌官方推荐使用Android Studio来管理SDK,这对新手其实更友好。你不需要精通Android开发,只需要用它来下载我们需要的“零件”。

  1. 安装Android Studio:从官网下载安装,过程中它会提示你安装Android SDK,勾选并记住安装路径,比如C:\Users\你的用户名\AppData\Local\Android\Sdk
  2. 配置环境变量:新建系统变量ANDROID_HOME,值就是上面的SDK路径。然后在Path变量中添加三个:
    • %ANDROID_HOME%\platform-tools(包含adb命令,用来连接手机)
    • %ANDROID_HOME%\tools
    • %ANDROID_HOME%\tools\bin
  3. 安装必要组件:打开Android Studio,进入Settings(或Preferences) > Appearance & Behavior > System Settings > Android SDK。在SDK Platforms标签页,至少勾选一个你手机或模拟器对应版本的Android系统(比如 Android 11.0 (R))。在SDK Tools标签页,务必勾选并安装:
    • Android SDK Build-Tools(选一个较高的版本,如 30.0.3)
    • Android Emulator(如果你用模拟器)
    • Android SDK Platform-Tools(包含adb,通常已默认安装)
    • Intel x86 Emulator Accelerator (HAXM installer)Android Emulator Hypervisor Driver(用于提升模拟器性能,根据电脑CPU类型选择)

完成后,在命令行输入adb versionemulator -list-avds,如果都有正常输出,说明Android环境基本OK。

2.2 Appium Server的两种选择:桌面版 vs 命令行版

Appium Server是核心“翻译官”和“调度中心”。你有两种选择:

方案A:Appium Desktop(图形界面版)这是对新手最友好的方式。从Appium官网下载安装,打开后点击“Start Server”按钮即可启动一个服务。它自带一个Inspector工具,可以用来查看App界面元素,对于编写脚本时定位元素至关重要。优点是开箱即用,可视化。缺点是版本更新可能略慢于命令行版,且内存管理有时不如命令行灵活(这解释了为什么搜索词里有“mac 上appium 内存溢出”的问题)。

方案B:Appium Server via npm(命令行版)这是更专业、更灵活的方式。前提是你需要先安装Node.js。安装Node.js后,打开命令行(Windows用CMD或PowerShell,Mac用终端),执行以下命令进行全局安装:

npm install -g appium

安装完成后,直接输入appium命令即可启动服务器。要使用Inspector,需要单独安装:

npm install -g appium-doctor appium-inspector

然后用appium-inspector命令启动。命令行版的优势是版本更新快,可以通过参数更精细地控制服务器行为,适合集成到CI/CD流水线中。

实操心得:我强烈建议零基础的同学从Appium Desktop开始。它能让你快速看到效果,建立信心。等熟悉了整个流程后,再切换到命令行版以获得更好的控制和性能。启动Appium Server后,默认会在http://127.0.0.1:4723提供服务,这个地址我们写脚本时会用到。

2.3 Python客户端库与编辑器准备

我们的测试脚本将用Python来写。首先确保你安装了Python(3.6以上版本)。然后,通过pip安装Appium的Python客户端库:

pip install Appium-Python-Client

这个库提供了所有用来和Appium Server通信的类和方法。至于代码编辑器,PyCharmVS Code都是极好的选择,它们对Python的支持和代码提示能大大提升效率。

最后,用一条命令做个健康检查:在命令行输入appium-doctor(如果你安装了的话),它会检查你的环境是否完备,并给出修复建议。如果所有项目都打了绿色的勾,那么恭喜你,最艰难的一关已经过去了!

3. 核心概念与第一个脚本:从“Hello World”到操控真实App

环境配好了,我们终于可以开始写代码了。但在动手之前,必须理解几个核心概念,这就像学开车前得知道方向盘、油门和刹车分别是干嘛的。

Session(会话):一次自动化测试的开始,始于向Appium Server发起一个“会话”请求。这个请求里包含了一个非常重要的字典——Desired Capabilities。你可以把它理解为一份“测试任务说明书”,告诉Appium Server:这次测试要用什么设备(平台名、版本号)、测哪个App、怎么启动等等。

Desired Capabilities 常用参数解析

  • platformName: 操作系统,填AndroidiOS
  • platformVersion: 手机系统的版本号,如11.0
  • deviceName: 设备名称,Android下可以自定义(但不能为空),iOS下必须是准确的设备名。
  • appPackage: 你要测试的App的包名(Android唯一标识),例如微信是com.tencent.mm
  • appActivity: 你要测试的App的启动Activity名(Android的界面入口),例如微信的启动页是.ui.LauncherUI
  • automationName: 自动化引擎,Android通常用UiAutomator2(推荐),iOS用XCUITest
  • udid: 物理设备的唯一标识符,当连接多台设备时必须指定。
  • app: 如果测试尚未安装的App,可以指定APK文件在本地的路径。

元素定位:这是自动化测试的基石。你要告诉Appium去操作屏幕上的哪个按钮、哪个输入框。Appium支持多种定位方式,最常用的是:

  • id: 通过元素的resource-id属性定位(首选,最稳定)。
  • accessibility_id: 通过元素的content-desc属性定位(在Android和iOS上通用性较好)。
  • xpath: 通过元素的路径表达式定位,功能强大但执行稍慢,且容易因UI改动而失效,慎用。

好了,理论说再多不如动手。我们来创建一个真正的“Hello World”脚本:打开手机上的“设置”App,并点击“关于手机”选项。

3.1 连接真实设备

  1. 用USB线连接你的Android手机。
  2. 在手机上开启“开发者选项”(通常是在“关于手机”里连续点击“版本号”7次)。
  3. 在开发者选项中,开启“USB调试”。
  4. 在电脑命令行输入adb devices,如果看到设备列表,说明连接成功。

3.2 使用Appium Inspector探查元素

启动Appium Desktop,先启动Server,然后点击放大镜图标打开Inspector。在Inspector中,你需要填写Desired Capabilities来启动一个会话并连接到你的手机。至少填写:

{ "platformName": "Android", "platformVersion": "你的手机系统版本", "deviceName": "你的手机设备名(adb devices显示的名称)", "automationName": "UiAutomator2" }

点击“Start Session”,Inspector会连接你的手机并显示当前屏幕。点击屏幕上的元素,右侧就会显示该元素的各种属性,比如resource-id,text,content-desc等。我们找到“设置”图标,记下它的属性(比如可能有一个resource-idcom.android.settings:id/settings_homepage_preference)。同样,找到“关于手机”选项,记下它的属性。

3.3 编写并运行第一个Python脚本

现在,打开你的代码编辑器,创建一个Python文件,比如first_test.py

from appium import webdriver from appium.webdriver.common.appiumby import AppiumBy import time # 1. 定义Desired Capabilities,我们的“任务说明书” desired_caps = { 'platformName': 'Android', 'platformVersion': '11.0', # 改为你的手机版本 'deviceName': 'your_device_name', # 改为adb devices显示的设备名 'automationName': 'UiAutomator2', 'appPackage': 'com.android.settings', # 系统设置App的包名 'appActivity': '.Settings' # 系统设置App的主Activity } # 2. 连接Appium Server,启动会话 driver = webdriver.Remote('http://127.0.0.1:4723', desired_caps) time.sleep(2) # 等待App稳定启动 # 3. 定位并点击“关于手机”选项 # 假设我们通过Inspector发现“关于手机”的resource-id是 `com.android.settings:id/about_phone_preference` about_phone_element = driver.find_element(AppiumBy.ID, 'com.android.settings:id/about_phone_preference') about_phone_element.click() print("成功点击‘关于手机’!") # 4. 等待几秒,查看结果,然后结束会话 time.sleep(3) driver.quit()

运行这个脚本(在终端python first_test.py),你会看到手机自动打开了设置,并跳转到了“关于手机”页面。这就是你的第一个自动化脚本!虽然简单,但它完整地走通了从环境配置、元素定位到脚本执行的全流程。这个“成功点击”的瞬间,就是你从零基础迈向自动化测试工程师的第一步。

4. 脚本进阶:编写健壮、可维护的测试用例

第一个脚本能跑通,但它是“脆弱”的。如果手机反应慢一点,如果元素还没加载出来,脚本就会因为找不到元素而报错崩溃。真正的自动化测试脚本需要健壮性和可维护性。这一章,我们来升级你的脚本。

4.1 等待机制:告别“NoSuchElementException”

为什么脚本会找不到元素?最常见的原因是:你的代码执行速度,快于手机UI渲染的速度。你发令“点击关于手机”,但那个按钮可能还在加载动画中。解决方法就是“等待”。

强制等待 (time.sleep): 我们第一个脚本里用的就是它。time.sleep(3)意味着无条件等待3秒。简单粗暴,但效率低下。如果网络好1秒就加载完了,剩下2秒就是浪费;如果网络差3秒没加载完,还是会报错。

隐式等待 (driver.implicitly_wait): 在创建driver后设置一次,对整个driver生命周期有效。它告诉driver在查找任何一个元素时,如果没立即找到,就轮询查找,直到超过设定的时间(如10秒)才抛异常。它解决的是“元素存在性”问题。

driver.implicitly_wait(10) # 设置隐式等待10秒

显式等待 (WebDriverWait): 这是最推荐、最灵活的方式。它针对某个特定的元素和条件进行等待,条件满足则立即返回,超时则抛异常。它解决的是“元素可交互性”问题(如可点击、可见、包含特定文本)。

from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # 等待“关于手机”元素可被点击,最多等10秒,每0.5秒检查一次 wait = WebDriverWait(driver, 10) about_phone_element = wait.until(EC.element_to_be_clickable((AppiumBy.ID, 'com.android.settings:id/about_phone_preference'))) about_phone_element.click()

实操心得:在实际项目中,我通常结合使用隐式等待和显式等待。设置一个较短的全局隐式等待(如5秒)作为兜底,然后在关键操作(如点击、输入)前使用显式等待,并配上更有描述性的超时信息,这样脚本既健壮又高效。

4.2 页面对象模型 (Page Object Model, POM):让脚本清晰如诗

如果你的测试有10个步骤,把所有定位和操作都写在一个脚本里,很快就会变成一团乱麻。POM设计模式就是为了解决这个问题。它的核心思想是:将一个App页面(或一个功能模块)封装成一个Python类。这个类里包含这个页面的所有元素定位器,以及在这个页面上可能进行的操作(方法)。测试脚本则只关心业务流程,不关心具体元素怎么定位。

我们来重构刚才的设置脚本:

# base_page.py - 基础页面类,封装一些公共方法 from appium.webdriver.webdriver import WebDriver class BasePage: def __init__(self, driver: WebDriver): self.driver = driver def find(self, by, locator): return self.driver.find_element(by, locator) def click(self, by, locator): self.find(by, locator).click() # settings_home_page.py - 设置主页 from appium.webdriver.common.appiumby import AppiumBy from base_page import BasePage class SettingsHomePage(BasePage): # 页面元素定位器,集中管理,方便维护 ABOUT_PHONE_BTN = (AppiumBy.ID, 'com.android.settings:id/about_phone_preference') def click_about_phone(self): self.click(*self.ABOUT_PHONE_BTN) # 使用*解包元组 # test_settings.py - 测试脚本 from appium import webdriver from settings_home_page import SettingsHomePage desired_caps = {...} # 同上 driver = webdriver.Remote('http://127.0.0.1:4723', desired_caps) # 创建页面对象 home_page = SettingsHomePage(driver) # 执行业务操作 home_page.click_about_phone() driver.quit()

看,测试脚本变得多么简洁!如果“关于手机”按钮的ID将来变了,你只需要去SettingsHomePage类里修改一行代码,所有用到这个按钮的测试用例都会自动生效。这就是POM的魅力:高可维护性、低耦合、高复用性

4.3 常用操作API:模拟真实用户行为

除了点击和查找,Appium提供了丰富的API来模拟用户操作:

  • 输入文本element.send_keys(“Hello Appium!”)
  • 清空输入框element.clear()
  • 获取元素文本text = element.text
  • 滑动/滚动
    # 从屏幕中央向下滑动 driver.swipe(start_x=500, start_y=1000, end_x=500, end_y=200, duration=800) # 或者使用更通用的滚动查找(适用于Appium较新版本) driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR, 'new UiScrollable(new UiSelector().scrollable(true)).scrollIntoView(text("目标文本"))')
  • 返回键、Home键、菜单键
    driver.press_keycode(4) # 返回键 driver.press_keycode(3) # Home键
  • 启动其他App或Activity
    driver.start_activity(app_package='com.tencent.mm', app_activity='.ui.LauncherUI')

将这些API与POM结合,你就能编写出模拟复杂用户流程的健壮测试脚本了。

5. 实战:构建一个完整的自动化测试框架雏形

掌握了单个脚本的编写,我们需要向工程化迈进。一个完整的测试框架不仅仅是脚本的集合,它还应该包括测试数据管理、测试报告生成、异常处理、日志记录等。这里,我为你搭建一个最小化但五脏俱全的框架雏形,你可以以此为基础进行扩展。

5.1 项目目录结构

一个清晰的项目结构是良好维护的开始。

your_automation_project/ ├── config/ # 配置文件目录 │ └── config.yaml # 存放设备信息、App信息、服务器地址等 ├── logs/ # 日志文件目录(运行时生成) ├── reports/ # 测试报告目录(运行时生成) ├── page_objects/ # 页面对象类 │ ├── __init__.py │ ├── base_page.py │ └── *.py (各个页面的类) ├── test_cases/ # 测试用例 │ ├── __init__.py │ └── test_*.py (具体的测试文件) ├── utils/ # 工具类 │ ├── __init__.py │ ├── driver_manager.py # 驱动管理(单例模式) │ └── logger.py # 日志记录器 ├── conftest.py # Pytest的共享配置(钩子函数、夹具) └── requirements.txt # 项目依赖包列表

5.2 驱动管理与日志记录

utils/driver_manager.py:使用单例模式确保整个测试过程中只有一个driver实例,避免资源冲突。

from appium import webdriver import yaml import os class DriverManager: _instance = None def __new__(cls): if cls._instance is None: cls._instance = super().__new__(cls) cls._instance._init_driver() return cls._instance def _init_driver(self): # 从配置文件读取Capabilities config_path = os.path.join(os.path.dirname(__file__), '../config/config.yaml') with open(config_path, 'r', encoding='utf-8') as f: config = yaml.safe_load(f) self.driver = webdriver.Remote(config['appium_server'], config['desired_caps']) self.driver.implicitly_wait(config.get('implicit_wait', 5)) def get_driver(self): return self.driver def quit_driver(self): if self.driver: self.driver.quit() self._instance = None

utils/logger.py:良好的日志是调试的利器。

import logging import os from datetime import datetime def setup_logger(name): logger = logging.getLogger(name) logger.setLevel(logging.DEBUG) # 避免重复添加handler if not logger.handlers: # 创建logs目录 log_dir = os.path.join(os.path.dirname(__file__), '../logs') os.makedirs(log_dir, exist_ok=True) # 文件处理器 log_file = os.path.join(log_dir, f'automation_{datetime.now().strftime("%Y%m%d")}.log') fh = logging.FileHandler(log_file, encoding='utf-8') fh.setLevel(logging.DEBUG) # 控制台处理器 ch = logging.StreamHandler() ch.setLevel(logging.INFO) # 格式器 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') fh.setFormatter(formatter) ch.setFormatter(formatter) logger.addHandler(fh) logger.addHandler(ch) return logger

5.3 使用Pytest组织测试用例

Pytest是Python最主流的测试框架之一,它比自带的unittest更简洁强大。

test_cases/test_settings_about.py

import pytest from utils.driver_manager import DriverManager from utils.logger import setup_logger from page_objects.settings_home_page import SettingsHomePage logger = setup_logger(__name__) class TestSettingsAbout: @classmethod def setup_class(cls): """整个测试类开始前执行一次:获取驱动""" cls.driver = DriverManager().get_driver() cls.home_page = SettingsHomePage(cls.driver) logger.info("测试类初始化完成") @classmethod def teardown_class(cls): """整个测试类结束后执行一次:退出驱动""" DriverManager().quit_driver() logger.info("测试类清理完成") def test_open_about_phone(self): """测试用例:打开关于手机页面""" logger.info("开始执行测试:打开关于手机页面") try: self.home_page.click_about_phone() # 这里可以添加断言,例如判断是否成功跳转到了关于手机页面 # assert “关于手机” in self.driver.page_source logger.info("测试步骤:点击关于手机成功") except Exception as e: logger.error(f"测试执行失败: {e}") # 可以在这里附加截图,方便排查 screenshot_path = f"./screenshots/error_{self.__class__.__name__}.png" self.driver.save_screenshot(screenshot_path) logger.info(f"错误截图已保存至: {screenshot_path}") raise e finally: # 每个用例后可以做一些清理,比如按返回键回到主页 self.driver.press_keycode(4)

conftest.py:Pytest的共享夹具(fixture)可以在这里定义,供所有测试用例使用。

import pytest from utils.driver_manager import DriverManager @pytest.fixture(scope="session") def appium_driver(): """提供一个全局的driver fixture""" dm = DriverManager() driver = dm.get_driver() yield driver dm.quit_driver()

这样,你就可以在测试用例中直接使用appium_driver这个参数了。

5.4 运行测试并生成报告

安装pytest和报告插件:

pip install pytest pytest-html

运行测试并生成漂亮的HTML报告:

pytest test_cases/ -v --html=reports/report.html --self-contained-html

打开生成的report.html,你就能看到一个清晰的测试结果总览,包括通过/失败数、执行时间、错误日志等。这个框架雏形已经具备了企业级项目的基本要素:配置化、页面对象、日志、报告。你可以在此基础上,加入数据驱动(如使用pytest.mark.parametrize)、并发测试、邮件通知等功能。

6. 常见问题与排查技巧实录

即使按照最详细的指南操作,在实际动手时也难免会遇到各种“坑”。下面是我在多年实践中总结的一些高频问题和解决方法,希望能帮你快速排雷。

6.1 环境与连接类问题

问题1:adb devices列表为空,找不到设备。

  • 排查:首先确认USB线是否完好,并已连接电脑。在手机上确认“USB调试”已开启。对于某些手机(如小米、华为),可能还需要在开发者选项里开启“USB调试(安全设置)”或“仅充电模式下允许ADB调试”。如果还不行,尝试更换USB口,或重启ADB服务:adb kill-server然后adb start-server

问题2:Appium Server启动失败,端口被占用。

  • 现象:启动Appium时提示Could not start REST http interface listener. Requested port is already in use
  • 解决:默认端口4723被其他进程占用。可以终止占用端口的进程,或者更换Appium端口。在启动命令中指定新端口:appium -p 4724,同时在脚本里修改Remote连接的URL为http://127.0.0.1:4724

问题3:Session创建失败,提示An unknown server-side error occurred

  • 排查:这是最令人头疼的报错,因为它太笼统。首先,检查Desired Capabilities是否填写正确,特别是appPackageappActivity。确保你指定的App已经安装在设备上。其次,查看Appium Server的控制台日志,错误详情通常会在那一大段红字里。一个常见原因是automationName设置错误,对于较新的Android设备,务必使用UiAutomator2

6.2 脚本执行类问题

问题4:元素找不到 (NoSuchElementException),但我用Inspector明明能看到。

  • 原因1:等待时间不足。这是最常见的原因。UI还没加载出来,脚本就去查找了。务必使用显式等待(WebDriverWait)。
  • 原因2:页面有WebView或混合应用。Appium默认在原生(Native)上下文下操作。如果元素在WebView里,需要切换上下文。使用driver.contexts获取所有上下文,然后切换到对应的WebView:driver.switch_to.context(‘WEBVIEW_com.example.app’)
  • 原因3:元素在弹窗、浮层或新的Activity里。确保你的操作逻辑正确,并且使用了正确的页面对象。有时需要先关闭弹窗才能操作底层元素。

问题5:脚本在模拟器上运行正常,在真机上失败。

  • 排查:真机的性能、分辨率、系统定制化(如MIUI, EMUI)都可能带来差异。
    • 性能:在真机操作后增加等待时间。
    • 权限:真机上App可能首次运行会请求权限,你的脚本需要处理权限弹窗。可以尝试在Capabilities中添加autoGrantPermissions: true来自动授予权限。
    • 输入法:确保设备上安装了Appium自带的输入法(Unicode IME),并在Capabilities中设置unicodeKeyboard: trueresetKeyboard: true,以避免输入法兼容性问题。

问题6:如何滑动列表直到找到某个元素?

  • 方案:不要使用固定的坐标滑动,这在不同分辨率设备上会失效。使用UiScrollable定位策略(仅Android)是更可靠的方法,如前文示例。或者,可以写一个循环,在找不到元素时执行一个短距离滑动,然后重试查找,直到找到或达到最大尝试次数。

6.3 性能与稳定性问题

问题7:测试运行速度慢。

  • 优化点1:减少不必要的等待。用显式等待替代固定的time.sleep
  • 优化点2:复用Session。对于一组相关的测试用例,不要每个用例都重启App(即创建新Session),这非常耗时。使用Pytest的scope=”class”scope=”module”的fixture来管理driver的生命周期。
  • 优化点3:关闭动画。在开发者选项里,将“窗口动画缩放”、“过渡动画缩放”、“动画程序时长缩放”都设置为“关闭”,可以显著提升UI交互速度。

问题8:测试脚本不稳定,时而成功时而失败。

  • 这是UI自动化的经典难题。除了加强等待策略,还可以:
    • 重试机制:对于某些非关键性的偶发失败(如网络波动导致的元素加载慢),可以在代码层面加入重试逻辑。Pytest有插件pytest-rerunfailures可以实现用例失败重跑。
    • 断言前状态确认:在执行一个操作后(如点击登录),不要立即断言,先等待一个明确的成功状态出现(如跳转到主页)。
    • 截图辅助:在用例失败时自动截图并保存,如上文示例代码所示,这是定位问题最直观的方式。

6.4 高级技巧与资源

技巧1:使用adb shell命令辅助测试。 Appium的能力基于ADB,很多操作可以直接用ADB命令完成,更直接高效。例如:

  • 安装/卸载APK:adb install app.apk,adb uninstall com.package.name
  • 获取当前Activity:adb shell dumpsys window | findstr mCurrentFocus(Windows) /grep mCurrentFocus(Mac/Linux)
  • 模拟按键:adb shell input keyevent KEYCODE_HOME
  • 输入文本:adb shell input text “hello”

技巧2:关注Appium的日志级别。 默认的Appium日志非常冗长。在调试特定问题时,可以在Capabilities中设置showChromedriverLog: true来查看ChromeDriver的日志(对于WebView调试),或者调整Appium Server的日志级别。但通常,查看出错时间点前后Appium Server控制台打印的日志就足够了。

技巧3:利用好社区和文档

  • 官方文档:Appium官方文档是首要参考,虽然有些地方更新不及时,但核心概念和API是准确的。
  • GitHub Issues:当你遇到一个奇怪的错误时,有很大概率别人也遇到过。去Appium的GitHub仓库搜索相关Issue,往往能找到解决方案或临时Workaround。
  • Stack Overflow:搜索[appium]标签下的问题,是解决具体编程问题的最佳途径之一。

自动化测试的路上,踩坑是必然的。每一次解决问题的过程,都是你对Appium、对移动端技术栈理解加深的过程。不要害怕报错,学会阅读和理解错误信息,善用搜索工具,你解决问题的能力会在这个过程中飞速成长。记住,你现在遇到的绝大多数问题,都曾有先行者遇到过并解决了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/8 16:45:52

Qt+C++写的可直接运行的超级马里奥第一关,含完整工程与资源文件

本文还有配套的精品资源,点击获取 简介:用Qt 5.12和C开发的2D横版闯关游戏,完整实现超级马里奥第一关核心玩法:角色左右移动、跳跃、踩扁敌人、吃蘑菇变大、发射火球、钻管道、击碎砖块、抵达城堡终点。工程结构清晰&#xff0…

作者头像 李华
网站建设 2026/7/8 16:40:04

3分钟完成Windows和Office智能激活:KMS_VL_ALL_AIO完整使用指南

3分钟完成Windows和Office智能激活:KMS_VL_ALL_AIO完整使用指南 【免费下载链接】KMS_VL_ALL_AIO Smart Activation Script 项目地址: https://gitcode.com/gh_mirrors/km/KMS_VL_ALL_AIO 还在为Windows激活弹窗而烦恼?Office功能受限影响工作效率…

作者头像 李华
网站建设 2026/7/8 16:35:17

从Frida Hook到自动化逆向:构建高效动态分析流水线

1. 项目概述:为什么我们需要自动化逆向流水线? 逆向分析,尤其是针对移动应用或桌面软件的动态分析,长期以来都是一项高度依赖个人经验和手工操作的技术活。传统的流程通常是:打开目标应用,启动调试器或Hook…

作者头像 李华
网站建设 2026/7/8 16:31:52

STM32与TLE 6208-6G实现直流电机精确控制方案

1. 项目背景与核心组件选型在工业自动化和机器人控制领域,直流电机的精确控制一直是个经典课题。这次我选用STM32F100ZE作为主控芯片,搭配英飞凌的TLE 6208-6 G驱动芯片的方案,主要是看中了两者在性价比和性能上的平衡。STM32F100ZE属于Corte…

作者头像 李华
网站建设 2026/7/8 16:29:07

联邦学习隐私保护方案选择:同态加密与差分隐私的五大核心对比

1. 联邦学习隐私保护的十字路口:为什么选择比努力更重要 如果你正在为你的联邦学习项目寻找一个靠谱的隐私保护方案,那么恭喜你,你已经走在了正确的道路上。但当你打开技术文档,看到“同态加密”和“差分隐私”这两个词时&#xf…

作者头像 李华
网站建设 2026/7/8 16:27:47

RSA加密算法深度解析:从数学原理到实战应用与问题排查

1. 项目概述:从“黑盒”到“白盒”的RSA实战之旅 最近在排查一个线上服务的数据传输问题时,又遇到了那个熟悉又让人头疼的错误日志:“RSA public key not find”。这让我想起,无论是刚入行的开发者,还是像我这样摸爬滚…

作者头像 李华