Appium移动端自动化测试从入门到实战踩坑总结
Appium环境搭建,别被官方文档绕晕了
搞移动端自动化测试,Appium确实是个不错的选择。不过第一次接触这玩意儿的时候,光是环境搭建就能让人头疼半天。我踩过不少坑,现在回头看看,其实没那么复杂。
首先说Android环境。如果你已经在开发Android应用,那基本环境已经有了。Android SDK、JDK这些必须的工具要装好,ANDROID_HOME环境变量也要配置到位。我建议直接用Android Studio,它会帮你处理大部分环境配置。
# 验证Android环境
adb devices
Node.js也是必需的,因为Appium是基于Node.js的。npm安装appium-server的话:
npm install -g appium
npm install -g appium-doctor
appium-doctor这个工具特别有用,能检查你的环境配置是否完整。跑一下命令就知道哪里有问题了。
连接设备这步最容易出错
设备连接看似简单,实际上很多人在这里卡住。USB调试开了吗?设备识别了吗?这些都是基本功。我遇到过几次设备连接不稳定的情况,后来发现是USB线质量不行导致的。
const { AppiumDriver, AndroidConfig } = require('nativescript-dev-appium');
// 基本配置
const capabilities = {
platformName: "Android",
deviceName: "your_device_name", // adb devices看到的设备名称
appPackage: "com.yourapp.package",
appActivity: "MainActivity",
automationName: "UiAutomator2"
};
const driver = new AppiumDriver(capabilities);
这里要注意automationName的设置。Android建议用UiAutomator2,iOS用XCUITest。如果用错了,后面的元素定位会出现各种奇怪问题。
元素定位,XPath是最稳妥的选择
Appium的元素定位方式有很多,但我建议主要用XPath。虽然速度不如id或者class,但胜在稳定。特别是在复杂的界面中,XPath几乎能找到任何元素。
// XPath定位
const element1 = await driver.findElementByXPath("//android.widget.Button[@text='登录']");
await element1.click();
// 查找列表中的某个item
const listItem = await driver.findElementByXPath("//androidx.recyclerview.widget.RecyclerView/android.view.ViewGroup[2]/android.widget.TextView");
// 根据content-desc属性查找
const element2 = await driver.findElementByXPath("//android.widget.ImageView[@content-desc='返回按钮']");
这里有个坑:XPath在不同版本的Android上可能表现不一致。有些老版本对XPath支持不够完善,这时候可以结合resource-id或者text来定位。
TouchAction玩转手势操作
移动应用测试离不开手势操作。滑动、点击、长按这些都需要通过TouchAction来实现。我之前在一个电商项目的测试中,用这套方法测试商品列表的滑动加载功能。
// 滑动操作
const actions = driver.touchAction();
const size = await driver.getWindowSize();
// 向上滑动(刷新操作)
await actions
.press({ x: size.width / 2, y: size.height * 0.8 })
.wait(1000)
.moveTo({ x: size.width / 2, y: size.height * 0.2 })
.release()
.perform();
// 长按操作
const element = await driver.findElementByXPath("//android.widget.ImageView");
await actions.longPress(element).wait(2000).release().perform();
这里需要注意坐标计算。我通常用屏幕尺寸的百分比来确定起点和终点,这样适配不同分辨率的设备就没问题了。
处理弹窗和权限请求
应用启动时经常会有各种权限申请弹窗,这些如果不处理会阻塞测试流程。我用的方法是在capabilities里加上相关的配置:
const capabilities = {
platformName: "Android",
deviceName: "your_device_name",
appPackage: "com.yourapp.package",
appActivity: "MainActivity",
autoGrantPermissions: true, // 自动授权
dontStopAppOnReset: true, // 重启时不关闭app
noReset: true, // 不重置app状态
automationName: "UiAutomator2"
};
如果还有弹窗处理不了,就得在代码里专门处理:
try {
const permissionDialog = await driver.findElementByXPath("//android.widget.Button[@text='允许']");
if (permissionDialog) {
await permissionDialog.click();
}
} catch (e) {
console.log('没有找到权限弹窗');
}
这种处理方式虽然有点暴力,但确实管用。
等待策略,别让网络请求拖慢测试
Appium的等待机制很重要。移动端网络状况千变万化,数据加载时间也不固定。我之前犯过错误,用固定的sleep时间,结果测试变得很不稳定。
// 显式等待,推荐这种方式
const EC = protractor.ExpectedConditions;
await driver.wait(EC.presenceOf(element(by.id('some_id'))), 10000);
// 或者自己写等待函数
async function waitForElement(locator, timeout = 10000) {
const startTime = Date.now();
while (Date.now() - startTime < timeout) {
try {
const element = await driver.findElement(locator);
if (element) return element;
} catch (e) {
await driver.sleep(500);
}
}
throw new Error(Element not found within ${timeout}ms);
}
隐式等待和显式等待的区别一定要搞清楚。隐式等待是全局的,显式等待是针对特定元素的。
截图和日志,排错的好帮手
自动化测试跑着跑着就挂了,这是常有的事。截图功能在这种时候特别有用。每次失败都保存一张截图,能快速定位问题。
// 截图并保存
async function takeScreenshot(driver, filename) {
const screenshot = await driver.takeScreenshot();
const fs = require('fs');
fs.writeFileSync(./screenshots/${filename}.png, screenshot, 'base64');
}
// 在关键步骤加截图
await takeScreenshot(driver, step_${Date.now()});
日志记录也很重要。把关键的操作步骤和结果都记下来,方便后期分析测试报告。
并行测试,提升效率的关键
一个一个跑测试用例太慢了,得想办法并行执行。我的做法是给不同的设备分配不同的端口,然后同时跑多个实例。
// Appium server启动时指定端口
// appium -p 4723 -bp 4724
// appium -p 4725 -bp 4726
const capabilitiesDevice1 = {
port: 4723,
udid: 'device1_udid',
// 其他配置...
};
const capabilitiesDevice2 = {
port: 4725,
udid: 'device2_udid',
// 其他配置...
};
这样可以在不同设备上同时跑测试,效率提升明显。不过要注意设备资源竞争的问题。
踩坑提醒:这三点一定注意
首先,apk签名问题。不同环境下打包的apk签名可能不一致,导致安装失败。解决办法是用–no-sign选项跳过签名验证,或者保持构建环境一致。
其次,页面加载时机。有时候页面看起来加载完了,但实际上数据还没完全渲染。这时候去找元素就会找不到。建议根据关键元素的出现来判断页面是否真正可用。
最后,设备兼容性。不同品牌不同版本的Android ROM差异很大,特别是MIUI、EMUI这些定制系统。最好准备几台主流品牌的测试机,覆盖常见的使用场景。
以上是我用Appium做移动端自动化的一些实践经验,主要是踩坑后的总结。这个工具的拓展用法还有很多,后续会继续分享这类博客。

暂无评论