03-python处理http返回包

思路

创建测试用例表,准备数据--读取测试用例表中的数据--获取接口返回的数据进行比较--将结果写入数据表
根据这个思路构造名为compare_param的类,类中包含了三个方法:
(1)compare_json_code(self,case_data,result_data): 当接口返回结果是json格式的数据,通过这个方法获取数据表中待比较code值与接口返回的状态码resultCode对比,并将结果写回数据库
(2)def compare_json_params(self,case_data,result_data): 当接口返回结果是json格式的数据,通过这个方法获取数据表中接口比较参数集合params_to_compare与接口返回的参数对比,并将结果写入数据库中
(3) def jsondata_to_set(self,dict_ob, set_ob): 将json格式的数据进行去重操作


python比较code

python参数比较

创建测试用例表case_interface

CREATE TABLE `case_interface` (
  `id` int(2) NOT NULL AUTO_INCREMENT,
  `name_interface` varchar(128) NOT NULL COMMENT '接口名称',
  `exe_level` int(2) DEFAULT NULL COMMENT '执行优先级,0代表BVT',
  `exe_mode` varchar(4) DEFAULT NULL COMMENT '执行方式:post,get,默认是post方式',
  `url_interface` varchar(128) DEFAULT NULL COMMENT '接口地址:如果以http开头的则直接使用改地址,否则拼接上不同环境的ip前缀作为接口地址',
  `header_interface` text COMMENT '接口请求的头文件,有则使用,无则调用配置文件',
  `params_interface` varchar(256) DEFAULT NULL COMMENT '接口请求的参数',
  `result_interface` text COMMENT '接口返回结果',
  `code_to_compare` varchar(16) DEFAULT NULL COMMENT '待比较的code值,用户自定义比较值,例如returncode和code等,默认returncode',
  `code_actual` varchar(16) DEFAULT NULL COMMENT '接口实际code实际返回值',
  `code_expect` varchar(16) DEFAULT NULL COMMENT '接口预期code返回值',
  `result_code_compare` int(2) DEFAULT NULL COMMENT 'code比较结果,0-pass,1-fail,2-无待比较参数,3-比较出错,4-返回包不合法,5-系统异常'
  `params_to_compare` varchar(256) DEFAULT NULL COMMENT '接口比较参数集合,用于比较参数完整性',
  `params_actual` text COMMENT '接口实际返回参数',
  `result_params_compare` int(2) DEFAULT NULL COMMENT 'code比较结果,0-pass,1-fail,2-获取参数集错误:去重错误,5-系统异常',
  `case_status` int(2) DEFAULT '0' COMMENT '用例状态 0-有效,1-无效',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT='接口用例表';

关键字参数:验证结构体是否正确,http返回包是否有对应关键字,返回有关键字参数的情况下去比较关键字参数的值和实际结果是否相等
参数完整性:预期参数列表都在实际返回列表中,集合的包含关系issubset()

python操作MySQL返回数据

python操作Mysql一般返回两种数据,元祖和字典。此处要用到是字典类型的数据

import pymysql,re,logging,os
class OperationDb_interface(object):
   def __init__(self):
      self.conn=pymysql.connect(host='localhost',
                                user='root',
                                passwd='*****',
                                db='my_test',
                                port=3306,
                                charset='utf8',
                                cursorclass=pymysql.cursors.DictCursor#返回字典
                                )#创建数据库链接

      self.cur=self.conn.cursor()#创建游标

在默认情况下cursor方法返回的是BaseCursor类型对象,BaseCursor类型对象在执行查询后每条记录的结果以列表(list)表示。如果要返回字典(dict)表示的记录,就要设置cursorclass参数为pymysql.cursors.DictCursor类

代码

#-*- coding:utf-8 -*-
#__author__='yy'
'''
@desc:根据case_interface 表中的信息对response结果做断言(code,参数完整性)操作,将断言结果写入数据表中
question:接口返回对象不是json,如xml,所以我们这个类应该具有可扩展性
'''
from mylogging import mylogger
from  Interface import OperationDb_interface
import json

class compare_param:
    def compare_json_code(self,case_data,result_data):
        '''
        当接口返回json格式数据,通过这个方法,对比返回状态码code,将结果写回数据库
        :param case_data: 数据库中存储测试case的数据,一条数据(字典类型)
        :param result_data:调用接口返回json格式的数据
        :return:
        1.{`code`:200,`message`:`code相等`,`content`:``}
        2.{`code`:300,`message`:`code不相等`,`content`:``}
        3.{`code`:301,`message`:`code不存在`,`content`:``}
        4.{`code`:400,`message`:`code比较出现异常`,`content`:``}
        '''
        try:
            op_sql= OperationDb_interface()
            update_sql="UPDATE case_interface SET result_interface=%s,code_actual=%s,result_code_compare=%s WHERE id =%s"
            code_expected = case_data.get("code_to_compare")#获取数据表中保存的code值
            if 'resultCode' in result_data:
                result_code = result_data.get("resultCode") #获取返回结果中的code值
                if code_expected == result_code:
                    op_sql.op_sql(update_sql,(str(result_data),result_code,0,case_data.get("id"))) #code比较结果,0-pass
                    result={'code':200,'message':'code相等','content':''}
                else:
                    op_sql.op_sql(update_sql,(str(result_data),result_code,1,case_data.get("id")))
                    result = {'code':300,'message':'code不相等','content':''}
            else:
                op_sql.op_sql(update_sql,(str(result_data),None,2,case_data.get("id")))#2-无待比较参数
                result = {'code':301,'message':'code不存在','content':''}
        except BaseException as  e:
            op_sql.op_sql(update_sql,(str(result_data),None,4,case_data.get("id")))#4-比较异常
            mylogger.info("[compare_json_code 测试用例信息]-%s"%str(case_data))
            mylogger.info("[compare_json_code 接口返回的信息]-%s"%str(result_data))
            mylogger.exception(e)
            result={'code':400,'message':'code比较出现异常','content':''}
        return  result
    def jsondata_to_set(self,dict_ob,set_ob):
        '''
        json格式数据去重操作:递归
        :param dict_ob: dict:json格式数据
        :param set_ob: 传入set对象(没有内容)
        :return:
        1.{"code":200,"message":"json:参数去重成功","content":set_ob}
        2.{"code":400,"message":"json:参数去重出现异常","content":""}
        '''
        try:
            for key,value in dict_ob.items():
                set_ob.add(key)
                if isinstance(value,dict):
                    self.jsondata_to_set(value,set_ob)
                elif isinstance(value,list):
                    for li in value:
                        self.jsondata_to_set(li,set_ob)

            result = {"code":200,"message":"json:参数去重成功","content":set_ob}
        except BaseException as e:
            mylogger.info("[jsondata_to_set params]-(dict_ob:%s,set_ob:%s)"%(str(dict_ob),str(set_ob)))
            mylogger.exception(e)
            result = {"code":400,"message":"json:参数去重出现异常","content":""}
        return result
    def compare_json_params(self,case_data,result_data):
        '''
        当借口返回结果是json格式的数据,通过这个方法,可以对比返回参数和数据库中的预期参数,并将结果写入数据库中
        :param case_data:数据库返回的用例信息,dict=>一条数据
        :param result_data:接口返回json数据,dict
        :return:
        1.{"code":200,"message":"参数完整性相等","content":""}
        2.{"code":301,"message":"参数完整性不相等","contenr":""}
        3.{"code":300,"message":"去重失败:获取参数集错误","content":""}
        4.{"code":400,"message":"参数完整性比较出现异常","content":""}
        '''
        try:
            op_sql = OperationDb_interface()
            #获取预期参数
            case_params =case_data.get("params_to_compare")
            case_params_set = eval(case_params)  #将字符串str当成有效的表达式来求值并返回计算结果
            #更新数据的sql语句
            update_sql="UPDATE case_interface set params_actual=%s ,result_params_compare=%s WHERE id=%s"

            #对json数据进行去重操作
            params_set = set() #set() 函数创建一个无序不重复元素集,可进行关系测试,删除重复数据,还可以计算交集、差集、并集等
            set_result = self.jsondata_to_set(result_data,params_set)
            print(case_params_set)
            print(params_set)
            if set_result.get("code")==200:
                #判断是否包含
                if case_params_set.issubset(params_set):#如果集合case_params_set中每个元素都在params_set中
                    #更新数据表
                    op_sql.op_sql(update_sql,(str(params_set),0,case_data.get("id"))) #0 pass
                    result = {"code":200,"message":"参数完整性相等","content":""}
                else:

                    op_sql.op_sql(update_sql,(str(params_set),1,case_data.get("id"))) #1 fail
                    result={"code":301,"message":"参数完整性不相等","content":""}
            elif set_result.get("code")==400:
                op_sql.op_sql(update_sql,(None,2,case_data.get("id")))# 2 去重错误
                result = {"code":300,"message":"去重失败:获取参数集错误","conten":""}
        except BaseException as e:
            op_sql.op_sql(update_sql,(None,5,case_data.get("id"))) # 5 系统异常
            mylogger.info("[compare_json_params params - (case_data:%s,result_data:%s)]"%(str(case_data),str(result_data)))
            mylogger.exception(e)
            result = {"code":400,"message":"参数完整性比较出现异常","content":""}
        return result
if __name__ == "__main__":
     #获取数据库的测试用例信息
     mysql_op = OperationDb_interface()
     case_data = mysql_op.selectOne("select * from case_interface WHERE id=1")
     #创建一个compare对象
     cmp_obj =compare_param()

     '''
     #code比较
     #test_compare_json_code:200-code相等
     result_interface= '{"message": "获取附近服务商成功","nextPage": 1,"pageNo": 0,"merchantInfos11":"测试环境店铺","resultCode":"000","totalPage": 66746}'
     cmpare_result = cmp_obj.compare_json_code(case_data,json.loads(result_interface))
     print(cmpare_result)
     '''

     '''
     result_interface = '{"message": "获取附近服务商成功","nextPage": 1,"pageNo": 0,"merchantInfos": [{"phone": "15100000000","star": 5,"totalQualityEvaluation": 0,"photoUrls": "","latitude": 0},{"phone": "15200000000","detail": null,"sex": null,"serviceFrequency": 0}],"resultCode": "000","totalPage": 66746}'
     my_set = set()
     result = cmp_obj.jsondata_to_set(json.loads(result_interface), my_set)
     if result.get("code") == 200:
         print(result.get("code"))
         print(result.get("message"))
         print(result.get("content"))
    '''


     #参数完整性的比较
     result_interface = '{"message": "获取附近服务商成功","nextPage": 1,"pageNo": 0,"merchantInfos":"测试环境店铺","resultCode": "000","totalPage": 66746}'
     cmpare_result = cmp_obj.compare_json_params(case_data,json.loads(result_interface))
     print(cmpare_result)


备注

  1. json.loads
    用法:把json格式字符串解码转换成python对象字典(json与字典的不同对于参数引号的使用,json使用双引号,字典使用单引号,而python只能处理单引号)
    ex:str_json='{"message":"success","page":1,"totalPage":100}'
    dict_json=json.loads(str_json)
    结果:{u'message':u'success',u'totalPage':100,u'page':1}

  2. dict.has_key(key)与dict.iteritems()
    dict.has_key(key): 判断键名key是不是在字典dict中,如果键在字典dict里返回true,否则返回false
    ex:test_dict={'message':'success','totalPage':100,'page':1}
    print test_dict.has_key('message')
    True
    print test_dict.has_key(‘project’)
    False

dict.iteritems(): 返回字典键、值的迭代器,一般用于循环获取键和值
ex:test_dict={'message':'success','totalPage':100,'page':1}
print test_dict.iteritems()
for key,value in test_dict,iteritems():
print (key,value)


message success
total Page 100
page 1

  1. eval()与 instance()
    eval():将字符串str当成有效的python表达式来求值并返回计算结果,这里将str类型的文件转换为本来面目(list、tuple、dict和string之间的转换)
    ex:u_str='{"message":"success","page":1,"totalPage":100}'
    print (eval(str_json))

{'page': 1, 'message': 'success', 'totalPage': 100}

isinstance(value,(dict,list)): 格式判断,指value的类型属于dict和list中的一种,如果是则返回True,否则返回False
ex:test_dict={"message":"success","page":1,"totalPage":100}
print (isinstance(test_dict,(dict,list)))


True
print (isinstance('python',(dict,list)))


False

  1. set() 与issubset()
    set(): 集合也是python的一种数据类型,它和列表很像,但是集合的数据是有序的且不能重复。所以我们可以将列表转换成集合,使用的就是set()
    ex:test_list=[1,2,3,3,4,2]
    t=set(test_list)
    print(t)

{1, 2, 3, 4}

issubset(): 集合的包含关系,如s.issubset(t),指的是否s中的每个元素都在t中,是则返回True,否则返回False
ex:a=set([1,2,3,4,5,])
b=set([1,2,3])
print (a.issubset(b))


False
print (b.issubset(a))


True

跟着亭子青年学习接口测试

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,076评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,658评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,732评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,493评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,591评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,598评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,601评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,348评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,797评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,114评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,278评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,953评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,585评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,202评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,180评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,139评论 2 352

推荐阅读更多精彩内容

  • Python 面向对象Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对...
    顺毛阅读 4,213评论 4 16
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,647评论 18 139
  • 未来不是属于有钱人,更不属于没钱人,是属于正能量的人! 不要跟消耗你的人在一起! 去靠近一个给你正能量的人。每个人...
    大道行者_阅读 200评论 0 0
  • 我定是上辈子拯救了银河系,这辈子才会如此幸运的赖上你,我完全不能想象没有你的日子里我要怎么过下去。 如同出生是不被...
    婉言1228阅读 418评论 0 1
  • 第1步:接到面试电话,一定要确认清楚相关细节。 求职者一定要问清楚面试时间、地点、所需材料、应聘的业务部门及产品线...
    面试求职那些事阅读 522评论 2 8