如何在WebdriverIO+Appium测试流程中检测React Native Android应用崩溃?
检测React Native Android应用崩溃(基于Appium+WebdriverIO)
因为你的应用崩溃时没有弹窗,得从应用进程状态、页面核心元素可达性、系统日志这几个维度入手,结合你提到的事件监听、try-catch、assert来落地。下面给你具体的实现方案和代码示例:
一、用WebdriverIO事件监听器做全局崩溃检测
WebdriverIO自带生命周期事件,你可以在每个测试命令执行后自动检查应用是否存活。比如在配置文件里注册全局命令,再绑定到afterCommand事件:
// wdio.conf.js 中的配置 exports.config = { // 其他配置(比如Appium服务地址、设备参数)... onPrepare: async function () { // 注册自定义的崩溃检测命令 browser.addCommand('checkAppAlive', async function () { const packageName = await this.getCurrentPackage(); // 替换成你的RN应用包名,比如com.yourapp // 用adb命令检查应用进程是否存在 const processCheck = await this.executeShellCommand(`ps -A | grep ${packageName}`); if (!processCheck.stdout.trim()) { await this.saveScreenshot(`crash-${Date.now()}.png`); // 崩溃时自动截图 throw new Error(`应用崩溃:${packageName} 进程已终止`); } // 额外检查:尝试访问应用的核心根元素(比如RN里的testID="app-root") try { await this.$('~app-root').waitForExist({ timeout: 3000 }); } catch (err) { await this.saveScreenshot(`crash-element-${Date.now()}.png`); throw new Error(`应用无响应:核心元素不可达,疑似崩溃`); } }); }, // 每个命令执行后自动触发崩溃检测(排除一些无关命令) afterCommand: async function (commandName) { const skipCommands = ['screenshot', 'getLog', 'executeShellCommand']; if (!skipCommands.includes(commandName)) { await browser.checkAppAlive(); } } };
二、Try-Catch+断言做局部关键操作检测
在触发复杂逻辑的操作(比如提交表单、跳转页面)后,用try-catch包裹断言,区分是普通断言失败还是应用崩溃:
describe('RN应用核心流程测试', () => { it('提交表单后检测应用状态', async () => { // 模拟关键操作:填写表单并提交 await $('~input-username').setValue('test-user'); await $('~submit-form').click(); try { // 断言跳转后的页面元素存在 await expect($('~success-page')).toBeDisplayed({ timeout: 5000 }); } catch (assertErr) { // 进一步验证是否是崩溃导致的元素不可达 const packageName = await browser.getCurrentPackage(); const processStatus = await browser.executeShellCommand(`ps -A | grep ${packageName}`); if (!processStatus.stdout.trim()) { console.error(`应用崩溃:提交表单后进程终止`); await browser.saveScreenshot(`crash-submit-${Date.now()}.png`); throw new Error(`应用崩溃:提交表单后进程终止,原错误:${assertErr.message}`); } else { // 不是崩溃,只是元素加载超时,抛出原断言错误 throw assertErr; } } }); });
三、解析Android Logcat日志抓崩溃
RN应用崩溃时,Android系统日志(logcat)会输出崩溃堆栈,你可以通过Appium获取logcat并筛选关键词:
// 自定义命令:检查logcat中的崩溃日志 browser.addCommand('checkCrashInLogcat', async function () { const logcatLogs = await this.getLogs('logcat'); // 筛选RN崩溃或Android致命异常的日志 const crashLogs = logcatLogs.filter(log => log.message.includes('FATAL EXCEPTION') || log.message.includes('ReactNative: Error') || log.message.includes('AndroidRuntime: Shutting down VM') ); if (crashLogs.length > 0) { const crashDetails = crashLogs.map(log => `${log.timestamp}: ${log.message}`).join('\n'); console.error(`检测到崩溃日志:\n${crashDetails}`); await browser.saveScreenshot(`crash-logcat-${Date.now()}.png`); throw new Error(`应用崩溃,日志详情:\n${crashDetails}`); } }); // 在测试用例中使用 it('执行复杂操作后检查logcat', async () => { await $('~load-complex-data').click(); await browser.checkCrashInLogcat(); });
四、日志与错误处理优化小技巧
- 用日志工具(比如winston)把崩溃日志按测试用例、时间分类写入文件,方便后续排查。
- 结合Selenium Grid的话,可以在Grid节点上配置日志收集,把每个测试会话的崩溃日志同步到中心存储。
- 崩溃时除了截图,还可以导出当前的Appium会话日志,便于定位问题。
内容的提问来源于stack exchange,提问作者punkuotukas
相关产品推荐
相关产品推荐

