Appium Server源码分析之作为Bootstrap客户端

发表于:2014-12-16 14:14

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:天地会珠海分舵    来源:51Testing软件测试网采编

分享:
  2. 创建Appium任务队列Work Queue
  appium server和bootstrap的连接在什么时候开始建立呢?其实这个需要由appium client端来进行启动。也就是说如果你只是启动appium这个应用的话,它是不会尝试和目标安卓机器的bootstrap进行连接的,而一旦我们准备运行一个脚本的时候,appium cilent端就会立刻先发送一个创建与bootstrap回话的请求“/wd/hub/session”请求过来:
  这个appium client创建session的请求所带的参数就是我们脚本中设置好的capabilities,在我的例子中是这些:
  DesiredCapabilities capabilities = new DesiredCapabilities();
  capabilities.setCapability("deviceName","Android");
  capabilities.setCapability("appPackage", "com.example.android.notepad");
  capabilities.setCapability("appActivity", "com.example.android.notepad.NotesList");
  driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
  往下我们就跟踪下创建session在routing路由表里对应的controller是怎么实现和bootstrap的通信的,但是其实在真正实现通信之前,appium需要先去初始化一个async库的queue队列来排队我们需要发送到bootstrap的命令任务,我们下面会一步步看这个队列是怎么建立起来的。
  我们先找到routing中对应的controller方法:
  rest.post('/wd/hub/session', controller.createSession);
  处理函数是controller的createSession这个方法,我们进去看看:
  exports.createSession = function (req, res) {
  if (typeof req.body === 'string') {
  req.body = JSON.parse(req.body);
  }
  ...
  req.appium.start(req.body.desiredCapabilities, function (err, instance) {    ...
  }
  它会先取得http client发过来的request的body,也就是上面包含我们的capabilities的那一串键值对组成的字符串了。然后将这些键值对转换成JSON格式,最后就以这些capabilities作为参数来调用req.appium的start方法,还记得req.appium是在哪里赋值的吗?对,就在上面初始化routing的时候调用的‘controller.getGlobalBeforeFilter“这个方法里面了,初始化成我们在启动http服务器时创建的那个appium server了(如果不清楚appium server是在启动http服务器过程中什么时候创建的,请查看上一篇文章)。好我们跳进该方法继续往下看:
Appium.prototype.start = function (desiredCaps, cb) {
var configureAndStart = function () {
this.desiredCapabilities = new Capabilities(desiredCaps);
this.updateResetArgsFromCaps();
this.args.webSocket = this.webSocket; // allow to persist over many sessions
this.configure(this.args, this.desiredCapabilities, function (err) {
if (err) {
logger.debug("Got configuration error, not starting session");
this.cleanupSession();
cb(err, null);
} else {
this.invoke(cb);
}
}.bind(this));
}.bind(this);
if (this.sessionId === null) {
configureAndStart();
} else if (this.sessionOverride) {
logger.info("Found an existing session to clobber, shutting it down " +
"first...");
this.stop(function (err) {
if (err) return cb(err);
logger.info("Old session shut down OK, proceeding to new session");
configureAndStart();
});
} else {
return cb(new Error("Requested a new session but one was in progress"));
}
};
  代码开始就是些根据传进来的capabilites参数初始化一个Capabilities对象之类的,这里Capabilities这个类值得一提的地方是它定义了一系列的capability,其中有一类是我们在测试脚本中必须填写的:
  var requiredCaps = [
  'platformName'
  , 'deviceName'
  ];
  也就是说其他的capability我们在脚本中可以根据需求取配置填写,但是这两个是必须的,硬性要求的。其实根据我对现有源码的研究,在安卓上面只有platformName是必须的,deviceName只有在ios上面才会用到,只是为了保持一致性,测试安卓时还是需要传进来而已,但是无论你设置什么值都没有影响。
  好,我们继续往下看,Appium类的start方法在实例化好Capabilities类后,往下有几步非常重要:
  第一步:通过调用configure方法来初始化Android设备类,Android设备类的实例维护的Appium Work Queue
  第二步:通过调用invoke方法建立好uiautomator类与bootstrap的连接
  Appium.prototype.configure = function (args, desiredCaps, cb) {
  var deviceType;
  try {
  deviceType = this.getDeviceType(args, desiredCaps);
  ...
  }
  ...
  this.device = this.getNewDevice(deviceType);
  this.device.configure(args, desiredCaps, cb);
  ...
  };
52/5<12345>
100家互联网大公司java笔试题汇总,填问卷领取~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2023
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号