接口自动化测试
自动化测试
- 单元测试 unittest pytest
- 接口自动化测试 requests
- 功能UI自动化测试
- 性能自动化测试
requests
- 发送get\post请求
get()
url请求路径
params --get当时请求参数
post()
url请求路径
data传递键值对方式的参数 —x-www-form-urlencoded
json传递json文本数据
**kwargs
headers请求头
files文件
所有的参数传递都是字典格式传递 — params data json headers files — - 响应结果查看
print(“登陆结果_text文本格式查看:”, login_result.text)
print(“登陆结果_json格式查看:”, login_result.json())
print(“登陆结果_status_code状态码查看:”, login_result.status_code)
print(“登陆结果响应头:”, login_result.headers - 请求参数查看
print(“请求路径01:”, login_result.url)
print(“请求方式02:”, login_result.request.url)
print(“请求方式:”, login_result.request.method)
print(“请求头:”, login_result.request.headers)
print(“请求体:”, login_result.request.body)
文件上传
获取文件路径
f = {“pic”:open(file=“D:/tupian.jpg”,mode=“rb”)}
传递文件参数
result = requests.post(url=baseurl,data=a,files=f)
接口依赖
# 获取验证码接口
phone = "13214114324"
code_data = {"mobile":phone}
code_result = requests.post(url='',data=code_data)
# 获取验证码
code = code_result.json()['data']
# 登录接口
login_data = {'mobile':phone,'smscode':code}
login_result = requests.post(url='',data=login_data)
# 获取token
token = login_result,json()['data']['token']
uid = login_result.json()['data']['user']['id']
# 添加购物车 ---json报文格式,请求头添加
j = {"count":1,"idgoods":2,"idsku":3,"iduser":uid]
h = {"authorization":token}
cart_result = requests.post(url='',json=j,headers=h)
接口自动化测试框架搭建
整体框架
1、log日志模块
import logging
# 设置日志打印模块
class Logger(logging.Logger):
# 初始化函数 cmd_level控制台打印时日志默认级别 file_level写入日志文件默认级别
def __init__(self, name='Dash',cmd_level=logging.DEBUG, file_level=logging.DEBUG):
# 调用父类初始化函数
super().__init__(name)
try:
self.setLevel(logging.DEBUG) # 设置日志输出的默认级别
# 日志输出格式
fmt = logging.Formatter('[%(asctime)s] %(filename)s->%(funcName)s line:%(lineno)d [%(levelname)s]%(message)s')
# 日志文件路径及名称...手动创建logs文件夹
self.log_file = '../logs/runlog.txt'
# 设置控制台输出
sh = logging.StreamHandler()
sh.setFormatter(fmt) # 设置控制台输出格式
sh.setLevel(cmd_level) #设置控制台输出的默认级别
# 设置文件输出
fh = logging.FileHandler(self.log_file,'a', encoding='utf-8')
fh.setFormatter(fmt)
fh.setLevel(file_level)
# 添加日志输出方式
self.addHandler(sh)
self.addHandler(fh)
except Exception as e:
raise e
# 初始化logger对象 供外面使用
logger = Logger()
2、Yml接口配置
name: *
method: *
url: *
headers: ~
params: ~
data: ~
json: ~
validate:
statusCode: ~
errorCode: ~
msg: ~
3、读取yaml配置数据
import yaml
from util.log import logger
class YamlUtil:
def __init__(self,file):
self.file =file
def getYamlData(self):
f = open(file=self.file,mode="r",encoding="utf-8")
j = yaml.load(stream=f,Loader=yaml.FullLoader)
logger.info("读取yaml数据:" +str(j))
return j
# if __name__ == '__main__':
# yu = YamlUtil('../config/erJi.yml')
# yu.getYamlData()
4、获取Csv接口数据
import csv
class GetCsv:
def __init__(self,file):
self.file = file
def getcsv_util(self):
# 第一步
f = open(file=self.file,mode="r",encoding="utf-8-sig")
reader = list(csv.reader(f))
# print(reader) # 打印读取csv数据
# keys = reader[0] # 获取csv第一行数据 keys
# print(keys)
# 第三步
# 定义一个空列表,准备装字典数据
dict_list = []
# 第二步
for value in range(1,len(reader)): # 从第二行开始获取所有得value
keys = reader[0]
values = reader[value]
# print(values) # 打印所有得value
dict = {} # 定义一个空字典,准备装数据
for j in range(len(keys)):
dict[keys[j]] = values[j] # 组装keys和values
# print(dict) # 打印查看一下
dict_list.append(dict) # 把字典数据装到列表里面
print(dict_list) # 打印一下看看装得对不对
return dict_list
if __name__ == '__main__':
cu = GetCsv('../data/erJi.csv')
cu.getcsv_util()
5、获取接口测试所需要数据
组装yaml和csv数据
from apiUrl import HOST_URL
from util.csvUtil import CsvUtil
from util.log import logger
from util.yamlUtil import YamlUtil
class RequestDataUtil:
def __init__(self,filename):
self.yamlFile = '../config/'+filename+'.yml'
self.csvFile = '../data/'+filename+'.csv'
def requestData(self):
# 1.获取yaml工具对象
yamldata = YamlUtil(self.yamlFile)
# yamldata.getYamlData()
# 2.获取csv工具对象
csvdata = CsvUtil(self.csvFile)
# csvdata.getCsvData()
requestdatalist = []
# 遍历csv列表数据,dict表示一行数据
for dict in csvdata.getCsvData():
yamlDict = yamldata.getYamlData()
# 1.url拼接
yamlDict['URL1'] = HOST_URL + yamlDict['url']
# 2.判断headers
headers = yamlDict['headers']
if headers != None:
for key in headers.keys():
headers[key] = dict[key]
# 3.判断params
params = yamlDict['params']
if params != None:
for key in params.keys():
params[key] = dict[key]
# 4.判断data
data = yamlDict['data']
if data != None:
for key in data.keys():
data[key] = dict[key]
# 5.判断json
json = yamlDict['json']
if json != None:
for key in json.keys():
json[key] = dict[key]
# 6.判断validate
validate = yamlDict['validate']
if validate != None:
for key in validate.keys():
validate[key] = dict[key]
# 添加到列表
requestdatalist.append(yamlDict)
logger.info("组装请求数据:"+str(requestdatalist))
return requestdatalist
if __name__ == '__main__':
ru = RequestDataUtil('erJi')
ru.requestData()
6、网络请求工具类
import requests
from util.log import logger
class RequestUtil:
def __doGet(self,url,params=None,**kwargs):
result = requests.get(url=url,params=params,**kwargs)
logger.info('请求路径:'+str(result.request.url))
logger.info('请求方式:'+str(result.request.method))
logger.info('请求头:'+str(result.request.headers))
logger.info('请求体:'+str(result.request.body))
logger.info('响应状态码:' +str(result.status_code))
logger.info('响应头:' +str(result.headers))
logger.info('响应文本内容:' +str(result.text))
return result
def __doPost(self,url,data=None,json=None,**kwargs):
result = requests.post(url=url,data=data,json=json,**kwargs)
logger.info('请求路径:' + str(result.request.url))
logger.info('请求方式:' + str(result.request.method))
logger.info('请求头:' + str(result.request.headers))
logger.info('请求体:' + str(result.request.body))
logger.info('响应状态码:' + str(result.status_code))
logger.info('响应头:' + str(result.headers))
logger.info('响应文本内容:' + str(result.text))
return result
def doRequest(self,method,url,parsms=None,data=None,json=None,**kwargs):
if method == 'GET':
return self.__doGet(url=url,params=parsms,**kwargs)
elif method == 'POST':
return self.__doPost(url=url,data=data,json=json,**kwargs)
else:
logger.info('暂时不支持的请求方式')
7、 单接口测试用户编写
import pytest
from util.requestDataUtil import RequestDataUtil
from util.requestUitl import RequestUtil
# 1、获取请求数据
rq = RequestDataUtil('login')
list = rq.requestData()
@pytest.fixture(scope='function',params=list)
def getData(request):
return request.param
# 3、获取网络请求工具对象
ru = RequestUtil()
class TestLogin:
def test_Login(self):
# 2、发送请求
result = ru.doRequest(method=getData['method'],url=getData['url'],headers=getData['headers'],params=getData['params'],data=getData['data'],json=getData['json'])
# 4、响应断言
ru.assertResult(result,getData['validate']['statusCode'],getData['validate']['errorCode'],getData['validate']['msg'])
8、运行测试用例、生成报告
import pytest
'''
1.执行main函数 进行pytest单元测试
2.执行allure执行 生成报告
allure generate ./json -o ./report --clean
3.启动allure服务
allure open report --host 192.168.1.165 --port 8800
输入地址 查看报告
'''
if __name__ == '__main__':
pytest.main(['-v', '-s', '../testcases', '--alluredir=../json'])
8、场景多接口测试用例编写
1、编写yaml文件
2、封装全局变量模块
"""
封装全局变量,存储,读取
"""
from util.log import logger
class Variable:
# 存储存储成键值对格式
def set(self,key,value):
# 打印一下
logger.info('保存键值对:key=:'+ str(key)+"value=:"+str(value))
# 保存成键值对格式
setattr(self,key,value)
# 读取,只读取key就ok
def get(self,key):
# 打印一下
logger.info("获取键值对:key=" +str(key))
if hasattr(self,key):
return getattr(self,key)
else:
return None
var = Variable()
# if __name__ == '__main__':
# var.set('name','duanyue')
# print(var.get("name"))