手机自动化测试: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"

}

});

});

};

手机自动化测试:Appium源码分析之跟踪代码分析六的更多相关文章

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

    手机自动化测试:Appium源码分析之跟踪代码分析九   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家 ...

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

    手机自动化测试:Appium源码分析之跟踪代码分析八   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家 ...

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

    手机自动化测试:Appium源码分析之跟踪代码分析七   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.poptest推出手机自 ...

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

    手机自动化测试:Appium源码分析之跟踪代码分析五   手机自动化测试是未来很重要的测试技术,作为一名测试人员应该熟练掌握,POPTEST举行手机自动化测试的课程,希望可以训练出优秀的手机测试开发工 ...

  5. 手机自动化测试:appium源码分析之bootstrap三

    手机自动化测试:appium源码分析之bootstrap三   研究bootstrap源码,我们可以通过代码的结构,可以看出来appium的扩展思路和实现方式,从中可以添加我们自己要的功能,针对app ...

  6. 手机自动化测试:appium源码分析之bootstrap二

    手机自动化测试:appium源码分析之bootstrap二   在bootstrap项目中的io.appium.android.bootstrap.handler包中的类都是对应的指令类, priva ...

  7. 手机自动化测试:appium源码分析之bootstrap一

    手机自动化测试:appium源码分析之bootstrap一   前言: poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.popte ...

  8. 手机自动化测试:appium源码分析之bootstrap十七

    手机自动化测试:appium源码分析之bootstrap十七   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣 ...

  9. 手机自动化测试:appium源码分析之bootstrap十六

    手机自动化测试:appium源码分析之bootstrap十六   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣 ...

随机推荐

  1. Myeclipse 搭建Java Web 项目 《一》

    今天将图文并茂的介绍如何使用myclipse 创建Java Web 项目;我使用的是myclipse 8.6 来进行创建: 1.打开Myeclipse,点击File --->然后New ---- ...

  2. BZOJ USACO 银组 水题集锦

    最近刷银组刷得好欢快,好像都是水题,在这里吧他们都记录一下吧(都是水题大家一定是道道都虐的把= =)几道比较神奇的题到时再列出来单独讲一下吧= =(其实我会说是BZOJ蹦了无聊再来写的么 = =) [ ...

  3. Linux下自动备份MySQL

    使用expect和mysqldump备份 expect expect是一个免费的编程工具语言,用来实现自动和交互式任务进行通信,而无需人的干预. 例如,执行shell脚本的过程中,需要输入用户名.密码 ...

  4. PCB行业ERP解决方案

    普实PCB管理系统包括PCB企业从接到订单开始,编排生产计划.制作工程指示.生产工具.准备物料.品质保障.工序生产.设备维护等一系列与企业运作密切相关的环节,使得企业的各个部门能够紧密联系.相互协调, ...

  5. HA高可用集群

     准备2台机器:主:master:192.168.254.140从:slave:192.168.254.141 1.主上安装:wget www.lishiming.net/data/attachmen ...

  6. Linux下修改系统时区

    使用 /etc/localtime 文件修改时区 先查看一下当前的时区,下面这个例子中使用 UTC 即世界统一标准时区.假设你可能需要改为美国西部标准时间,即太平洋时间. # date Thu Aug ...

  7. 自己动手编写Maven的插件

    Maven的插件机制是完全依赖Maven的生命周期的,因此理解生命周期至关重要.本文参考官方文档后使用archetype创建,手动创建太麻烦. 创建创建项目 选择maven-archetype-moj ...

  8. 写lua时需要注意的地方

    条件语句判断时,只有false和nil会导致判断为假,其他的任何值都为真. Lua 的字符串与编码无关: 它不关心字符串中具体内容. 标准 Lua 使用 64 位整数和双精度(64 位)浮点数, 但你 ...

  9. vbs文件小技巧

    vbs文件介绍: VBS是基于Visual Basic的脚本语言.VBS的全称是:Microsoft Visual Basic Script Editon.(微软公司可视化BASIC脚本版). 可以新 ...

  10. JAVA基础:自己构造一个按递增排列的数组,用户输入一个数,插入适当位置