视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
python+requests+unittestAPI接口测试问题
2020-11-27 14:14:14 责编:小采
文档
 黑熊在网上查找了下接口测试相关的资料,大都重点是以数据驱动的形式,将用例维护在文本或表格中,而没有说明怎么样去生成想要的用例,

问题:

测试接口时,比如参数a,b,c,我要先测a参数,有(不传,为空,整形,浮点,字符串,object,过短,超长,sql注入)这些情况,其中一种情况就是一条用例,同时要保证b,c的正确,确保a的测试不受b,c参数的错误影响

解决思路:

符合接口规范的参数可以手动去填写,或者准备在代码库中。那些不符合规范的参数(不传,为空,整形,浮点,字符串,object,过短,超长,sql注入)也可以准备在库中作为常量反复使用

主要实现的功能点:

1.api参数整理到dict中,方便组合参数生成用例

2.对生成的用例进行循环执行

3.封装些许代码便于使用和维护

源码分析:

canshuxinxi.py文件用来存放api接口信息。以dict形式存放,这样就可以API_ALL['登录接口'][url]这种方式去取,看起来较直观,知道取得是哪个接口的那部分信息。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2017-06-09 14:09
# canshuxinxi.py

# 接口信息
API_ALL = {
 '登录接口': {
 'number': '1',
 'url': 'http://www.baidu.com',
 'leixing': 'post',
 'head': {
 'aa': 'bb',
 'cc': 'dd',
 },
 'canshu': {
 'username': 'Wbfxs001',
 'password': '111111Qq',
 'grant_type': 'password',
 },
 'qiwang': {
 'code': 200,
 'name': 'Wbfxs001',
 },
 },

 '退出接口': {
 'number': '1',
 'url': 'http://www.baidu.com',
 'leixing': 'get',
 'canshu': {
 'username': 'Wbfxs001',
 'password': '111111Qq',
 'grant_type': 'password',
 }
 }
}

changliang.py文件用来存非常规(可能会让接口响应异常)参数,同理也是存放在dict中,方便维护,比如以后要加新的sql注入代码段,可以直接在后面添加

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2017-06-09 14:09
# changliang.py

# 常用参数不传,为空,整形,浮点,字符串,object,过短,超长,sql注入
objects1 = 'xxxx'
objects2 = 'ssss'

ZHCS = {
 '为空': [''],
 '整形': [10, 23, 44, 88, 99],
 '浮点': [1.11, 2.342, -1.03],
 '字符串': ['aaaa', 'bbbb', 'cccc','dddd'],
 'object': [objects1, objects2],
 '过短': ['1', '0'],
 '超长': ['11111111111111111111111111111111111111111111111'],
 'sql注入': [';and 1=1 ;and 1=2', ";and (select count(*) from sysobjects)>0 mssql", ";and 1=(select IS_SRVROLEMEMBER('sysadmin'));--"],
 }

# gongju.py作为工具类,下面方法进行了封装,方便调用。实现了对参数进行组合,生产不同组合的dict类型的参数,并将dict参数保存到list中,方便取用。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2017-06-09 14:11
# gongju.py

# 生成不同组合的参数

class gj():

 def listalls(self, csTrue, csFalse):
 fzgcs = [] # 得到cycanshu的key,将所有非正规参数放在一个list中
 listall = [] # 保存参数dict 为 list
 zhcs = dict(csTrue)
 listall.append(csTrue)
 aaa = list(csFalse.keys())
 for i in aaa:
 bbb = csFalse[i] # 得到具体参数list
 for k in bbb:
 fzgcs.append(k) # 便利每一个参数加入fzgcs列表

 zhcskey = list(zhcs.keys()) # 拿到将要进行组合的参数
 for i in zhcskey:
 a = zhcs[i] # 保留原有的参数值,下面替换完后复原正确参数
 for k in fzgcs:
 zhcs[i] = k
 listall.append(str(zhcs))
 # 循环完后复原正确参数
 zhcs[i] = a
 return listall

jiaoben.py文件作为脚本类,用来对组合好的参数进行循环执行,依次带入组合参数请求。(只做了请求和打印响应信息,可再加入对响应结果断言)

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2017-06-09 14:22
# jiaoben.py

from changliang import ZHCS
from canshuxinxi import API_ALL
from gongju import gj
import requests
# 脚本类,组合工具参数进行请求
gj = gj()
def jball():
 apikeys = API_ALL.keys()
 print(apikeys)
 for key in apikeys:
 apiname = key
 url = API_ALL[key]['url']
 number = API_ALL[key]['number']
 leixin = API_ALL[key]['leixing']
 canshus = gj.listalls(API_ALL[key]['canshu'], ZHCS)
 if leixin == 'post':
 print("======="+" api名称:"+apiname+"=======")
 for cs in canshus:
 mp = requests.post(url=url, data=cs)
 fhcode = str(mp.status_code)
 xysj = str(mp.elapsed.microseconds)
 print("=响应=api编号:"+number+" 响应code:"+fhcode+" 响应时间:"+xysj)
 if leixin == 'get':
 print("======="+" api名称:"+apiname+"=======")
 for cs in canshus:
 mp = requests.get(url=url, data=cs)
 fhcode = str(mp.status_code)
 xysj = str(mp.elapsed.microseconds)
 print("=响应=api编号:"+number+" 响应code:"+fhcode+" 响应时间:"+xysj)
jball()

tesone.py文件作为用例执行文件,熟悉unittest框架的都清楚其中的原理,就不做多介绍,黑熊主要用来控制脚本的执行,结合了unittest框架后,方便后续的扩展。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2017-06-09 8:53
# tesone.py

import requests
import unittest
import time
from jiaoben import jball
class testclassone(unittest.TestCase):
 def setUp(self):
 print(111)
 pass
 def test_1(self):
 jball()  # 执行脚本
 pass
 def tearDown(self):
 print(333)
 pass


if __name__ == '__main__':
 unittest.main()

最后附上用例执行后的效果图:

下载本文
显示全文
专题