Appium Appium autoLaunch 问题

Kilmer · 2015年04月17日 · 最后由 Jia.Q 回复于 2020年07月22日 · 3890 次阅读

我整套环境是在 Appium 源码环境下进行。

autoLaunch 设置为 False 时,脚本无法做任何动作,看一下相关代码:

if (this.device.args.autoLaunch === false) {
    // if user has passed in desiredCaps.autoLaunch = false
    // meaning they will manage app install / launching
    if (typeof this.device.noLaunchSetup === "function") {
      this.device.noLaunchSetup(function (err) {
        if (err) return cb(err);
        cb(null, this.device);
      }.bind(this));
    } else {
      cb(null, this.device);
    }
  } else {
    // the normal case, where we launch the device for folks

    var onStart = function (err, sessionIdOverride) {
      if (sessionIdOverride) {
        this.sessionId = sessionIdOverride;
        logger.debug("Overriding session id with " +
                    JSON.stringify(sessionIdOverride));
      }
      if (err) return this.cleanupSession(err, cb);
      logger.debug("Device launched! Ready for commands");
      this.setCommandTimeout(this.desiredCapabilities.newCommandTimeout);
      cb(null, this.device);
    }.bind(this);

    this.device.start(onStart, _.once(this.cleanupSession.bind(this)));
  }

this.device.start(onStart, _.once(this.cleanupSession.bind(this)));
只有在 device.start 函数中才会才会实例化 Uiautomator 对象,然后建立与 Bootstrap 的 Socket 连接。
而这步骤只有在 autoLaunch 为 True 的情况才能执行。

看一下 noLaunchSetup 函数的具体内容:

Android.prototype.noLaunchSetup = function (cb) {
  logger.debug("Setting up Android for 'autoLaunch: false'");
  async.series([
    this.initJavaVersion.bind(this),
    this.initAdb.bind(this),
  ], function (err) { cb(err); });
};

只有 initJavaVersion 和 initAdb ,完全没有初始化 AppiumServer 对象下 Android 对象(也就是 device)的 Uiautomator 对象。
如果是这样,那 autoLaunch=False 的情况,脚本岂不是完全不能做动作?

将 noLaunchSetup 修改为:

Android.prototype.noLaunchSetup = function (cb) {
  logger.debug("Setting up Android for 'autoLaunch: false'");
  async.series([
    this.initJavaVersion.bind(this),
    this.initAdb.bind(this),
    this.initUiautomator.bind(this),
    function (cb) {this.uiautomator.start(cb);}.bind(this)
  ], function (err) { cb(err); });
};
``
就可以了

这是代码的Bug还是设置autoLaunch 为Flase后还要设置其他的参数才能在脚本中做动作

请大神解答一下
共收到 8 条回复 时间 点赞

autoLaunch 配置为 false 是设计给手动 launch 被测应用这样的场景使用的(例如我测试场景下的被测应用需要跳转到另一个指定应用,因此需要安装两个应用,这时候默认只安装被测应用这种设计就不够用了)。手动 launch 的相关文档:
https://github.com/appium/appium/blob/89dbea6bcbbe17498206f61aeee243592ac7ac5d/docs/cn/writing-running-appium/appium-bindings.cn.md#%E5%90%AF%E5%8A%A8-launch

autoLaunch 的默认值是 true

默认值是 True

True 的话流程会走 Android.prototype.start。

我想确定是源码里面的情况是 False 就不会初始化 Uiautomator 的对象这种情况是源码的 bug,还是故意这样设计的,或则说这样设计有啥作用没?

#2 楼 @kilmer 代码的注释里已经说得够清楚了

// if user has passed in desiredCaps.autoLaunch = false
// meaning they will manage app install / launching

翻译过来就是:如果用户设置了 desiredCaps.autoLaunch = false,那么这意味着他们会负责管理应用的安装/启动。

这是 autoLaunch 本身的设计目的,不是 bug 。

另外,麻烦加一下头像。。。

#3 楼 @chenhengjie123

// meaning they will manage app install / launching

我去看看自己安装的这种流程在源码里的逻辑。

#5 楼 @kilmer :thumbsup: 研究通了后面分享一下吧!

赞啊,看了两位的回答,困扰我一个上午的问题终于解决了

落辰曦 [该话题已被删除] 中提及了此贴 04月30日 17:21

我想不用 appium 启动应用,就将 autoLaunch 设为了 false,然后用 adb shell am start 来启动应用,后续再用 appium 来定位元素。就我想问一下,在后续定位元素中,appium 能够初始化 UIautomator 对象吗?

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册