• 手机自动化测试:Appium源码分析之跟踪代码分析六


    手机自动化测试:Appium源码分析之跟踪代码分析六

     

       poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标。poptest推出手机自动化测试的课程,讲解appuim的实际应用,培训全程用商业项目, 大家可以加qq群进行交流:195983133

     

    加载模块

    var logger = require('./logger.js').get('appium')

      , status = require('./status.js')

      , _ = require('underscore')

      , safely = require('./helpers').safely;

    加载了4个模块,3个本地模块(logger,status,helpers)和一个核心工具模块(underscore)。本地模块我们后续再讲解,这个工具模块是做什么用的,我找到一篇文章讲解这个underscore,从这篇文章可以了解到这个模块主要提供了一些常用的函数,大概80个。

    7个函数

    reponses模块中包含7个函数,下面我们一步一步解释

    getSessionId函数

    //得到session的id号,每一个session都有一个独特的id用来标识

    var getSessionId = function (req, response) {

      //判断传递过来的参数response是否初始化,如果已经初始化,sessionId的值就赋值为response的属性sessionId的值

      //否则赋值为undefined

      var sessionId = (typeof response === 'undefined') ? undefined : response.sessionId;

      //经过上面的赋值后,如果sessionId的值为undefined,那么就要进一步处理

      if (typeof sessionId === "undefined") {

        if (req.appium) {

          //如果req.appium初始化过,就将appium中的属性sessionId赋值给当前变量sessionId

          //需要注意的是后面的||null写法,如果req.appium.sessionId是没有定义的,那么会走到||后面,意思也是

          //给sessionId定义为null,如果不加||null,会发生什么呢?(sessionId=undefined)...

          sessionId = req.appium.sessionId || null;

        } else {

          //如果req.appium没有初始化,那么就直接将sessionId置为空

          sessionId = null;

        }

      }

      //因为我们要求返回的sessionId是一个字符串,那么我就要判断该类型是否正确,如果不正确,也需要置为null值

      if (typeof sessionId !== "string" && sessionId !== null) {

        sessionId = null;

      }

      return sessionId;

    };

    notImplementedInThisContext

    //当我们调用的方法,并不存在的时候,会调用该方法,该方法一般是在设备端,执行查找或对某一个控件进行操作的。

    var notImplementedInThisContext = function (req, res) {

      //首先打印提示信息

      logger.debug("Responding to client that a method is not implemented " +

                  "in this context");

      safely(req, function () {

        //状态设置为501,并返回一个json字符串

        res.status(501).send({

          status: status.codes.UnknownError.code

        , sessionId: getSessionId(req)

        , value: {

          //提示信息消息体

            message: "Not implemented in this context, try switching " +

                     "into or out of a web view"

          }

        });

      });

    };

    上面的函数体内有2个地方需要理解:safely()和res.status(501).send()

    函数

    意义

    safely

    helpers.js模块中safely方法

    res.status(501).send

    将response状态设置为501,然后发送一个消息

    下面是safely方法的源码,也很简单,就是调用了嵌套的回调函数。

    // Mainly used to wrap http response methods, or for cases where errors

    // perdure the domain

    var safely = function () {

      var args = new (Args)(arguments);

      var req = args.all[0];

      var fn = args.callback;

      try {

        fn();

      } catch (err) {

        logger.error('Unexpected error:', err.stack, getRequestContext(req));

      }

    };

     

    respondError

    //返回错误信息

    var respondError = exports.respondError = function (req, res, statusObj, value) {

      //设置错误信息的内容和状态码,因为message要求是字符串类型,code是整形类型

      var code = 1, message = "An unknown error occurred";

      var newValue = value;

      if (typeof statusObj === "string") {

        message = statusObj;

      } else if (typeof statusObj === "undefined") {

        message = "undefined status object";

      } else if (typeof statusObj === "number") {

        code = statusObj;

        message = status.getSummaryByCode(code);

      } else if (typeof statusObj.code !== "undefined") {

        code = statusObj.code;

        message = statusObj.summary;

      } else if (typeof statusObj.message !== "undefined") {

        message = statusObj.message;

      }

      //如果value的值是一个对象类型的值,需要从这个对象中解析出message属性

      //然后进行拼接组成一个json字符串,赋值给newValue,如果不是一个对象类型的值

      //直接组装成json字符串

      if (typeof newValue === "object") {

        if (newValue !== null && _.has(value, "message")) {

          // make sure this doesn't get obliterated

          value.origValue = value.message;

          message += " (Original error: " + value.message + ")";

        }

        newValue = _.extend({message: message}, value);

      } else {

     

        newValue = {message: message, origValue: value};

      }

      //拼接返回信息json字符串对象reponse

      var response = {status: code, value: newValue};

      //获取sessionId

      response.sessionId = getSessionId(req, response);

      logger.debug("Responding to client with error: " + JSON.stringify(response));

      //调用helpers.js模块的safely函数,就是调用里面的嵌套函数

      safely(req, function () {

        res.status(500).send(response);

      });

    };

    respondSuccess

    var respondSuccess = exports.respondSuccess = function (req, res, value, sid) {

      var response = {status: status.codes.Success.code, value: value};

      response.sessionId = getSessionId(req, response) || sid;

      if (typeof response.value === "undefined") {

        response.value = '';

      }

      var printResponse = _.clone(response);

      var maxLen = 1000;

      if (printResponse.value !== null &&

          typeof printResponse.value.length !== "undefined" &&

          printResponse.value.length > maxLen) {

        printResponse.value = printResponse.value.slice(0, maxLen) + "...";

      }

      res.jsonResp = JSON.stringify(printResponse);

      logger.debug("Responding to client with success: " + res.jsonResp);

      safely(req, function () {

        res.status(200).send(response);

      });

    };

    这个函数我就不解释了,因为大致的方式都是一样的,都是先解析出打印的消息体,然后发送出去,只是这里面的response状态是200,因为是成功的。该方法调用的log信息,我们会经常见到。

    getResponseHandler

    exports.getResponseHandler = function (req, res) {

      //直接返回匿名函数

      return function (err, response) {

        //先判断response是否已经初始化,或者是否初始化为空

        if (typeof response === "undefined" || response === null) {

          //设置为空的json字符串

          response = {};

        }

        //判断错误的信息,符合如下条件的,直接抛出异常

        if (err !== null && typeof err !== "undefined" && typeof err.status !== 'undefined' && typeof err.value !== 'undefined') {

          throw new Error("Looks like you passed in a response object as the " +

                          "first param to getResponseHandler. Err is always the " +

                          "first param! Fix your codes!");

        } else if (err !== null && typeof err !== "undefined") {

          if (typeof err.name !== 'undefined') {

            if (err.name === 'NotImplementedError') {

              //如果错误的name值为NotImplementedError,就调用notImplementedInThisContext函数

              notImplementedInThisContext(req, res);

            } else if (err.name === "NotYetImplementedError") {

              //如果错误的name值为NotYetImplementedError,就调用notYetImplemented函数

              notYetImplemented(req, res);

            } else {

              //其他类型都调用respondError

              respondError(req, res, status.codes.UnknownError.code, err);

            }

          } else {

            var value = response.value;

            if (typeof value === "undefined") {

              value = '';

            }

            //如果错误类型name属性值为undefined,我们调用respondError的时候传入的参数为value值

            respondError(req, res, err.message, value);

          }

        } else {

          //如果错误信息为空或者未定义,我们需要根据状态码的不同,调用不同函数处理

          if (response.status === 0) {

            respondSuccess(req, res, response.value, response.sessionId);

          } else {

            respondError(req, res, response.status, response.value);

          }

        }

      };

    };

    终于到了我们真正要解释的函数了-getResponseHandler,从我上面的解释可以看出来,该函数是一个控制类的函数,所有的调用经过该函数处理后,会根据传入参数的不同,调用不同的函数,所以这个函数名字取为handler,以为回复处理器。

    checkMissingParams

    exports.checkMissingParams = function (req, res, params, strict) {

      //如果strict未定义,设置为false,说明strict为boolean类型的值

      if (typeof strict === "undefined") {

        strict = false;

      }

      var missingParamNames = [];

      //迭代params所有的元素,获取所有没有定义的或者值与strict相反的参数,添加到missingParamNames数组中

      _.each(params, function (param, paramName) {

        if (typeof param === "undefined" || (strict && !param)) {

          missingParamNames.push(paramName);

        }

      });

      if (missingParamNames.length > 0) {

        //将数组转化为json字符串

        var missingList = JSON.stringify(missingParamNames);

        logger.debug("Missing params for request: " + missingList);

        //response的状态为400,消息体为上面的json字符串的

        safely(req, function () {

          res.status(400).send("Missing parameters: " + missingList);

        });

        return false;

      } else {

        return true;

      }

    };

    上面的函数是找到为定义的参数或者为null的参数

    notYetImplemented

    //在getResponseHandler函数中我们看到当err.name为NotYetImplementedError时,会调用该函数

    var notYetImplemented = exports.notYetImplemented = function (req, res) {

      //与notImplementedInThisContext类似,都是将response的状态设置为501,然后消息体不同

      logger.debug("Responding to client that a method is not implemented");

      safely(req, function () {

        res.status(501).send({

          status: status.codes.UnknownError.code

        , sessionId: getSessionId(req)

        , value: {

            message: "Not yet implemented. " +

                   "Please help us: http://appium.io/get-involved.html"

          }

        });

      });

    };

  • 相关阅读:
    软考
    十步走-阅读笔记
    软著申请
    十步走-阅读笔记
    基于Ubuntu安装部署ZooKeeper
    基于Ubuntu安装JDK(OPenJDK8)
    Intern Day89
    阿里巴巴Java研发工程师技术一面
    面试
    6_moc.md
  • 原文地址:https://www.cnblogs.com/poptest/p/4958802.html
Copyright © 2020-2023  润新知