在接口测试的过程中,很多时候会用到对CSV的读取操作,本文主要说明Python3对CSV的写入和读取。
1. 需求
某API,GET方法,token,mobile,email三个参数
- token为必填项
- mobile,email 必填其中1项
- mobile为手机号,email为email格式
2. 方案
针对上面的API,在做接口测试时,需要的测试用例动辄会多达10+, 这个时候采用数据驱动的方式将共性的内容写入配置文件或许会更合适。
这里考虑把API、参数、以及预期结果预行在格式化的CSV里保存,利用csv组件从CSV里读取URL、参数以及预期结果,Requests组件发起请求,将响应结果与预期结果进行比对,***把比对结果写到结果CSV。
流程如下图
3. 实现
(1) 在上代码之前,先安装好如下几个组件:
- csv 读写CSV文件
- json
- requests 发起请求,获取响应结果
- unittest 测试用例调度
(2) data.csv(本示例选取部分用例)
(3) reader_CSV函数代码示例
- import csv
- import json
- import requests
- import time
- import unittest
- def readCSV(self,filename):
- '''
- :param filename: 需要读取的数据文件
- :return: [{data1},{data2}...]
- '''
- datas = []
- try:
- #以DictReader的方式读取数据文件,方便与json互做转换
- with open(filename,'r') as csvfile :
- #从文件里读取到的数据转换成字典列表的格式
- reader = csv.DictReader(csvfile)
- for row in reader:
- data = {}
- data['id'] = row['id']
- data['url'] = row['url']
- data['token'] = str(row['token'])
- data['mobile'] = row['mobile']
- data['email'] = row['email']
- data['expect'] = json.dumps(row['expect']) \
- if isinstance(row['expect'],dict) \
- else row['expect'] #如果expect读取出来的不是json则取其原值,否则转为json格式保存到result里
- datas.append(data)
- return datas
- #如果文件找不到,返回空的datas
- except FileNotFoundError:
- print("文件不存在",filename)
- return datas
(4) request_URL函数示例(包含GET请求和POST请求2个方法)
- def get_request(self,url,params):
- '''
- 通用的调用GET接口方法
- :param url:string 接口路径
- :param params:{"":"","":""} 需要传入的参数
- :return: response响应体
- '''
- print("调用API...")
- r = requests.get(url,paramsparams=params)
- print(r.text)
- return r
- def post_request(self,url,params):
- '''
- 通用的调用POST接口方法
- :param url: string 接口路径
- :param params: {"":"","":""} 需要传入的参数
- :return:response响应体
- '''
- print("调用API...")
- r = requests.post(url,params=json.dumps(params)) #post的方法必须用json.dumps()转化成json格式
- print(r.text)
- return r
(5) assert_Result函数示例
- def assertResult(self,except_value,real_value):
- '''
- 校验样本字符串中是否包含指定字符串
- :param except_value: string 指定字符串
- :param real_value: string 样本字符串
- :return: Boolean 样本中包含指定字符串返回True,否则返回False
- '''
- ifsuccess = except_value in str(real_value)
- return ifsuccess
(6) write_CSV函数示例
- def writeCSV(self,filename,results):
- '''
- 写入csv文件指定内容
- :param filename: string 需要写入的文件名称
- :param results: [{data1},{data2},...] 写入的内容
- :return: 无
- '''
- print("写文件:",filename)
- #以DictWriter的方式写文件
- with open(filename,'w+') as csvfile:
- headers="id,url,token,mobile,email,expect,real_value,assert_value".split(",")
- writer = csv.DictWriter(csvfile,fieldnames=headers)
- #写表头
- writer.writeheader()
- #写数据
- if results.__len__() > 0 :
- for result in results:
- writer.writerow(result)
- csvfile.close()
(7) test_interface1函数示例
- def test_interface1(self):
- #指定读取的数据文件名称
- data_file = "../data/data.csv"
- #指定最终结果生成的数据文件名称
- result_file = "../data/result_{}.csv".format(str(time.time()).split(".")[0])
- #读取指定文件的数据
- datas = self.readCSV(data_file)
- #数据文件有内容则调用接口,否则直接测试结束
- if datas.__len__() > 0:
- results =[]
- #获取数据文件里的每一行
- for testcase in datas :
- result = {}
- result["id"] = testcase["id"]
- result["url"] = testcase["url"]
- result["token"] = testcase["token"]
- result["mobile"] = testcase["mobile"]
- result["email"] = testcase["email"]
- result["expect"] = testcase["expect"]
- #组装参数
- params = {
- "token":result["token"],
- "mobile":result["mobile"],
- "email":result["email"]
- }
- #调用API接口,获取响应结果
- real_value = self.get_request(result["url"],params)
- #调用assert方法,检查预期结果是否在响应结果中存在
- assert_value = self.assertResult(result["expect"],real_value.text)
- result["real_value"] = real_value.text
- result["assert_value"] = assert_value
- #获取每一行里的所有字段以及实际结果和验证结果
- results.append(result)
- #执行完所有记录后,将所有结果写入result.csv
- self.writeCSV(result_file,results) #写入csv文件
- print("测试结束")
8result_1523956055.csv(本示例中的测试结果请忽略)
4. 总结
python封装了很多方法,对于测试来说开发速度相对较快,接口自动化测试如果采用CSV管理的数据驱动方式,使用csv+requests是测试开发不容错过的利器之一。
【本文是51CTO专栏机构“岂安科技”的原创文章,转载请通过微信公众号(bigsec)联系原作者】