前言:该篇重点讲数据依赖、cookie处理和发送邮件(部分方法在第一篇中已经编写)
一、 数据依赖简单说明
接口B的请求数据依赖于接口A的返回数据,即为数据依赖。比如说:接口B(图2)是一个支付接口,接口A(图1)是一个订单提交接口。接口B中请求数据trade_number的值来源于接口A的响应数据out_trade_no的值
图 1
图 2
二、 解决数据依赖方法封装
创建文件 dataconfig/dependent_data.py
from utils.operation_excel import OperationExcel
from base.run_method import RunMethod
from dataconfig.get_data import GetData
import json
from jsonpath_rw import jsonpath,parse
class DependentData(object):
def __init__(self, case_id):
self.opera_excel = OperationExcel()
self.case_id = case_id
self.data = GetData()
# 通过case_id获取该case_id的整行数据
def get_case_line_data(self):
rows_data = self.opera_excel.get_rows_data(self.case_id)
return rows_data
# 执行依赖测试,获取结果
def run_dependent(self):
run_method = RunMethod()
row_num = self.opera_excel.get_row_num(self.case_id)
request_data = self.data.get_data_from_json(row_num)
method = self.data.get_request_method(row_num)
url = self.data.get_url(row_num)
res = run_method.run_main(method, url, request_data)
return json.loads(res)
# 根据依赖的key去获取执行依赖测试的case响应,然后返回
def get_data_for_key(self, row):
# 依赖的返回数据的格式要注意层级关系
depend_data = self.data.get_depend_key(row)
response_data = self.run_dependent()
# jsonpath_rw类似于xpath
json_exe = parse(depend_data)
# 从响应数据结果集中找到依赖的返回数据
model = json_exe.find(response_data)
# 类似于for循环,i是字典类型的
return [math.value for math in model][0]
三、 cookie处理简单说明
访问某些接口前需要登录,即需要携带cookies才能访问成功,则需要先访问登录接口,然后把cookies信息存储在json文件中
实例:接口A(登录接口)请求后,自动调用接口B。接口B使用接口A中的token作为请求数据,且返回cookies。访问接口C时,必须携带cookies才能访问成功,如下图所示,接口顺序依次是A、B和C
用例修改如下,运行时会判断“是否携带header”字段的值:
四、 封装处理cookies方法
1. 创建 utils/operation_header.py
import requests
import json
from utils.operation_json import OperationJson
class OperationHeader(object):
def __init__(self, response):
self.response = json.loads(response)
# 获取登录返回的响应数据中url的内容,根据实际接口情况来编写该方法
def get_response_url(self):
url = self.response['data']['url'][0]
return url
# 获取cookie的jar文件
def get_cookie(self):
# 请求数据中除了url,还有另外两个参数callback和_
url = self.get_response_url()+"&callback=jQuery21008240514814031887_1508666806688&_=1508666806689"
cookie = requests.get(url).cookies
return cookie
def write_cookie(self):
cookie = requests.utils.dict_from_cookiejar(self.get_cookie())
op_json = OperationJson()
op_json.write_data(cookie)
2. 创建空文件data/cookie.json ,运行程序后该文件中存储cookies的值
五、 发送邮件
创建文件 utils/send_mail.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from email.mime.multipart import MIMEMultipart
from email.header import Header
from email.mime.text import MIMEText
import smtplib
class SendEmail(object):
def send_mail(self, user_list, subject, content, file):
smtpserver = 'smtp.qq.com'
user = '[email protected]'
password = "XXX"
sender = '[email protected]'
receives = user_list
# 构造邮件对象
msg = MIMEMultipart('mixed')
# 定义邮件的标题
subject = subject
# HTML邮件正文,定义成字典
msg['Subject'] = Header(subject, "utf-8")
msg['From'] = sender
msg['To'] = ','.join(receives)
# 构造文字内容
text_plain = MIMEText(content)
msg.attach(text_plain)
# 构造附件
text_attr = MIMEText(file, 'base64', 'utf-8')
text_attr["Content-Type"] = 'application/octet-stream'
text_attr['Content-Disposition'] = 'attachment; filename = "report.xls"'
msg.attach(text_attr)
# 邮箱设置时勾选了SSL加密连接,进行防垃圾邮件,SSL协议端口号要使用465???
smtp = smtplib.SMTP_SSL(smtpserver, 465)
# 向服务器标识用户身份
smtp.helo(smtpserver)
# 向服务器返回确认结果
smtp.ehlo(smtpserver)
# 登录邮箱的账号和授权密码
smtp.login(user, password)
print("start send email...")
# 开始进行邮件的发送,msg表示已定义的字典
smtp.sendmail(sender, receives, msg.as_string())
smtp.quit()
print("send email end")
def send_main(self, pass_list, fail_list):
pass_num = float(len(pass_list))
fail_num = float(len(fail_list))
count_num = pass_num + fail_num
pass_result = "%.2f%%" % (pass_num/count_num*100)
fail_result = "%.2f%%" % (fail_num / count_num * 100)
user_list = ["[email protected]"]
subject = "接口自动化测试报告"
content = "此次一共运行接口个数为%s个,通过个数为%s个,失败个数为%s,通过率为%s,失败率为%s" % (count_num, pass_num, fail_num, pass_result, fail_result)
file = open("../data/imooc_case.xls", 'rb').read()
self.send_mail(user_list, subject, content, file)
六、 连接数据库
创建文件 utils/connect_db.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import pymysql
import json
class OperationMysql(object):
def __init__(self):
self.connect = pymysql.Connect(
host='localhost',
port=3306,
user='admin',
passwd='111111',
db='MySQL',
charset='utf8'
)
self.cur = self.connect.cursor()
# 查询一条数据
def search_one(self, sql):
# 用execute系列方法执行sql
self.cur.execute(sql)
# fetchone()每次获取一条记录
result = self.cur.fetchone()
# result = self.cur.fetchall()
result = json.dumps(result)
return result
七、 修改run_test.py文件(添加数据依赖、cookies处理和发送邮件)
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from base.run_method import RunMethod
from dataconfig.get_data import GetData
from dataconfig.dependent_data import DependentData
from utils.operation_header import OperationHeader
from utils.operation_json import OperationJson
from utils.common_util import CommonUtil
from utils.send_mail import SendEmail
class RunTest(object):
def __init__(self):
self.data = GetData()
self.run_method = RunMethod()
self.com_util = CommonUtil()
self.send_mail = SendEmail()
# 执行程序
def go_on_run(self):
pass_count = []
fail_count = []
# 下标从0开始
rows_count = self.data.get_case_lines()
# 从下标1开始循环取数据,忽略第一行表头数据
for i in range(1, rows_count):
is_run = self.data.get_is_run(i)
if is_run:
method = self.data.get_request_method(i)
url = self.data.get_url(i)
# data = self.data.get_request_data(i)
data = self.data.get_data_from_json(i)
headers = self.data.get_is_header(i)
# expect = self.data.get_expect_data_from_mysql(i)
expect = self.data.get_expect_data(i)
depend_case = self.data.get_is_depend(i)
'''
暂时没用到数据依赖
'''
if depend_case != None:
self.depend_data = DependentData(depend_case)
# 获取依赖的响应数据
depend_response_data = self.depend_data.get_data_for_key(i)
# 获取数据依赖字段
depend_key = self.data.get_depend_field(i)
# 请求数据中的“数据依赖字段"的值更新成“依赖的返回数据”
data[depend_key] = depend_response_data
if headers == "write":
res = self.run_method.run_main(method, url, data)
op_header = OperationHeader(res)
op_header.write_cookie()
elif headers == "yes":
op_json = OperationJson('../data/cookie.json')
cookie = op_json.get_data('apsid')
cookies = {
'apsid': cookie
}
res = self.run_method.run_main(method, url, data, cookies)
else:
res = self.run_method.run_main(method, url, data)
if self.com_util.is_contain(expect, res):
self.data.write_result(i, 'pass')
pass_count.append(i)
else:
self.data.write_result(i, res)
fail_count.append(i)
print("成功的用例数:", len(pass_count))
print("失败的用例数:", len(fail_count))
self.send_mail.send_main(pass_count, fail_count)
if __name__ == '__main__':
run = RunTest()
run.go_on_run()
运行结果:
备注:数据依赖未调试通,暂时删除了需要用到数据依赖的接口
八、 项目目录:
九、 持续集成
1. 使用jenkins,配置项目信息。具体步骤:新建任务(选择第一个自由风格)->使用自定义的工作空间(目录是要运行的文件所在的路径),如图1->构建选择“执行windows批处理命令”,并输入如下命令,如图2
图1
图2
2.运行结果如下:
3.报错解决办法: