Playwright自动化测试实战踩坑记那些年我遇到的诡异问题
移动端自动化测试的痛苦经历
之前做移动端项目的时候,每次发版前都要手动测试各种手机型号,iOS、Android各种系统版本,搞到人都快废了。UI稍微有点变动就要重新测试一轮,效率低得要死。后来老板看不下去了,说必须搞自动化测试。
一开始想用Selenium,但发现对移动端支持不够好,各种driver问题一大堆。后来看到Playwright官方说支持移动端模拟,就抱着试试的心态接入了。说实话,开始没想到能这么顺利,后面确实踩了不少坑。
基本配置就花了两天
官方文档看起来挺简单,实际配起来才发现一堆坑。首先是环境搭建,Node.js版本要求比较严格,老版本直接跑不起来。然后是移动端设备模拟,Chrome DevTools Protocol那套东西理解起来也有点绕。
const { chromium, devices } = require('playwright');
// 设备配置
const iPhoneConfig = {
...devices['iPhone 12'],
viewport: { width: 390, height: 844 },
deviceScaleFactor: 3,
isMobile: true,
hasTouch: true,
defaultBrowserType: 'chromium'
};
async function runTest() {
const browser = await chromium.launch({
headless: false // 开发阶段先设为false便于调试
});
const context = await browser.newContext(iPhoneConfig);
const page = await context.newPage();
await page.goto('https://jztheme.com/test-page');
// 这里开始各种移动端特有的操作
await page.waitForLoadState('networkidle');
await browser.close();
}
这里要注意的是,viewport和deviceScaleFactor的设置很关键,错了的话页面渲染会有偏差。刚开始我一直用默认的iPhone配置,结果某些页面的布局完全不对,折腾了半天才发现是这些参数的问题。
最大的坑:触摸事件处理
移动端最头疼的就是touch相关事件,click有时候不好使,需要模拟真实的touch操作。项目中有个轮播图组件,正常情况下需要滑动切换,但Playwright的默认click方法根本不管用。
// 最初的错误尝试
await page.click('.carousel-item'); // 完全无效
// 正确的触摸操作方式
await page.touchscreen.tap(100, 200); // 直接坐标点击
// 更复杂的滑动操作
await page.touchscreen.start(300, 500);
await page.touchscreen.move(100, 500); // 向左滑动
await page.touchscreen.end();
// 或者使用gesture方式
await page.gesture({
start: { x: 300, y: 500 },
end: { x: 100, y: 500 }
});
这里踩过好几次坑,开始用click模拟滑动,结果发现轮播图完全没反应。后来查文档才知道需要模拟真实的touch事件。还有个问题是,某些手机浏览器对touch事件的处理比较特殊,需要加上一定的延时。
性能优化是个大工程
刚跑起来发现一个问题,测试执行速度特别慢,一个简单的登录流程要跑半分钟。后来分析发现主要是页面加载等待和元素查找耗时太长。
// 优化前的写法
await page.waitForTimeout(3000); // 硬编码等待
await page.click('#submit-btn');
// 优化后的写法
await page.waitForSelector('#submit-btn', {
state: 'visible',
timeout: 10000
});
await page.locator('#submit-btn').click({
timeout: 5000,
force: true // 强制点击,忽略可见性检查
});
// 并行执行多个操作
const [response] = await Promise.all([
page.waitForResponse('**/api/login'),
page.click('#submit-btn')
]);
这里的timeout设置很重要,移动端网络不稳定,有时候请求会比较慢。force: true这个参数也很有用,某些元素可能被遮挡但仍然可以点击,普通click会失败。
还遇到个奇葩问题,某些低端安卓机模拟环境下,页面渲染特别慢,经常出现元素找到了但实际还没渲染完成的情况。最后加了个通用的等待机制:
async function waitForRender(page, selector) {
await page.waitForSelector(selector, { state: 'attached' });
await page.waitForTimeout(200); // 短暂等待渲染
await page.evaluate((sel) => {
const element = document.querySelector(sel);
if (element) {
const style = window.getComputedStyle(element);
return style.display !== 'none' && style.visibility !== 'hidden';
}
return false;
}, selector);
}
兼容性测试的真实感受
真正开始大规模测试才发现,不同设备的差异比想象中大。iOS和Android的字体渲染就不一样,某些元素在iPhone上位置正常,在Android上就偏移了。还有软键盘弹出的问题,会导致页面布局发生变化。
为了处理这些问题,写了大量的设备特异性代码:
async function handleKeyboard(page, inputSelector) {
const userAgent = await page.evaluate(() => navigator.userAgent);
if (userAgent.includes('iPhone')) {
// iOS特殊处理
await page.focus(inputSelector);
await page.waitForTimeout(500); // iOS键盘弹出需要时间
} else {
// Android处理
await page.click(inputSelector);
await page.keyboard.type('test input');
}
}
// 屏幕方向切换测试
await page.setViewportSize({ width: 844, height: 390 }); // 横屏
await page.waitForTimeout(1000);
await page.setViewportSize({ width: 390, height: 844 }); // 竖屏
这里其实有很多细节问题,比如某些Android机型输入框聚焦后页面会自动缩放,导致其他元素位置变化。这些都需要在测试中考虑到。
CI/CD集成的曲折路
最后要把测试集成到CI/CD流水线,这又是一堆问题。服务器环境没有图形界面,需要headless模式运行,但某些移动端特性在headless模式下表现不一致。
// CI环境配置
const launchOptions = process.env.CI ? {
headless: true,
args: [
'--disable-dev-shm-usage',
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-gpu'
]
} : {
headless: false
};
const browser = await chromium.launch(launchOptions);
还有并发执行的问题,同时跑多个设备测试容易内存爆掉。最后用了jest-puppeteer的方式,控制并发数量,避免资源冲突。
效果评估与遗留问题
经过一个月的折腾,自动化测试覆盖率达到了70%,确实大大减少了人工测试的工作量。回归测试时间从原来的2小时缩短到20分钟,这个提升还是很明显的。
不过还是有些问题没完全解决,比如某些H5游戏类功能还是需要手动测试,触控精度要求高的场景自动化也很难覆盖。还有就是测试数据的清理,移动端页面缓存比较复杂,有时候会影响测试结果。
整体来说,这次技术选型还是成功的。虽然前期踩坑比较多,但稳定运行后确实提升了效率。后续还会继续优化,主要是增加更多的断言检查和错误日志记录。
一点小心得
Playwright对移动端的支持确实是越来越好,但要想用好还是要花不少功夫。特别是要考虑到各种设备的差异,不能指望一套代码跑所有机型。建议从核心功能开始测试,逐步扩展覆盖范围,别一开始就想着全覆盖。
以上是我踩坑后的总结,希望对你有帮助。这个工具确实不错,但用起来还是有不少细节需要注意的地方。

暂无评论