ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Appium移动端自动化测试实战:从环境搭建到框架设计

Appium移动端自动化测试实战:从环境搭建到框架设计 1. 为什么我最终选择了 Appium以及它能帮你解决什么问题先说结论如果你所在团队的业务同时覆盖 Android 和 iOS又希望用同一套代码维护自动化用例Appium 几乎是绕不开的选项。我前前后后折腾过 UIAutomator、XCUITest 原生方案也试过用 Macaca 做跨端尝试最后在生产环境里跑得最稳、社区问题最容易搜到答案的还是 Appium。原因不复杂。Appium 的核心思路是把移动端的自动化请求转成标准的 WebDriver 协议也就是把你熟悉的 Selenium 那套行为模式搬到手机上来。你在浏览器里 findElement、click、sendKeys到 Appium 里同样这样写。对于从 Web 自动化转过来的测试工程师来说学习曲线被拉得非常平。团队里有一个人熟悉 Selenium其他人照着他的代码风格抄作业就行。这套框架能解决的实际问题大概有三类回归测试的重复劳动。每次发版前手工把核心流程过一遍耗时两个小时起步而且人一累就容易漏点。Appium 把操作脚本化之后晚上挂机跑早上看报告就行。跨端用例的一致性问题。同样的登录流程Android 和 iOS 的控件定位方式完全不同但 Appium 允许你用一套代码通过不同的定位策略去兼容两端维护成本比维护两套脚本低不少。与 CI/CD 的衔接。Appium 有成熟的命令行启动方式和测试报告插件可以接到 Jenkins、GitLab CI 或者云测平台里实现提交代码后自动触发测试。适合谁来参考这篇指南我直接说清楚刚接触移动端自动化、卡在环境搭建这一步的测试新人从 Web 测试转向移动端的开发或测试工程师以及在现有框架上踩了不少坑、想系统梳理一遍技术选型和细节的测试负责人。我写这篇东西的原则是不堆理论所有步骤都是我实际跑通过的版本涉及的版本号、坑点、配置项都标出来了。你照着做大概率一次成功。不同版本的软件在安装细节上会有差异但核心逻辑是一样的。2. 环境搭建完整实操从零跑通第一个 Appium 脚本2.1 你需要准备哪些基础组件以及它们各自扮演什么角色环境搭建是劝退最多新人的地方因为涉及到的组件确实多。我第一次搭的时候装了又卸、卸了又装折腾了两天才把所有版本对齐。为了让你少走弯路我先用最直白的类比把每个组件的角色讲清楚。Node.jsAppium 本身是基于 Node.js 写的你可以理解成它是 Appium 的运行引擎。没有 Node.jsAppium 就是一堆无法执行的源代码。Appium Server用来接收你写的自动化脚本发来的指令然后转发给手机。它相当于一个翻译官把你的测试代码翻译成手机能听懂的指令。Appium Desktop现在叫 Appium Inspector这是调试工具帮你看手机屏幕上的控件结构找到每个按钮、输入框的定位属性。简单说它就是找元素定位的辅助工具。Android SDKAndroid 端要用到 adbAndroid Debug Bridge和 uiautomator2 等底层驱动这些都在 SDK 里。它负责建立起电脑和手机之间的通信通道。Xcode / Command Line ToolsiOS 端需要 Xcode 提供模拟器、签名工具和 XCTest 驱动能力。没有 XcodeAppium 无法在 iOS 设备上执行任何操作。Appium 客户端库比如 Java 的io.appium:java-client、Python 的Appium-Python-Client它就是你在代码里 import 的那个库用来编写测试逻辑。这些组件之间的关系我用一句话总结写好的脚本通过客户端库发送给 Appium ServerServer 再通过对应平台的原生驱动如 uiautomator2、XCUITest操作手机最后把执行结果返回给脚本。2.2 一步步搭建Windows/macOS 双平台实操记录我分别在 Windows 10 和 macOS 上完整搭过一遍下面把关键步骤和版本选择都列出来。先以 Android 环境为主iOS 环境单独写一节。第一步安装 Node.js在 Windows 上直接去官网下载 LTS 版本即可我用的版本是 16.x。macOS 上建议用 Homebrew 安装因为后续很多工具链比如管理 Appium 版本都依赖 brew 生态。# macOS 安装命令 brew install node安装完成后打开终端验证node -v npm -v能正确输出版本号说明安装成功。注意如果已经装过旧版本建议先彻底卸载再重装避免残留文件导致 Appium 版本冲突。我遇到过不少看似玄学的问题最后排查下来都是 Node 版本太老或太新导致的。第二步安装 Appium Server新版 Appium2.x 版本从老版本1.x变成了命令行安装和驱动管理的方式。这一步是很多旧教程没更新的地方。推荐直接全局安装npm install -g appium2.5.1验证安装结果appium --version如果顺利输出版本号说明 Server 安装完成。2.x 版本不再像 1.x 那样把所有驱动都内置而是采用了按需安装驱动的模式。所以还需要继续装驱动。第三步安装 Android 驱动appium driver install uiautomator2这条命令会下载并安装 Android 平台的自动化驱动之后 Appium 就是通过它来和 Android 设备通信的。安装完可以查看已安装的驱动appium driver list如果安装过程因为网络原因失败可以配置镜像源或者手动下载后解压到对应目录。这个坑我在后面常见问题章节会详细展开。第四步配置 Android SDK 环境变量在 Windows 上SDK 通常安装在你本地的 AppData\Local\Android\Sdk 目录macOS 上通常在 ~/Library/Android/sdk。需要手动配置环境变量否则 Appium 无法找到 adb 工具。# macOS 在 ~/.bash_profile 或 ~/.zshrc 中添加 export ANDROID_HOME$HOME/Library/Android/sdk export PATH$PATH:$ANDROID_HOME/platform-tools:$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin配置完成后执行adb devices如果能看到连接的设备说明 adb 工作正常。接着验证 uiautomator2 所需的 SDK 组件已经就位通常是确认存在adb、aapt等命令。第五步安装 Appium Inspector从官网下载对应系统的安装包即可。打开后要配置三个关键参数Remote Host 填127.0.0.1Port 填4723Path 填/wd/hub。这三个参数和你启动 Appium Server 时的监听地址必须完全一致。到这里环境层面的组件都齐了。2.3 iOS 环境的额外准备步骤如果你只做 Android可以跳过这一节。但只要你的业务涉及 iPhone下面这些配置无法绕过。首先是必须安装 Xcode并且建议保持 Xcode 主版本和 Appium 官方文档中支持的版本对齐。Appium 2.x 对 Xcode 版本比较敏感版本跨度太大会出现驱动初始化失败。其次需要安装 Appium 的 iOS 驱动appium driver install xcuitest还需要确保 Command Line Tools 已经安装xcode-select --install在真机调试的场景下还需要用 Xcode 配置开发签名Development Team。模拟器可以直接跑但真机如果不签名自动化用例会在启动阶段直接报错退出。我的建议是入门阶段先在模拟器上跑通整个流程等脚本稳定了再上真机。模拟器的启动速度和稳定性都比真机好很多适合用于框架验证和用例调试。2.4 验证环境跑通第一个真实脚本环境装完最关键的一步就是写第一个脚本验证所有组件能协同工作。这里我用 Python 示例因为 Python 的语法最直白团队里即便是非专业开发的测试人员也容易看懂。先安装 Python 客户端库pip3 install Appium-Python-Client然后准备一个 Android 模拟器如果还没有用 Android Studio 自带的 AVD Manager 创建一个启动后执行adb devices确认设备在线。下面这个脚本的目标非常简单打开系统设置应用获取当前页面的标题文字并打印出来。这一步能验证设备连接、Server 通信、元素定位全链路是否通畅。from appium import webdriver from appium.options.android import UiAutomator2Options options UiAutomator2Options() options.platform_name Android options.platform_version 13 options.device_name Android Test Device options.app_package com.android.settings options.app_activity .Settings options.automation_name UiAutomator2 options.no_reset True driver webdriver.Remote(http://127.0.0.1:4723/wd/hub, optionsoptions) # 等待页面加载完成 driver.implicitly_wait(10) # 尝试获取页面标题控件文本 title_elements driver.find_elements( xpath, //android.widget.TextView[contains(text, 设置)] ) for elem in title_elements[:3]: print(找到控件文本为, elem.text) driver.quit()执行前需要先启动 Appium Server。新开一个终端窗口输入appium看到类似Appium server ready的日志说明 Server 已经就绪。然后运行上面的 Python 脚本。控制台能输出控件文本内容说明全链路已经打通了你的框架基础已经启动成功。我第一次跑通的时候其实非常平静因为过程太顺了——反而后面遇到的真实项目问题更多。但这一步的意义是你有了一个可以去折腾的试验场后面所有复杂功能都可以基于这个最小脚本去扩展。3. 框架设计思路从能跑到好维护的演进路径环境通了只是一切的开始。真实项目里脚本数量从几个增长到上百个如果不做设计代码会迅速腐烂。你会发现同一个定位逻辑往三个文件里粘了三遍改一个控件属性要全局搜索替换。这个时候你就需要一套合理的框架结构来兜底。3.1 我从项目实战里沉淀出来的目录结构下面是我在几个实际项目里反复调整后沉淀下来的目录结构。它不是唯一的答案但经过了多个版本迭代能够覆盖大部分业务场景并且结构清晰、便于多人协作。每个目录的职责都非常单一新人接手时不会产生的歧义。test_framework/ ├── config/ │ ├── android_caps.yaml │ ├── ios_caps.yaml │ └── environment.yaml ├── pages/ │ ├── base_page.py │ ├── login_page.py │ └── home_page.py ├── test_cases/ │ ├── test_login.py │ ├── test_home.py │ └── conftest.py ├── resources/ │ └── test_app.apk ├── report/ │ └── (自动生成的测试报告) └── utils/ ├── driver_manager.py ├── logger.py └── assertion_helpers.py这套结构的设计逻辑很简单config存放所有环境的配置参数把 Android 和 iOS 的差异隔离在这里。改环境配置不碰代码方便不同环境切换。pages使用 Page Object 模式每个页面封装成一个类把元素定位和页面操作逻辑隔离。测试用例不直接写定位而是调用页面的方法。test_cases只写业务逻辑和断言。用例层的代码量会非常少核心是表达用户做了什么、期望什么结果。utils存放驱动初始化、日志、公共断言等工具类。这里是最容易被忽视但最值得花时间打磨的部分。3.2 为什么 Page Object 模式在移动端同样重要很多人觉得 Page Object 模式是 Selenium Web 自动化的专利在移动端就随便写写。这个认知是错误的。移动端的页面结构比 Web 更不稳定尤其是 Android 的版本碎片化同一控件的 id 在不同 ROM 里可能是完全不同的值。Page Object 模式的核心思想是把元素定位和业务操作拆开。测试用例只关心登录成功这个动作而不关心输入框的 resource-id 是 login_username 还是 et_account。如果不做这样的封装你可能会面临下面这个典型场景。项目进行到第二个月测试用例数量积累到 50 个以上某天产品经理说登录页的输入框控件改了属性。你在 IDE 里 Ctrl H 全局搜索旧 id发现 27 个文件都引用了这个控件。改完还不一定找得全漏掉一个就导致用例失败。这种维护成本足够拖垮一个测试项目。而有了 Page Object 模式只需要改login_page.py文件里的一个配置所有调用方自动生效。移动端的 Page Object 和 Web 端还有一点不同移动端有更多的交互方式比如滑动、长按、多点触控、Toast 提示校验等。这些都需要在 Page 层封装成可复用的方法而不是让每个测试用例自己写一遍。这样做的另一个好处是当 Appium 的 API 发生 breaking change比如从 1.x 迁移到 2.x你只需要修改 Page 层的驱动调用方式而不用逐个调整测试用例。3.3 驱动初始化与复用这块写不好脚本性能直接崩连接管理和会话复用是框架设计里最容易出错的地方。新手常犯的错误是每个测试用例都自己创建一个 driver 实例用例结束后直接退出。这在用例少时没问题但当用例数量超过 30 条你会发现每次启动 Appium 会话都要花 5~10 秒整个测试套件跑下来光连接消耗就占了三分之一的时间。我的做法是采用 pytest 的session级 fixture让整个测试过程只创建一次 driver并在所有用例结束时才清理。下面是用例文件conftest.py的完整示例import pytest from appium import webdriver from appium.options.android import UiAutomator2Options pytest.fixture(scopesession) def android_driver(): options UiAutomator2Options() options.platform_name Android options.platform_version 13 options.device_name emulator-5554 options.app ./resources/test_app.apk options.app_package com.example.app options.app_activity .MainActivity options.no_reset True options.new_command_timeout 60 driver webdriver.Remote(http://127.0.0.1:4723/wd/hub, optionsoptions) yield driver driver.quit()一个容易踩的坑是Appium 默认会话会在命令超时后自动关闭所以new_command_timeout必须设一个足够大的值否则用例间如果出现 60 秒内的停顿比如人工调试暂停会话会被服务端回收。在 iOS 上会话创建的时间往往比 Android 更长因为需要先启动模拟器再初始化 XCTest runner。如果你的测试套件里同时覆盖 Android 和 iOS建议按平台分开跑不要在一个进程里交替执行两种驱动避免资源竞争导致的随机失败。4. 元素定位实战从入门到看穿控件的独家经验4.1 移动端定位策略对比为什么 resource-id 不是万能药Appium 支持多种定位策略id、xpath、accessibility_id、class_name、android_uiautomator、ios_predicate_string 等。选择不同的定位策略执行速度和稳定性差异很大。我和团队在项目中做过简单的性能对比结论是idAndroid 的 resource-id和accessibility_idiOS 的 accessibility identifier是最快、最稳定的定位方式。而 xpath 的通用性最强但执行速度最慢且对页面层级变化极其敏感。一旦开发调整了布局层级xpath 就废了。下面用一个实际例子说明。假设某个登录按钮在 Appium Inspector 里能看到这些属性resource-id: com.example.app:id/btn_login text: 登录 class: android.widget.Button content-desc: 登录按钮 xpath: //android.widget.Button[resource-idcom.example.app:id/btn_login]我们的定位优先级通常是resource-id accessibility_id content-desc text xpath。只有当以上所有策略都无法唯一定位时才考虑使用 xpath并且要用相对路径而不是绝对路径。绝对路径长什么样比如这样//android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.RelativeLayout[1]/android.widget.Button[2]这种 xpath 一旦页面结构调整哪怕是加了一个无关的布局控件它也会立即失效。更合理的写法是利用稳定的属性组合//android.widget.Button[text登录 and resource-idcom.example.app:id/btn_login]优先选择与业务含义关联的属性减少对层级结构的依赖。这样开发调整布局时用例大概率还能继续运行。4.2 复杂控件定位列表滑动、动态加载、WebView 的实战处理移动端自动化最棘手的问题通常是三类。第一类是列表懒加载。比如电商 App 的商品列表只有滑动到底部才会加载新数据。定位某个不在屏幕内的元素时直接调用find_element会抛NoSuchElementException。这时候你需要先滑动再查找的循环逻辑def scroll_to_element(driver, target_text, max_swipes5): for _ in range(max_swipes): try: elem driver.find_element( xpath, f//android.widget.TextView[text{target_text}] ) return elem except Exception: size driver.get_window_size() start_x size[width] // 2 start_y int(size[height] * 0.8) end_y int(size[height] * 0.2) driver.swipe(start_x, start_y, start_x, end_y, 800) raise Exception(f滑动 {max_swipes} 次后仍未找到元素: {target_text})第二类是动态加载的内容。比如加载动画遮罩层消失了真正的元素才出现。mobile 端的兜底方案是配合显式等待等待某个元素出现后再操作from appium.webdriver.common.appiumby import AppiumBy from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC wait WebDriverWait(driver, 20) login_button wait.until( EC.presence_of_element_located( (AppiumBy.ID, com.example.app:id/btn_login) ) )第三类是 WebView 混合页面的定位。在 H5 页面里原生控件定位策略失效需要先切换上下文contexts driver.contexts print(当前上下文列表:, contexts) # 切换到 WebView通常是 contexts 里的最后一个 driver.switch_to.context(WEBVIEW_com.example.app) # 切换之后就可以像 selenium 一样用 css selector driver.find_element(css selector, .login-button).click() # 用完切回原生上下文 driver.switch_to.context(NATIVE_APP)这里有个经验之谈WebView 的加载需要一点时间切换前最好等contexts里出现WEBVIEW开头的项否则会报找不到上下文。4.3 使用 Appium Inspector 快速锁定目标元素Appium Inspector 的使用思路很多人第一天就学但真正用好它有三个小技巧。第一是快照功能。连接设备后点击刷新按钮Appium Inspector 会抓取当前屏幕的 UI 层级。如果页面内容很多有时需要点击选择模式才能点选具体控件这样看它的属性才准。第二是搜索模式。直接在搜索框输入resource-id或 text 名称它会自动高亮匹配的元素。这个功能在定位一些隐藏控件时很实用。第三是记录操作路径。Appium Inspector 有录制功能可以手动点击界面上的按钮它会自动生成对应的定位代码。这个功能虽然生成的代码不一定最优但用来快速了解控件属性关系足够了。5. 跨平台方案一套用例如何优雅地适配 Android 和 iOS如果只看 Android前面的内容已经能满足日常需求。但很多项目要求 Android 和 iOS 同时覆盖最核心的问题是如何处理两端在定位属性和行为逻辑上的差异。5.1 用动态定位策略统一两端的元素描述最直接也最易维护的方式是为同一个元素维护两份定位配置然后运行时根据平台选择。我的做法是在config里给每个元素定义一个字典element_binding { login_button: { android: (id, com.example.app:id/btn_login), ios: (accessibility_id, LoginButton), } }然后封装一个方法def find(driver, platform_name, binding): strategy binding[platform_name][0] value binding[platform_name][1] return driver.find_element(strategy, value)这样做的好处是把差异集中在一个文件里改配置不用动用例。但它有一个明显的缺点每个元素都要定义双份配置工作量翻倍。所以我的建议是只在两端属性确实不同的元素上做这种配置一些通用的 class 或 text 可以直接用同一策略。5.2 处理平台特有交互Toast 校验、手势操作和键盘差异Toast 校验是移动端自动化一个高频场景。Android 的 Toast 在 UI 层级里短暂出现后消失没有固定的元素定位早期版本需要用 uiautomator2 的方式去捕获。iOS 上没有完全对应的控件需要使用 predicate 字符串去匹配。下面是 Android 端的 Toast 校验脚本def get_toast_text(driver, timeout5): toast_locator ( xpath, //android.widget.Toast ) try: toast WebDriverWait(driver, timeout).until( EC.presence_of_element_located(toast_locator) ) return toast.text except Exception: return None注意Toast 出现的时机非常短默认等待时间不宜过长否则会拖慢用例执行速度。手势操作这块Android 和 iOS 的 API 有差异但 Appium 的TouchAction已经帮我们做了统一。比如长按操作from appium.webdriver.common.touch_action import TouchAction action TouchAction(driver) action.long_press(elementtarget_element, duration1000).perform()不过要提醒的是TouchAction在新版本 Appium 中已有废弃趋势官方开始推荐使用 W3C Actions API。新项目建议直接用ActionChains语法体系避免后续升级时的迁移成本。键盘弹起的处理是另一个隐藏坑。在 Android 上软键盘弹出后可能导致部分元素被遮挡自动化点击会点击到键盘区域。解决办法是先执行几个按压返回键的操作收掉键盘再点击元素driver.press_keycode(4) # Android 上的 back 键iOS 上可以通过点击键盘的搜索键或者背景空白处来收起键盘具体要看业务页面的交互设计。5.3 数据驱动不同平台、不同账号场景的用例组织当用例里需要覆盖多组数据时最简单的做法是复制用例然后改参数。这完全不可取。用 pytest 的参数化功能可以优雅地解决import pytest class TestLogin: pytest.mark.parametrize(username,password,expected, [ (test_user_01, 123456, 登录成功), (test_user_02, wrong_pass, 密码错误), (, 123456, 用户名不能为空), ], ids[success, wrong_password, empty_username] ) def test_login_scenarios(self, android_driver, username, password, expected): login_page LoginPage(android_driver) login_page.input_username(username) login_page.input_password(password) login_page.click_login_button() actual login_page.get_result_message() assert actual expected, f预期: {expected}, 实际: {actual}这种方式的好处是用例结构保持单一但数据覆盖量可以轻松达到几十条甚至上百条。如果后续需要使用 Excel 或 YAML 文件维护测试数据pytest 的parametrize也支持传入外部数据文件改动成本很小。6. 报告输出与 CI 集成让自动化真正落地到工作流脚本能在本地跑只是第一步要把自动化的价值体现在项目里得有稳定的报告和自动化触发机制。6.1 从 pytest 到 Allure 报告一套可视化的完整配置Allure 是目前最主流的测试报告框架它能把用例的执行状态、截图、步骤日志都整理成一份优雅的 HTML 报告。接入步骤很简单pip install allure-pytest执行测试时加上--alluredir./report/results参数测试结束后用命令行生成报告allure generate ./report/results -o ./report/html allure open ./report/html在实际项目中我通常会在 fixture 里写入失败截图逻辑让所有失败的用例自动截取当时屏幕状态并附加到 Allure 报告中。这对于定位问题非常有帮助import allure import pytest pytest.hookimpl(hookwrapperTrue) def pytest_runtest_makereport(item, call): outcome yield report outcome.get_result() if report.when call and report.failed: driver item.funcargs.get(android_driver) if driver: screenshot driver.get_screenshot_as_png() allure.attach( screenshot, name失败截图, attachment_typeallure.attachment_type.PNG )有了这个 hook每次用例失败后测试报告里会直接展示当时的界面截图排查效率提升非常明显。我建议所有项目在搭建的第一个星期就把这个功能加上。6.2 接入 Jenkins提交代码后自动触发 Appium 测试CI 集成并不复杂核心就是三件事确保测试环境有必要的依赖、启动 Appium Server、运行测试命令。在 Jenkins 上你可以新建一个流水线任务简单的做法是执行一段 Linux shell 命令# 启动 Appium Server后台运行 nohup appium --port 4723 appium.log 21 # 等待服务就绪 sleep 10 # 运行测试并生成结果 pytest test_cases/ --alluredir./report/results # 生成 Allure 报告 allure generate ./report/results -o ./report/html使用 Jenkins 的 Allure 插件可以把生成的report/html目录自动展示在任务页面上。团队其他人只需要打开 Jenkins 任务就能看到最新的测试结果和历史趋势。需要特别注意的是 CI 机器上的设备连接稳定性。Android 真机在长时间运行后可能出现 adb 连接断开的情况一个稳妥的做法是在 CI 任务开始前执行一次adb kill-server adb start-server再执行adb devices检查设备状态。设备离线时直接让任务失败避免浪费一整个晚上跑出一个没意义的报告。6.3 移动端性能数据的采集让自动化不止于点按钮既然热搜词里有移动端性能优化我也多说一点。Appium 不仅是功能测试工具也能用来采集性能数据。Android 上可以通过 driver 执行 adb 命令def get_cpu_usage(driver, package_name): # 执行 adb shell 命令获取 CPU 占用 result driver.execute_script( mobile: shell, {command: top, args: [-n, 1, -p, get_pid(driver, package_name)]} ) return parse_top_output(result)iOS 的性能数据获取相对受限但可以通过 Instruments 的命令行工具在 macOS 环境上做离线分析。这些性能数据可以被写入报告或单独落库用来监控关键版本之间的性能变化。不过这种玩法通常是在自动化框架已经稳定之后才扩展的初期不建议投入太多精力。7. 常见问题排查实录这些坑我踩过你直接绕过7.1 问题速查表一条条对照着查现象可能原因解决方案Could not find a connected Android deviceadb 没有识别到设备执行adb devices确认设备在线重新插拔执行adb kill-server adb start-server启动 Appium 时提示驱动未安装2.x 版本驱动按需安装执行appium driver install uiautomator2或appium driver install xcuitest元素定位时长时间无响应页面加载慢、控件未出现增加显式等待先验证 Appium Inspector 能否定位到元素脚本正常但参数被忽略Desired Capabilities 名称拼写错误严格对照官方文档确认大小写例如platformName而不是platformname升级 Appium 1.x 到 2.x 后脚本全面失败旧版配置项被移除查看 deprecation 警告逐条替换为新的 APIToast 短时无法捕获Toast 出现时间太短先定位 Toast 再执行触发操作或者使用更精确的 xpathiOS 模拟器启动慢首次启动 XCTest runner预先手动运行一次测试后续会快很多WebView 中 no such context未等待 WebView 加载完成等待contexts中出现WEBVIEW前缀再切换7.2 新手最容易忽略的三件事第一Node.js 版本锁死在一个 LTS 大版本。Appium 社区对 Node 版本的兼容测试主要集中在 LTS 上最新偶数版本可以尝鲜但如果出现诡异的依赖问题先降级到 LTS 试试。第二不要图省事不用 no_reset 参数。这个参数决定每次启动 Appium 会话时是否重置 App 的状态。如果设成 FalseApp 可以保留之前测试留下的数据状态提升执行速度。但它也会导致用例之间互相污染。稳妥的做法是关键流程用例用 no_resetFalse 保证环境干净重复执行的模块用 no_resetTrue 提速。第三Capabilities 里的 app 和 appPackage/appActivity 不要同时传入。很多新手把安装包路径和包名、启动 Activity 一起填Appium 虽然能用但行为不稳定。明确指定 app 从安装包安装时会让启动流程慢很多。实际项目里通常会先手动安装好 App然后在 Capabilities 里只传包名和启动 Activity。8. 我在真实项目中的沉淀与最终建议Appium 环境搭建本身并不难真正有价值的是框架设计思维。我从一个人闷头写脚本的低效模式逐步演进到 Page Object 数据驱动 报告输出 CI 集成的稳定模式之后最大的感受是自动化测试的核心价值不是省人工而是尽早发现问题并提供可靠依据。它应该成为研发流程里一个稳定的质量信号而不是一个反复需要人工维护的玩具。根据我个人经验团队首次搭建 Appium 框架时不必追求功能齐全先把最小可用闭环跑通环境通、定位稳、报告出、CI 跑。然后在这个基础上持续迭代把覆盖率从核心流程逐渐扩展到全业务。最后分享一个小技巧框架搭建初期不要在用例数量上急于求成先用五个用例把整个工程跑顺包括失败重试、截图上报、报告生成。五个用例稳定后再以每天三到五个用例的速度扩充你会发现后面越加越轻松。相反如果一开始就写五十个用例你会陷入无穷无尽的维护泥潭项目很快夭折。步子小一点反而到得快。
返回列表