资讯详情

资讯详情

App自动化测试入门:从环境搭建到跑通第一个脚本

做过App测试的人应该都有过这种经历功能测到第三轮每天都在重复安装-登录-下单-卸载点得手指发麻新机型一到手又得把整套冒烟用例在真机上从头过一遍偶尔半夜收到反馈说某个页面崩溃你还得手动复现半天才能定位问题。这时候你自然会想要是这些重复劳动能自动跑就好了。App自动化测试就是这么来的——用脚本代替人工去驱动手机上的App完成点击、输入、滑动、断言这一整套操作把回归测试从几小时压缩到十几分钟。这篇入门文章我会先讲清楚APP测试到底在测什么再带你把自动化环境从零搭起来从JDK、Android SDK到Appium Server最后跑通第一个真正能用的自动化脚本。适合刚接触测试不久、想转自动化的功能测试同学也适合想系统梳理环境搭建过程的在职测试工程师。1. APP测试到底在测什么先把定义吃透1.1 APP测试和Web测试的差异很多人刚入门时有个错觉App测试不就是浏览器测试换个壳吗实际上差别非常大。Web测试只要盯住浏览器兼容性同一套Chrome、Firefox用户行为基本一致但App测试面对的是碎片化严重的Android生态和相对封闭的iOS生态。你不仅要验证业务功能对不对还要考虑系统版本差异、屏幕分辨率适配、网络从4G切换到Wi-Fi的体验、来电和通知打断App时是否闪退、长时间驻留后台后内存是否异常增长甚至不同厂商ROM对自启动权限的不同处理。这些都是Web测试中不需要重点关注的维度。从测试类型上说APP测试可以拆成功能测试、兼容性测试、性能测试、安全性测试、稳定性测试和自动化测试几大块。功能测试验证业务流程是否正确兼容性测试覆盖不同机型、系统版本、屏幕尺寸性能测试关注启动时间、帧率、内存占用、CPU消耗稳定性测试则通过长时间运行、随机操作来暴露ANRApplication Not Responding应用无响应和闪退问题。自动化测试并不是独立于这些之外的东西它更像一种执行手段——把已经设计好的功能用例和冒烟用例用代码固化成脚本反复快速执行。1.2 自动化测试适合做什么、不适合做什么我自己的经验是自动化在回归测试和冒烟测试里性价比最高。App发版前核心路径登录、注册、下单、支付、消息列表必须在全量机型上验证一遍手工跑完一套需要大半天自动化脚本跑完只需要十几分钟而且结果可控、可留档。多版本回归时自动化还能帮你快速定位上个版本是好的、这个版本坏了是哪次提交引入的直接缩短问题排查范围。但自动化不是万能的。首次开发的新功能不建议直接自动化因为需求还在变界面元素频繁调整脚本维护成本会高到你想摔键盘。视觉层面的东西也不适合自动化比如按钮配色是否好看、文案是否有歧义、交互是否符合操作习惯这类问题需要人的主观判断。还有一个很多人忽略的点自动化对用例设计质量要求很高你的断言写得越精确脚本能发现的问题才越有价值。如果一个自动化用例跑完只验证页面没崩有内容显示那它基本等同于没测。2. 搭环境之前先想清楚四件事2.1 为什么是Appium而不是其他框架市面上做App自动化的工具不少老牌的Monkey、UI Automator、Robotium后来的Macaca、Airtest近几年流行的还有Maestro、Flutter自带的integration_test。我推荐新手从Appium入手主要原因是它跨平台、跨语言而且社区资料最多。Appium的核心设计思路是通过WebDriver协议来驱动手机上的App你在PC端写脚本脚本通过Appium Server转发命令最后由手机端的自动化引擎去执行实际操作。这个Server层把上层脚本和底层设备解耦了所以你可以完全用Python写代码不需要深入Android的Instrumentation机制。另一层考虑是生态。Appium对iOS和Android通吃Android端有UiAutomator2引擎iOS端有XCUITest引擎一套API风格、两套平台都能跑。就算你所在的公司暂时只测AndroidiOS自动化后面也未必没有需求与其到时候重新学一个框架不如一开始就选一个天花板足够高的。相比之下Airtest在游戏测试和图像识别上有优势但它的脚本组织和CI集成能力没有Appium成熟Monkey只能做随机压力测试根本写不了业务逻辑用例。初学者不用贪多先把Appium这一套彻底搞明白再去看别的工具会轻松得多。2.2 测试脚本语言Python还是Java这个问题几乎每个入门的人都会问。如果团队里已经有历史代码是用Java写的很多大厂的老自动化框架是JavaMavenTestNG那就跟团队保持一致没必要另起炉灶。如果是从零开始我强烈建议用Python。原因很简单语法简洁、写起来快Appium的Python客户端库封装到位断言库pytest、allure报告这些周边工具也都是现成的。你用Java写一个元素等待工具类可能要五十行Python里一个内置库加两行代码就搞定了。自动化脚本的核心价值是维护成本和执行效率不是工程化炫技。我自己对比过两种方式Java版本要处理Maven依赖、TestNG注解、各种静态类型声明新手光把代码编译通过就要折腾半天Python版本从写脚本到跑出第一条日志可能只需要十分钟。等脚本规模到了几千条再考虑引入更重的工程化体系也不迟。记住一个原则能用简单工具解决的问题不要一开始就引入复杂架构。2.3 真机还是模拟器模拟器的优势是创建快、配置灵活、不占用实体设备。Android Studio自带的AVD、第三方的MuMu、夜神都挺好用。但模拟器有一个无法回避的问题它不等于真机。CPU架构、GPU渲染方式、触摸事件上报频率都和真机有差异很多偶发性Bug只有在真机上才复现得出来。而且从Appium连接模拟器这件事本身也偶尔会踩坑SDK路径不对、端口冲突、ADB版本不一致多一个变量就多一个排查点。我的建议是日常开发调试用模拟器速度快、截图方便正式的兼容性回归测试必须用真机。真机也不需要买一堆主流的两三个品牌各准备一台不同Android版本的机型基本能覆盖绝大部分兼容性问题。入门阶段你手头随便一台Android手机只要是Android 7以上就行插上电脑开始练完全没问题。如果用iOS那就只有真机一条路Xcode的模拟器Appium也能跑但配置链路过长新手不建议一上来就碰。2.4 版本矩阵一条最容易踩坑的暗线App自动化环境搭建百分之八十的坑都出在版本匹配上。拿一套我现在验证过的组合给你参考JDK 11Android Gradle插件要求JDK 11以上但Appium本身并不挑剔JDK 8也能用Android SDK Platform-Tools保持最新包含最新版ADBAppium Server用2.x现在npm上默认安装就是2.xAppium的UiAutomator2驱动单独用appium driver install uiautomator2安装Python用3.9以上appium-python-client用2.x注意2.x的API和1.x有差异网上很多老教程是1.x语法照着写可能会报错。这里最烦的问题是Appium 2.x把驱动拆分出去了很多旧教程里npm install -g appium装完就算完事结果启动session时报错说找不到uiautomator2其实就是缺了驱动安装这一步。后面我会在实操环节把这步讲透。你搭环境的时候先把自己用的所有组件版本记下来写在一张表里遇到问题先排查版本匹配能省掉大量时间。组件推荐版本说明JDK118也可用于Android SDK和部分工具链Android SDK Platform-Tools最新稳定版提供ADB工具Appium Server2.x通过npm安装驱动需单独安装UiAutomator2 Driver最新版Appium 2.x的Android执行引擎Python3.9脚本语言appium-python-client2.xPython客户端库3. 环境搭建实操从JDK到第一个自动化会话3.1 JDK和Android SDK的安装与验证先装JDK。Windows直接去Oracle官网下载安装包macOS推荐用Homebrew执行brew install openjdk11。安装完成后最关键的一步是配置环境变量Windows用户在系统变量里新建JAVA_HOME指向JDK安装目录再把%JAVA_HOME%\bin追加到Path变量中。配置完打开一个全新终端窗口执行java -version能正常输出版本号就成功了。如果终端一直提示找不到命令多半是Path没配好或者没开新窗口重新打开一个终端再看别在旧窗口里反复试。Android SDK的安装是环境里的重头戏。最省事的方案是下载Android Studio安装后打开SDK Manager把Platform-Tools装好。其实你不一定需要完整的Android Studio但通过它的SDK Manager来管理SDK组件最不容易出错而且Android Studio本身做元素定位后面要用的Appium Inspector也可以单独装时会用到。装完后把ANDROID_HOME环境变量指到SDK目录再把platform-tools目录加进Path。在终端执行adb --version能看到版本号就说明ADB已经能用了。这里有一个新手容易忽略的细节ANDROID_HOME和ANDROID_SDK_ROOT在有些老工具里是两个不同的变量Appium 2.x主要认前者但为了兼容旧工具链我习惯两个都设置成同一个路径。另外在macOS上SDK默认路径是~/Library/Android/sdkWindows上通常是%LOCALAPPDATA%\Android\Sdk设置环境变量的时候千万别写错。3.2 Appium Server与Python客户端的安装Appium Server是连接脚本和手机的桥梁2.x版本通常用npm全局安装。先确认你本机有Node.js环境然后用下面这条命令npm install -g appium装完执行appium --version确认版本。重点来了2.x版本默认不带Android驱动需要单独执行appium driver install uiautomator2我用的是uiautomator2驱动它在Android 7及以上机型上表现稳定而且元素定位速度比老的selendroid快很多。如果你要跑iOS还需要执行appium driver install xcuitest。驱动安装好以后可以顺手跑一下appium-doctor来检查环境完整性npm install -g appium-doctor appium-doctor它会逐项检查JAVA_HOME、ANDROID_HOME、Node、ADB等组件是否就绪哪个缺失一眼就能看出来。这条命令值得在出现问题时第一时间运行比翻日志高效得多。Python客户端库安装很简单pip install Appium-Python-Client装完执行pip show Appium-Python-Client检查版本。如果之前装过旧版建议先升级到2.x因为新版API把desired_capabilities相关的写法调整了一下混用新旧版本很容易踩坑。3.3 连接设备与desired capabilities配置先用数据线把Android手机连到电脑上然后打开手机的开发者选项把USB调试打开。不同品牌的开启方式略有差异但通用的办法是连续点击版本号七次返回设置页就能看到开发者选项了。在终端执行adb devices正常情况下输出的列表中会看到你的设备编号后面跟着device状态。如果显示unauthorized说明手机上的授权弹窗被忽略了手动在手机上确认即可如果什么都看不到优先换一根能传数据的数据线很多所谓充电线根本没有数据传输引脚。设备连上之后就可以写第一段自动化脚本了。Appium的会话是由一个叫做desired capabilities的字典发起的它告诉Server你要测什么、用什么引擎、连接哪台设备。最简配置如下from appium import webdriver from appium.options.android import UiAutomator2Options options UiAutomator2Options() options.platform_name Android options.platform_version 13 options.device_name Pixel_6 options.app /path/to/your_app.apk options.automation_name UiAutomator2 options.no_reset True driver webdriver.Remote(http://127.0.0.1:4723, optionsoptions)逐个解释这些字段的含义platform_name是操作系统类型platform_version是Android版本号device_name是设备标识这里填什么其实不会报错但最好和adb devices里看到的编号靠拢app是你待测APK的绝对路径automation_name指定用哪个自动化引擎no_reset表示不要清空App的数据——第一次启动时如果不清数据可以节省安装时间但调试阶段建议改成False保证每次都是从干净状态开始。注意这里我用了UiAutomator2Options这个写法这是appium-python-client 2.x推荐的封装方式。如果你在网上看到desired_caps {...}这种老写法也能跑但要确认客户端版本是1.x。两套写法别混着用。执行脚本前先启动Appium Serverappium或者指定端口appium -p 4723然后运行你的Python脚本只要看到driver初始化没有抛异常就说明环境已经通了。3.4 跑通第一个脚本启动App并断言首页环境通了之后我建议你马上写一个带断言的最小用例把启动、点击、验证、退出这一整个链路跑通这比只验证能启动会话有意义得多。下面这段示例脚本做的事情是打开App等待登录页出现输入用户名和密码点击登录然后断言首页上有某个期望元素。from appium import webdriver from appium.options.android import UiAutomator2Options from appium.webdriver.common.appiumby import AppiumBy from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC options UiAutomator2Options() options.platform_name Android options.platform_version 13 options.device_name Android_device options.app /path/to/your_app.apk options.automation_name UiAutomator2 options.no_reset False driver webdriver.Remote(http://127.0.0.1:4723, optionsoptions) try: wait WebDriverWait(driver, 20) # 等待并输入用户名 username wait.until( EC.presence_of_element_located((AppiumBy.ID, com.example.app:id/username)) ) username.send_keys(test_user) password driver.find_element(AppiumBy.ID, com.example.app:id/password) password.send_keys(test_pass) driver.find_element(AppiumBy.ID, com.example.app:id/login_btn).click() # 等待首页加载出来断言某个关键元素可见 home_element wait.until( EC.visibility_of_element_located((AppiumBy.ID, com.example.app:id/home_title)) ) assert home_element.is_displayed(), 首页没有加载出来 print(登录流程自动化通过) finally: driver.quit()这段脚本里有几个值得细看的地方。WebDriverWait和expected_conditions是Selenium体系的组件Appium继承了这一套写法作用是在元素还没出现在屏幕上时自动等待避免因为页面加载速度波动导致脚本偶发失败。AppiumBy.ID指定了定位策略实际项目里最常用的是ID定位但有些App的控件没有设置resource-id这时候可以用AppiumBy.XPATH、AppiumBy.CLASS_NAME或者用AppiumBy.ACCESSIBILITY_ID按content-desc属性定位。定位策略的选择直接影响脚本稳定性后面我会在常见问题里专门聊。脚本跑完会输出登录流程自动化通过如果过程中任何一个元素没找到就会在对应步骤抛异常这样可以精确知道卡在哪一步。接下来你就能从这个最小模板出发慢慢扩展出完整业务用例了。4. 常见问题与排查技巧实录4.1 adb连接不上设备怎么办adb devices列表空白这个问题我遇到太多次了新手阶段更是高频。先别急着怀疑人生按顺序排查第一步换一根数据线必须是带数据传输功能的线别用充电线第二步检查手机的USB调试开关有没有真的打开有些手机在开发者选项里打开USB调试之后还需要额外开启USB调试安全设置之类的子选项第三步把手机连接模式从仅充电切成文件传输或MTP部分手机在纯充电模式下不会暴露ADB接口第四步重启ADB服务执行adb kill-server再adb start-server。如果以上都无效再检查是不是安装了多个ADB工具导致版本冲突——比如Android Studio自带一个ADB第三方模拟器又带一个两个版本在不同的路径下打架应用adb --version看看路径来源手动删掉多余的那个。还有一类问题是设备显示为offline这通常是手机和电脑之间的ADB版本不匹配造成的。优先保证platform-tools是最新版重启手机和ADB服务一般能解决。真机调试的另一个高频场景是Android 13及以上的系统多了一个无线调试选项如果你用的是无线连接调试配对过程稍微复杂一点容易被忽略入门阶段还是优先用数据线等跑通流程再尝试无线方案。4.2 Session创建失败capability写错还是端口被占用Session创建失败是环境搭建里最让人沮丧的问题之一因为报错信息往往很笼统。你需要学会看Appium Server那侧的输出日志。启动Appium Server时加上--log-level debug可以看到更多细节appium --log-level debug常见的失败原因有三种。第一种是端口被占用4723端口被别的实例占了启动新Server时指定其他端口appium -p 4725同时脚本里的连接地址也要对应改成http://127.0.0.1:4725。第二种是capability里platform_version填的版本号跟设备实际版本不一致比如设备是Android 12你还是填了13。第三种是app指向的APK路径不存在或权限不对Appium在推送App到设备前会校验本地文件路径写错的话第一时间就会报错。一个比较隐蔽的坑是Windows上APK路径如果包含空格有可能导致Appium找不到文件。解决办法是直接用正斜杠路径并且尽量把APK放在一个纯英文、没有空格的目录下。4.3 UiAutomator2与Appium版本兼容问题如果你装了Appium 2.x但是没有手动安装UiAutomator2驱动执行脚本时会直接提示找不到uiautomator2。解决方式就是前面提到的appium driver install uiautomator2。但如果已经装了还是报错查看一下驱动版本是不是太老appium driver list能列出已安装的驱动以及版本号。驱动更新命令是appium driver update uiautomator2还有一个常见场景手机上已经安装过一个旧版的io.appium.uiautomator2.server和io.appium.uiautomator2.server.test当Appium尝试重新部署驱动时可能因为签名冲突而失败。把这两个应用从手机上卸载重新跑脚本让Server重新安装通常就能解决。症状优先排查方向解决动作session创建失败驱动是否安装appium driver list缺失就installsession创建失败端口占用换端口或杀掉占用进程session创建失败设备版本不匹配核对platform_version元素找不到定位策略不对切换ID/XPATH/ACCESSIBILITY_ID升级失败驱动版本过旧appium driver update4.4 元素定位的经典翻车现场元素定位不稳定是自动化用例线上跑挂的主要原因而且在入门阶段就一定会遇到。最典型的一种情况是脚本在本地跑得好好的一放到CI机器上就各种元素找不到。原因通常是App在不同网络环境下加载的元素树不一样或者页面弹窗、广告遮挡了目标元素。解决思路是不要依赖一个元素的单一属性尽量多写几个备用定位器在关键步骤前先处理掉可能出现的弹窗比如把同意用户协议知道啦等引导按钮先点掉。另一个提升稳定性的好习惯是使用显式等待而不是固定time.sleep(x)。固定等待看着简单但线上网络抖动时要么等不够、要么浪费时间。用WebDriverWait配合expected_conditions可以在元素出现时立即执行下一步这才是自动化脚本该有的样子。我见过不少新人用一串time.sleep(3)把脚本跑通结果机器稍微卡顿就直接翻车排查时根本分不清哪个睡等是为了哪个页面加载。定位控件还有一个实用技巧Appium Inspector真机连接后在UI树里能直接看到元素的resource-id、content-desc和xpath路径不需要你手动猜属性。拿到元素之后尽量优先用ID或ACCESSIBILITY_IDxpath尽量不用绝对路径/hierarchy/android.widget.FrameLayout/...这种一旦界面层级调整必挂。写xpath时多用相对路径配合text或者contains匹配例如//android.widget.TextView[contains(text, 登录)]这样的定位器对界面微调有更强的适应力。最后再分享一点经验环境搭建跑通只是万里长征的第一步后面你维护脚本花的时间一定比写脚本多这是正常的。先从一个App的三五个核心冒烟用例开始做别贪多脚本量超过一百条以后维护成本会陡增这时候你才会真正理解为什么用例设计、定位策略、等待方式这些软技能那么重要。另外一个实用建议把自己每个阶段装的组件版本号随手记在项目README里下次换电脑搭环境会感谢现在的自己。调试的时候多看Appium Server日志少猜绝大多数问题的答案都在日志里。祝顺利跑通第一个脚本。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →