前言
这个季度初的时候, 我们公司管理层提出了全面提升部门技术水准的要求, 而作为项目开发流程中最重要的一环 -- 测试, 我们也是有自己的技术追求的, 所以为了, 由原来的业务功能测试转变成自动化测试. 之前大多都是手工进行, 利用 postman 和 fiddler 进行抓包和截取数据, 后来, 经过大家的讨论, 决定基于 python 学习, 开始搞接口自动化, 经过大家的努力, 这套自动化框架目前已经基本完成了, 于是进行一些总结, 便于以后回顾温习, 有许多不完善的地方, 大家可以留言一起讨论研究, 共同进步.
首先, 我们可以捋一捋思路, 想一想接口测试的流程
其次, 选择合适的框架
流程清晰之后, 我们需要选择一个合适的框架, 于是选择了 Python3+requests+unittest 框架
Requests 模块发送 http 的网络请求, 请求类型主要包含了 post,get, PUT,DELETE,HEAD
python+unittest 单元测试框架构成, 和测试报告生成 (htmlTestRunner)
框架详解不在此赘述, requests 可参考 点击前往
unittest 参考 点击前往 https://www.jianshu.com/p/a73a9b68abbf
基于以上, 我们来一步步搭建我们的框架. 在这个过程中, 我们需要做到业务和数据的分离, 这样才能灵活, 达到我们写框架的目的. 接下来, 我们来进行结构的划分.
我们的结构是这样的
data: 存放自动化测试所用到的数据文档
log: 存放生成的日志文件
base: 存放公共的方法
report: 存放生成的自动化测试报告
testcase: 存放测试脚本
接下来, 公共方法的开发
整体结构有了划分, 接下来就该一步步的填充整个框架了, 我们先来看看 Base 文件中的公共类或函数, 这主要用于后续测试 case 的调用, 所有公共的, 一成不变的数据都可以放在这里, 维护也方便
配置文档如下
- [DATABASE]
- data_address = ./data/
- report_address = ./report/
- [HTTP]
- base_url = http://xxx.xx
想知道怎样从配置文档中得到或写入相应的数据吗? 那继续看吧
- import os
- import configparser
- # 获取当前 py 文件地址
- proDir = os.path.split(os.path.realpath(__file__))[0]
- # 组合 config 文件地址
- configPath = os.path.join(proDir,"config.ini")
- class ReadConfig:
- def __init__(self):
- #获取当前路径下的配置文件
- self.cf = configparser.ConfigParser()
- self.cf.read(configPath)
- def get_config(self,field,key):
- #获取配置文件中的 key 值
- result = self.cf.get(field,key)
- return result
- def set_config(self,field,key,value):
- #向配置文件中写入配置信息
- fb = open(configPath,'w')
- self.cf.set(field,key,value)
- self.cf.write(fb)
那问题又来了, 我们的测试数据放在哪里? 怎么取值? 怎么写入? 怎么保存?...
别急, 接着往下看
测试数据优先考虑放在 Excel 或 database 中, 此处以 Excel 为例做个简单介绍
这里需要用到两个操作表格的库, xlrd 数据驱动的读取, 作用于 Excel 文档, 但 xlrd 不能写入数据, 所以引入 xlutils 数据驱动的读取和写入
安装方法可以用 pip3 install xlrd 和 pip3 install xlutils 来安装.
- import xlrd
- import xlutils.copy
- from Base.readConfig import ReadConfig
- import time
- class ReadExcel:
- def __init__(self,section,field,sheet):
- # 打开工作表, 并定位到 sheet
- data_address = ReadConfig().get_config(section,field)
- workbook = xlrd.open_workbook(data_address)
- self.table = workbook.sheets()[sheet]
- def get_rows(self):
- # 获取 Excel 行数
- rows = self.table.nrows
- return rows
- def get_cell(self,row,col):
- # 获取单元格数据
- cell_data = self.table.cell(row,col).value
- return cell_data
- def get_col(self,col):
- # 获取整列数据
- col_data = self.table.col_value(col)
- return col_data
- class WriteExcel:
- def __init__(self,section,field,sheet):
- # 打开工作表
- self.address = ReadConfig().get_config(section,field)
- self.workbook = xlrd.open_workbook(self.address)
- self.wf = xlutils.copy.copy(self.workbook)
- self.ws = self.wf.get_sheet(sheet)
- def set_cell(self,row,col,value):
- #设置单元格数据
- self.ws.write(row,col,value)
- def save_excel(self,filename,format):
- #获取当前时间
- self.time = time.strftime("%Y%m%d%H%M%S", time.localtime())
- #生成文件的文件名及格式
- self.report = filename + '_' +self.time + format
- #保存文件
- self.wf.save(self.report)
然后, 测试脚本的编辑
一切准备就绪, 下面通过一个简单的, 完整的代码进行演示公共函数的调用, 框架的使用及报告的生成
- import unittest
- import requests
- from Base.readConfig import ReadConfig
- from Base.readExcel import ReadExcel
- from Base.readExcel import WriteExcel
- # 实例化
- readexcel = ReadExcel('DATABASE','data_address',0)
- writeexcel = WriteExcel('DATABASE','data_address',0)
- class testcase(unittest.TestCase):
- #初始化
- def setUp(self):
- #获取 url
- self.base_url = ReadConfig().get_config('HTTP', 'base_url')
- self.url = self.base_url + readexcel.get_cell(1,1)
- #获取请求头
- self.headers = readexcel.get_cell(1,4)
- def test_case(self):
- nok = 0
- ner = 0
- # 循环读取 Excel 中的测试数据, 进行结果验证, 并生成 Excel 形式的测试报告
- for i in range(3,readexcel.get_rows()):
- #发送网络请求, 得到响应值
- response = requests.post(self.url, headers=self.headers, data=readexcel.get_cell(i,4).encode('utf-8'))
- actualresult = response.JSON()
- #获取 Excel 中的预期结果
- expectresult = eval(readexcel.get_cell(i,6))
- # 获取需验证的数据
- key = eval(readexcel.get_cell(i, 5))
- keylen = len(key)
- j = 0
- for k in range(keylen):
- aresult = 'actualresult' + key[k]
- eresult = 'expectresult' + key[k]
- if eval(aresult) == eval(eresult):
- #预期结果和实际结果一致
- j = j + 1
- if j == keylen:
- #测试数据执行通过
- nok = nok + 1
- writeexcel.set_cell(i, 8, 'SUCCESS')
- else:
- # 测试数据执行失败, 并将实际结果写入 Excel
- ner = ner + 1
- writeexcel.set_cell(i, 8, 'FAILURE')
- writeexcel.set_cell(i, 7, str(actualresult))
- print('第', i + 1, '行用例执行失败: 预期结果是', expectresult, '实际结果是', actualresult)
- # 保存测试报告
- writeexcel.save_excel('testreport', '.xls')
- print('测试数据中总共', nok, '条用例执行通过', ner, '条用例执行失败')
- #释放资源
- def tearDown(self):
- pass
- if __name__ == '__main__':
- #构造测试集合
- suite = unittest.TestSuite()
- suite.addTest(testcase('test_case'))
- #创建 HTML 文件
- filename = ReadConfig().get_config('DATABASE', 'report_address') + 'testreport.html'
- fb = open(filename,"wb")
- #执行测试并生成 HTML 测试报告
- runner = HTMLTestRunner.HTMLTestRunner(stream = fb,description = '针对接口的描述信息',title = '某某的自动化测试报告')
- runner.run(suite)
- #关闭文件
- fb.close()
最后, 生成的 HTML 报告
以上是最近总结的部分成果, 希望对大家有帮助, 后续会陆续更新, 也请大家多多留言, 互相交流互相成长
来源: https://juejin.im/post/5c050dffe51d45636350f1a0