手机自动化测试: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"
}
});
});
};
手机自动化测试:Appium源码分析之跟踪代码分析六的更多相关文章
- 手机自动化测试:Appium源码分析之跟踪代码分析九
手机自动化测试:Appium源码分析之跟踪代码分析九 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家 ...
- 手机自动化测试:Appium源码分析之跟踪代码分析八
手机自动化测试:Appium源码分析之跟踪代码分析八 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家 ...
- 手机自动化测试:Appium源码分析之跟踪代码分析七
手机自动化测试:Appium源码分析之跟踪代码分析七 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.poptest推出手机自 ...
- 手机自动化测试:Appium源码分析之跟踪代码分析五
手机自动化测试:Appium源码分析之跟踪代码分析五 手机自动化测试是未来很重要的测试技术,作为一名测试人员应该熟练掌握,POPTEST举行手机自动化测试的课程,希望可以训练出优秀的手机测试开发工 ...
- 手机自动化测试:appium源码分析之bootstrap三
手机自动化测试:appium源码分析之bootstrap三 研究bootstrap源码,我们可以通过代码的结构,可以看出来appium的扩展思路和实现方式,从中可以添加我们自己要的功能,针对app ...
- 手机自动化测试:appium源码分析之bootstrap二
手机自动化测试:appium源码分析之bootstrap二 在bootstrap项目中的io.appium.android.bootstrap.handler包中的类都是对应的指令类, priva ...
- 手机自动化测试:appium源码分析之bootstrap一
手机自动化测试:appium源码分析之bootstrap一 前言: poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.popte ...
- 手机自动化测试:appium源码分析之bootstrap十七
手机自动化测试:appium源码分析之bootstrap十七 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣 ...
- 手机自动化测试:appium源码分析之bootstrap十六
手机自动化测试:appium源码分析之bootstrap十六 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣 ...
随机推荐
- SpringMVC:学习笔记(1)——理解MVC及快速入门
SprigMVC-理解MVC及快速入门 说明: 传统MVC-->JSPModel2-->Front Controller + Application Controller + Page C ...
- 关于Mysql的索引
索引是指把你设置为索引的字段A的内容储存在一个独立区间S里,里面只有这个字段的内容.在找查这个与这个字段A的内容时会直接从这个独立区间里查找,而不是去到数据表里查找.找到的这些符合条件的字段后再读取字 ...
- hibernate分页模糊查询
在web项目中,显示数据一般采用分页显示的,在分页的同时,用户可能还有搜索的需求,也就是模糊查询,所以,我们要在dao写一个可以分页并且可以动态加条件查询的方法.分页比较简单,采用hibernate提 ...
- 不恰当的update语句使用主键和索引导致mysql死锁
背景知识: 截至目前,MySQL一共向用户提供了包括DBD.HEAP.ISAM.MERGE.MyIAS.InnoDB以及Gemeni这7种Mysql表类型.其中DBD.InnoDB属于事务安全类表,而 ...
- Laravel使用Seeder自动填充数据
要查看代码,可以点击 或者转到链接:https://github.com/laravel/framework Laravel自动填充数据使用的是Seeder类 <?php use Illumin ...
- 自定义分页Gridview中Excel导出
先上图,如图所示导出所有查询出的数据 用的是AspNetPager分页控件,这个导出方法,不受分页和gridview列中数据的约束,可以导出您想导出的数据 首先前台页面代码,lblink即为导出exc ...
- 读书笔记 effective c++ Item 30 理解内联的里里外外 (大师入场啦)
最近北京房价蹭蹭猛涨,买了房子的人心花怒放,没买的人心惊肉跳,咬牙切齿,楼主作为北漂无房一族,着实又亚历山大了一把,这些天晚上睡觉总是很难入睡,即使入睡,也是浮梦连篇,即使亚历山大,对C++的热情和追 ...
- Memcached【第二篇】高可用集群搭建
第一步:准备 1. 架构信息 利用 magent 搭建 memcached 集群,实现性能的高可用. IP Port 主从 192.168.6.129 11211 主节点 192.168.6.130 ...
- mac环境,搭建python+selenium遇到的问题
安装过程: 1.下载安装pip,下载并且解压文件(默认路径即可),打开终端,执行sudo python setup.py install,系统自带python,也可以不安装 2.执行 sudo eas ...
- Zookeeper与Kafka集群搭建
一 :环境准备: 物理机window7 64位 vmware 3个虚拟机 centos6.8 IP为:192.168.17.[129 -131] JDK1.7安装配置 各虚拟机之间配置免密登录 安装 ...