需求:python脚本实现【添加发布会信息】的接口测试,以邮件形式发送测试报告
1.新建一个case目录,存放测试用例
2.新建一个config目录,存放配置信息和读取配置信息
3.新建一个db_fixture目录,初始化数据
4.新建report目录,用来存放生成的测试报告
5.run_main.py文件,执行接口测试脚本
(一般还会新建一个common目录,存放一些公共方法,例如读取excel方法等)
1.config部分
(1)db_config.ini 数据库配置信息(此处需注意,这里的数据库需要与实际项目的数据库一致)
# coding:utf-8
# 数据库配置信息
[mysqlconf]
host = 47.xx.xxx.xx
port = 3306
user = root
password = 123456
db = guest
(2) readDbConfig.py 读取数据库信息,封装清除数据和插入数据的方法,以便进行初始化数据的操作
#coding:utf-8
from pymysql import connect,cursors
from pymysql.err import OperationalError
import os
import configparser
# ================读取db_config.ini文件设置=================
cur_path = os.path.dirname(os.path.realpath(__file__))
configPath = os.path.join(cur_path,"db_config.ini")
cf = configparser.ConfigParser()
cf.read(configPath,encoding='UTF-8')
host = cf.get("mysqlconf","host")
port = cf.get("mysqlconf","port")
db = cf.get("mysqlconf","db")
user = cf.get("mysqlconf","user")
password = cf.get("mysqlconf","password")
# ================封装MySQL基本操作=================
class DB:
def __init__(self):
try:
# 连接数据库
self.conn = connect(
host = host,
user = user,
password = password,
db = db,
charset = "utf8mb4",
cursorclass = cursors.DictCursor
)
except OperationalError as e:
print("Mysql Error %d:%s"%(e.args[0],e.args[1]))
# 清除表数据
def clear(self,tabel_name):
real_sql = "delete from "+ tabel_name +";"
with self.conn.cursor() as cursor:
cursor.execute("SET FOREIGN_KEY_CHECKS = 0;")
cursor.execute(real_sql)
self.conn.commit()
# 插入表数据
def insert(self,table_name,table_data):
for key in table_data:
table_data[key] = "'"+str(table_data[key])+"'"
key = ','.join(table_data.keys())
value = ",".join(table_data.values())
real_sql = "INSERT INTO " + table_name + " (" + key + ") VALUES (" + value +")" + ";"
print(real_sql)
with self.conn.cursor() as cursor:
cursor.execute(real_sql)
self.conn.commit()
# 关闭数据库连接
def close(self):
self.conn.close()
if __name__ == '__main__':
db = DB()
table_name = "sign_event"
data = {"id":12,
"name":"红米",
"limit2":2000,
"status":1,
"address":"北京会展中心",
"start_time":"2018-10-30 08:00:00",
}
db.clear(table_name)
db.insert(table_name,data)
db.close()
(3) email_config.ini 邮箱信息
# coding:utf-8
# 邮箱配置信息
[email]
smtp_server = smtp.qq.com
port = 465
sender = [email protected]
psw = xxxxxxxx
receiver = [email protected]
(4) readEmailConfig.py 读取邮件信息
#coding:utf-8
# ================读取cfg.ini文件设置=================
import os
import configparser
# os.path.realpath(__file__):返回当前文件的绝对路径
# os.path.dirname(): 返回()所在目录
cur_path = os.path.dirname(os.path.realpath(__file__)) # 当前文件的所在目录
configPath = os.path.join(cur_path,"email_config.ini") # 路径拼接:/config/email_config.ini
conf = configparser.ConfigParser()
conf.read(configPath,encoding='UTF-8') # 读取/config/email_config.ini 的内容
# get(section,option) 得到section中option的值,返回为string类型
smtp_server = conf.get("email","smtp_server")
sender = conf.get("email","sender")
psw = conf.get("email","psw")
receiver = conf.get("email","receiver")
port = conf.get("email","port")
2.db_fixture部分
(1)test_data.py 添加测试数据
# coding:utf-8
from config.readDbConfig import DB
# 创建测试数据
datas = {
# 发布会表数据
"sign_event":[
{"id":1,"name":"红米Pro发布会","limit2":2000,"status":1,"address":"北京会展中心","start_time":"2018-10-31 08:00:00"},
{"id":2,"name":"可参加人数为0","limit2":0,"status":1,"address":"北京会展中心","start_time":"2018-10-31 08:00:00"},
{"id":3,"name":"当前状态为0关闭","limit2":2000,"status":0,"address":"北京会展中心","start_time":"2018-10-31 08:00:00"},
{"id":4,"name":"发布会已结束","limit2":2000,"status":1,"address":"北京会展中心","start_time":"2017-10-31 08:00:00"},
{"id":5,"name":"小米5发布会","limit2":2000,"status":1,"address":"北京会展中心","start_time":"2018-10-31 08:00:00"}
]
}
# 将测试数据插入表
def init_data():
db = DB()
for table,data in datas.items():
db.clear(table)
for d in data:
db.insert(table,d)
db.close()
if __name__ == '__main__':
init_data()
3.case部分
(1)test_add_event.py 测试用例
# coding:utf-8
import unittest
import requests
import os,sys
cur_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0,cur_path)
from db_fixture import test_data
class TestAddEvent(unittest.TestCase):
"""添加发布会"""
def setUp(self):
self.base_url = "http://47.xx.xxx.xx:8000/api/add_event/"
def tearDown(self):
print("")
def test_add_event_all_null(self):
"""所有参数为空添加"""
payload = {"eid":"","name":"","limit2":"","address":"","start_time":""}
r = requests.post(self.base_url,data=payload)
self.result = r.json()
self.assertEqual(self.result["status"],10021)
self.assertEqual(self.result["message"],"parameter error")
def test_add_event_eid_exist(self):
"""id已经存在"""
payload = {"eid":1,"name":"一加4发布会","limit2":2000,"address":"深圳宝体","start_time":"2018-11-01 08:00:00"}
r = requests.post(self.base_url, data=payload)
self.result = r.json()
self.assertEqual(self.result["status"], 10022)
self.assertEqual(self.result["message"], "event id already exists")
def test_add_event_name_exists(self):
"""名称已经存在"""
payload = {"eid": 88, "name": "红米Pro发布会", "limit2": 2000, "address": "深圳宝体", "start_time": "2018-11-01 08:00:00"}
r = requests.post(self.base_url, data=payload)
self.result = r.json()
self.assertEqual(self.result["status"], 10023)
self.assertEqual(self.result["message"], "event name already exists")
def test_add_event_data_type_error(self):
"""日期格式错误"""
payload = {"eid": 102, "name": "一加4发布会", "limit2": 2000, "address": "深圳宝体", "start_time": "2018"}
r = requests.post(self.base_url, data=payload)
self.result = r.json()
self.assertEqual(self.result["status"], 10024)
def test_add_event_success(self):
"""添加成功"""
payload = {"eid": 88, "name": "孙小二发布会", "limit2": 2000, "address": "深圳宝体", "start_time": "2018-11-01 08:00:00"}
r = requests.post(self.base_url, data=payload)
self.result = r.json()
print(self.result)
self.assertEqual(self.result["status"], 200)
if __name__ == '__main__':
test_data.init_data() # 初始化接口测试数据
unittest.main()
4.run_main.py 执行脚本
# coding:utf-8
import os
import unittest
import time
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from db_fixture import test_data
import HTMLTestRunnerCN_test
from config import readEmailConfig
# 当前脚本所在文件真实路径
cur_path = os.path.dirname(os.path.realpath(__file__))
def add_case(caseName="case",rule="test_*.py"):
"""第一步:加载所有测试用例"""
case_path = os.path.join(cur_path,caseName) # 用例文件夹
# 文件夹不存在就创建一个文件夹
if not os.path.exists(case_path):os.mkdir(case_path)
# 定义discover加载所有测试用例
# case_path:执行用例的目录;pattern:匹配脚本名称的规则;top_level_dir:默认为None
discover = unittest.defaultTestLoader.discover(case_path,pattern=rule,top_level_dir=None)
return discover
def run_case(all_case,reportName="report"):
"""第二步:执行所有的用例,并把结果写入到html测试报告中"""
now = time.strftime("%Y_%m_%d_%H_%M_%S")
report_path = os.path.join(cur_path,reportName)
if not os.path.exists(report_path):os.mkdir(report_path)
report_abspath = os.path.join(report_path,now+"result.html")
print("report path:%s"%report_abspath)
fp = open(report_abspath,"wb")
runner = HTMLTestRunnerCN_test.HTMLTestRunner(stream=fp,title="自动化接口测试报告,测试结果如下:",
description="用例执行情况")
# 调用add_case函数
runner.run(all_case)
fp.close()
def get_report_file(report_path):
"""第三步:获取最新的测试报告"""
lists = os.listdir(report_path)
lists.sort(key=lambda fn:os.path.getmtime(os.path.join(report_path,fn)))
print("最新测试生成的报告:"+lists[-1])
# 找到生成最新的报告文件
report_file = os.path.join(report_path,lists[-1])
return report_file
def send_mail(sender,psw,receiver,smtpserver,report_file,port):
"""第四步:发送最新的测试报告内容"""
with open(report_file,"rb") as f:
mail_body = f.read()
# 定义邮件内容
msg = MIMEMultipart()
body = MIMEText(mail_body,_subtype="html",_charset="utf-8")
msg["Subject"] = "自动化测试报告"
msg["from"] = sender
msg["to"] = receiver
msg.attach(body)
# 添加附件
att = MIMEText(open(report_file,"rb").read(),"base64","utf-8")
att["Content-Type"] = "application/octet-stream"
att["Content-Disposition"] = "attachment;filename = 'report.html'"
msg.attach(att)
try:
smtp = smtplib.SMTP_SSL(smtpserver,port)
except:
smtp = smtplib.SMTP()
smtp.connect(smtpserver,port)
# 用户名密码
smtp.login(sender,psw)
smtp.sendmail(sender,receiver,msg.as_string())
smtp.quit()
print("test report email has send out")
if __name__ == '__main__':
test_data.init_data() # 初始化接口测试数据
all_case = add_case() # 加载用例
run_case(all_case) # 执行用例
report_path = os.path.join(cur_path,"report")
report_file = get_report_file(report_path)
# 邮箱配置,邮箱信息获取
sender = readEmailConfig.sender
psw = readEmailConfig.psw
smtp_server = readEmailConfig.smtp_server
port = readEmailConfig.port
receiver = readEmailConfig.receiver
send_mail(sender,psw,receiver,smtp_server,report_file,port) # 调用发送邮件方法
1.执行run_main.py 脚本会在report目录生成一个html文件
2.用例全部执行通过