Python3+requests搭建接口自动化测试框架


一、接口自动化的意义

新版本上线时之前版本的功能需要进行回归测试,导致大量的重复性手工测试。引入自动化测试可以使用自动化技术代替部分手工的回归性测试,解放更多人力做其它更有必要的事情。但目前项目UI变动频繁,而接口一般不会做大变动所以先暂时做接口自动化。使用接口自动化可以做上线前接口功能的回归性测试,也可以定时巡检线上环境接口的运行情况,能及时发现线上环境接口问题并解决。同时此框架可以帮助不会写代码的测试同事进行接口自动化的相关工作。

二、准备工作

    开发语言:Python3

需要安装的模块:

Requests: python的一个HTTP客户端库,和urllib、urllib2类似。

1、安装方法:

使用pip安装

pip install Requests

或 

python3 -m pip install Requests                                     

下载源码后安装

git clone git://github.com/kennethreitz/requests.git

cd requests

python setup.py install

xlsxwriter:是python用来构造xlsx文件的模块,可以完成xlsx文件的自动化构造,包括:合并单元格,制作excel图表等功能。

1、安装方法:

使用pip安装

pip install Requests

或 

python3 -m pip install Requests

三、框架流程及逻辑

框架理念:使用json文件编写测试用例,建一个脚本循环读取测试用例并执行,然后对比返回的接口和用例中的期望结果。将测试结果写入到一个excel表格中生成测试报告,最后使用发送邮件功能将测试报告发送到指定邮箱。其中对所有公共方法进行封装并放在common公共文件目录下。

四、各模块介绍

----interface_test                             项目文件夹目录

    ----common                                存放公共方法目录

            ----__init__.py                    初始化文件

            ----conf.py                          操作配置文件相关方法

            ----excelaction.py                Excel文件相关操作方法

            ----jsonaction.py                 Json文件相关操作方法

            ----logger.py                       记录日志的相关方法

            ----newfile.py                      获取最新文件的相关方法

            ----sendmail.py                   发送报告到指定邮箱的相关方法

            ----signture.py                    对数据进行签名的相关方法

            ----userinfo.py                    获取用户信息的相关方法

            ----config_test.conf             基本配置文件

    ----logs                                       存放日志的目录

    ----report                                    存放测试报告的目录

    ----test_data                                存放测试用例数据的目录

            ----login-1.json                    登录接口的测试用例数据

            ----logout-2.json                  退出登录接口的测试用例数据

    ----execute_test.py                       读取测试用例并执行测试用例

----test.bat                                    运行测试项目的批处理文件

execute_test.py 主要程序

1 # -*- coding: utf-8 -*-

  2 #!/usr/bin/env python                                                               

  3 import os                                                                                       

  4 import json                                                                                   

  5 import requests                                                                                           

  6 import common.conf as conf                                                                                                                       

  7 import common.excelaction as excelaction                                                                                                               

  8 from common.sendemail import sendreport                                                                                                           

  9 from common.signture import sign                                                                                           

10 import common.userinfo as userinfo                                                                                                       

11 import common.logger as logger                                                                                                                       

12 import sys                                                                                                                               

13 import time                                                                                                                               

14                                                                                                                                                                                       

15 #data_path = os.path.dirname(__file__) + '\\test_data\\' # 测试用例数据文件所在目录                                                                           

16 data_path = conf.testdata_path                                                                                                                   

17                                                                                                                                                                                           

18 test_reports = [] # 添加一个数组用来存储测试结果                                                                                                     

19 for file in os.listdir(data_path): # 循环读取目录下的文件                                                                                                                                               

20    child = os.path.join('%s%s'%(data_path,file)) # 将文件名和路径拼接好                                                                               

21    logger.info("当前打开的文件:"+child)                                                                                                                                 

22    fl = open(child) # 打开文件                                                                                                                                           

23    try:                                                                                                                                                                                               

24        cases = json.load(fl)                                                                                                                   

25        for key in cases: # 循环读取文件中的测试用例(case)                                                                                           

26            start_time = time.clock()                                                                                                           

27            case = cases[key]                                                                                                               

28            url = conf.get_conf('module',case['module']) + case['url']                                                                                                       

29            data = case['data']                                                                                                                   

30            data['Platform'] = conf.get_conf('params','Platform')                                                                                           

31            data['Terminal'] = conf.get_conf('params','Terminal')                                                                       

32            data['UserIP'] = conf.get_conf('params','UserIP')                                                                                       

33            data['Version'] = conf.get_conf('params','Version')                                                                                           

34            if "UserToken" in data and data['UserToken'] == '':                                                                                                   

35                data['UserToken'] = userinfo.get_token()                                                                                               

36            hope_result = case['assert']                                                                                               

37            method = case['method']                                                                                                   

38            test_report = {                                                                                                                       

39                "case_id":case['id'],                                                                                                               

40                "t_name":case['name'],                                                                                                               

41                "method":method,                                                                                                                   

42                "url":url,                                                                                                                               

43                "params":data,                                                                                                               

44                "hope_result":hope_result,                                                                                                   

45                "actual_result":[],                                                                                                                   

46                "test_result":""                                                                                                                               

47            }                                                                                                                                                                 

48            try:                                                                                                                                                   

49                if method == 'post':                                                                                                                           

50                    addsign_data = sign(data,conf.get_conf('sign','api_key'))                                                                                   

51                    r = requests.post(url,data=json.dumps(addsign_data),headers=conf.header)                                                                           

52                    response = r.json()                                                                                                   

53                    s = True                                                                                                                   

54                    for k in hope_result:                                                                                                           

55                        ar = str(k) + ":" + str(response[k])                                                                                               

56                        test_report["actual_result"].append(ar)                                                                                           

57                        if type(hope_result[k]) == type(''):                                                                                               

58                            if hope_result[k] in response[k]:                                                                                           

59                                s = s&True                                                                                                           

60                            else:                                                                                                                   

61                                s = s&False                                                                                                       

62                        else:                                                                                                                               

63                            if hope_result[k] == response[k]:                                                                                           

64                                s = s&True                                                                                                                                                                                           

65                            else:                                                                                                               

66                                s = s&False                                                                                                               

67                    if s:                                                                                                                                 

68                        test_report["test_result"] = "PASS"                                                                                           

69                    else:                                                                                                                           

70                        test_report["test_result"] = "Fail"                                                                                       

71                                                                                                                                                                                                   

72                elif method == 'get':                                                                                                       

73                    addsign_data = sign(data,conf.get_conf('sign','api_key'))                                                                                   

74                    r = requests.get(url,params=addsign_data,headers=conf.header)                                                                           

75                    response = r.json()                                                                                                       

76                    s = True                                                                                                                               

77                    for k in hope_result:                                                                                                           

78                        ar = str(k) + ":" + str(response[k])                                                                                       

79                        test_report["actual_result"].append(ar)                                                                                       

80                        if type(hope_result[k]) == type(''):                                                                                                   

81                            if hope_result[k] in response[k]:                                                                                                   

82                                s = s&True                                                                                                           

83                            else:                                                                                                               

84                                s = s&False                                                                                                                   

85                        else:                                                                                                                                   

86                            if hope_result[k] == response[k]:                                                                                                       

87                                s = s&True                                                                                                                           

88                            else:                                                                                                   

89                                s = s&False                                                                                                               

90                    if s:                                                                                                       

91                        test_report["test_result"] = "PASS"                                                                                                   

92                    else:                                                                                                                               

93                        test_report["test_result"] = "Fail"                                                                                                       

94                                                                                                                                                                           

95                else:                                                                                                                                   

96                    print(u'暂不支持该请求方式')                                                                                                                                   

97                test_reports.append(test_report)                                                                                                                       

98                end_time = time.clock()                                                                                                                   

99                str_time = '当前执行的用例:' + key + '_'*4 + '用例执行所用时间:' + str(end_time-                                                                                                    start_time) + 's'                                                                                                                                   

100                logger.info(str_time)                                                                                                       

101            except:                                                                                                                               

102                error_msg = sys.exc_info()                                                                                                                                       

103                logger.error(error_msg)                                                                                                               

104                continue                                                                                                                                   

105    except:                                                                                                                                   

106        error_msg = sys.exc_info()                                                                                                               

107        logger.error(error_msg)                                                                                                                   

108        continue                                                                                                                                           

109                                                                                                                                                                                               

110 excelaction.creat_report(test_reports) #生成测试报告                                                                                       

111 sendreport() #发送测试报告                                                                                                       

五、具体使用

1、在配置文件做对应项目的基础配置

[email] -- 邮箱相关配置

sender = ***@163.com -- 发件邮箱

receiver = ***@163.com -- 收件邮箱

smtpserver = smtp.163.com -- 发件邮箱服务器

username = ***@163.com -- 发件邮箱账户名

password = **** -- 发件邮箱密码(用于第三方登录的秘密)

[module] -- 模块相关接口域名配置

passport = http://passport.XXX.com/ -- 对应模块接口域名

[sign] -- 签名相关的配置

api_key = XXX-XXX -- 生成签名的key(填写项目对应的key)

[params] -- 接口参数配置(配置公共参数)

Platform = 1 -- 根据对应项目配置对应的公共参数和对应值

2、在test_data文件夹内用json文件写测试用例和对应参数 

"case1":{

    "name":"登录接口_测试正常登录",        -- 接口名称(或者接口简介)

    "module":"passport",                -- 接口所属模块

    "url":"/api/Passport/Login",            -- 接口地址(完整地址由模块对应域名+该地址拼接)

      "method":"post",                    -- 接口请求方式

      "id":"1-001",                        -- 用例ID

    "data":{                            -- 接口请求参数(请求时由该参数加公共参数)

        "UserName":"XXX",                -- 接口请求参数(根据具体接口补充,如果接口需要token则需要加token关键字(值为空就行),接口请求时会自动根据参数生成Sign,如果想自己定义则需要加Sign关键字(值填写自己定义的))

        },

    "assert":{                            -- 该条测试用例的断言条件

        "Status":200,                    -- 具体的断言条件,需要返回状态为200

        "Message":"登录成功"            -- 具体的断言条件

        }

    }

3、配置好基础配置和编写完测试用例后,运行项目中的test.bat文件。运行完成后会在report文件夹内生成测试报告文件,在logs文件夹内会生成测试运行过程中的记录日志和报错日志

创建了一个测试交流群,如果对软件测试、接口测试、自动化测试、面试经验交流感兴趣可以加测试交流群:829792258,还会有同行一起技术交流

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