我们可以在命令行中执行 adb install 安装某个应用,会发现快速返回 Success 了,而实际应用正在安装中,这种情况下,appium 会误以为被测应用已经安装上了,然后去启动这个 app,结果发现 app 不存在(appium 重重试一次,仍然失败),这种情况下,appium 测试 100% 会失败。

事故手机:OPPO R9sk

测试的 Appium 版本:1.12.1

解决方案

找到安装 app 的地方,安装完后,检测 app 是否真正安装成功了,如果没成功,则等待,直到超时或者成功安装。

实施办法

针对 UIAutomator1,我们需要更改 appium-android-driver,我们找到 lib/driver.js 的 initAUT 方法,在代码 await helpers.installApk(this.adb, this.opts);后加上这个检测过程:

await helpers.installApk(this.adb, this.opts);
log.info('安装应用后,检查被测应用是否存在');
await this.waitPackagePresent(60000);

waitPackagePresent 就是这个检测过程的方法,代码如下:

/**
  * 一定时间内等待某包出现
  */
 async waitPackagePresent (timeout) {
   log.info(`waitPackagePresent: ${timeout}`);
   let start = new Date().getTime();
   while (new Date().getTime() - start < timeout) {
     const appState = await this.adb.getApplicationInstallState(this.opts.app, this.opts.appPackage);
     log.info(`app state is ${appState} 1`);
     switch (appState) {
       case 'notInstalled':
         log.info(`检测到${this.opts.appPackage}尚未安装上,等待1s,继续检测`);
         await sleep(1000);
         break;
       default:
         log.info('被测应用已安装上');
         return true;
     }
   }
   log.errorAndThrow(`Could not find package ${this.opts.appPackage} on the device in ${timeout}`);
 }

而针对 UIAutomator2 的话,同样我们找到 UIAutomator2 的 nodejs 驱动工程:appium-uiautomator2-driver,然后找到 lib/driver.js,同样也是在 initAUT 方法中:

if (this.opts.app) {
  if (!this.opts.noSign && !await this.adb.checkApkCert(this.opts.app, this.opts.appPackage)) {
    await helpers.signApp(this.adb, this.opts.app);
  }
  await helpers.installApk(this.adb, this.opts);
  await this.waitPackagePresent(60000); // 这是新增
}

waitPackagePresent 方法同上。

更多请关注知乎专栏:https://zhuanlan.zhihu.com/custom-appium


↙↙↙阅读原文可查看相关链接,并与作者交流