本文共 9808 字,大约阅读时间需要 32 分钟。
前期的工作,做的已经差不多ok,咱们开始进行搭建运行项目之旅
在data.py里面增加 进行测试报告数据重组的方法
def testsuite2data(data):
# 进行测试报告同步头部标题和内容对应
result = [[header_custom[key.lower()] for key in report_header.values()]]
for d in data:
s = d['steps'][0]
testcase = [d.get('id', 'id'), d.get('title', 'title'), d.get('testdot', 'testdot'), s.get('no', 'no'),
s.get('_keyword', '_keyword'), s.get('page', 'page'), s.get('_element', '_element'),
s.get('data', 'data'),
s.get('output', 'output'),
s.get('expected', 'expected'), d.get('designer', 'designer'), s.get('score', 'score'),
s.get('_resultinfo', '')]
result.append(testcase)
for s in d['steps'][1:]:
step = ['', '', s.get('testdot', 'testdot'), s.get('no', 'no'), s.get('_keyword', '_keyword'),
s.get('page', 'page'), s.get('_element', '_element'), s.get('data', 'data'),
s.get('output', 'output'),
s.get('expected', 'expected'),
d.get('designer', 'designer'), s.get('score', 'score'), s.get('_resultinfo', '_resultinfo')]
result.append(step)
return result;
1.增加Junit.py文件(生成xml测试报告,用于展示allure测试报告)
2.增加testcase.py文件(执行测试用例,记录请求过程)
3.增加autotest.py文件(执行用例,生成Excel测试报告和发送邮件)
4.增加httpstart.py文件(启动测试的文件)
Junit.py 代码如下
import timeit
from xml.dom.minidom import Document
from pathlib import Path
from control.data import gettime
from datetime import datetime
from control.log import logger
class Junit:
def __init__(self, pstarttime):
# 创建DOM文档对象
self.doc = Document()
self.pstarttime = pstarttime
# 创建用例套件集
self.testsuites = self.doc.createElement('testsuites')
self.doc.appendChild(self.testsuites)
# 报告数据
self.nowtime = gettime()
# 创建用例套件
self.testsuite = self.doc.createElement('testsuite')
def suite(self, error, failures, tests, skips):
self.testsuite.setAttribute('errors', str(error))
self.testsuite.setAttribute('failures', str(failures))
self.testsuite.setAttribute('hostname', 'seautotest')
self.testsuite.setAttribute('tests', str(tests))
self.testsuite.setAttribute('skipped', str(skips))
self.testsuite.setAttribute('name', 'API')
self.testsuite.setAttribute('timestamp', str(datetime.isoformat(self.pstarttime)))
def case(self, id, title, time):
self.testcase = self.doc.createElement('testcase')
self.testcase.setAttribute('classname', str(id))
self.testcase.setAttribute('name', str(title))
self.case_timer = time
def skip_case(self, message):
skip = self.doc.createElement('skipped')
skip.setAttribute('message', message)
self.testsuite.appendChild(skip)
def settime(self):
# logger.info(self.time)
endtime = datetime.now()
# 单个用例的执行时间
td = endtime - self.case_timer
time = float(
(td.microseconds + (td.seconds + td.days * 24 * 3600) * 10 ** 6)) / 10 ** 6
self.testcase.setAttribute('time', str(time))
self.testcase.setAttribute('priority', 'M')
self.testsuite.appendChild(self.testcase)
def failure(self, message):
failure = self.doc.createElement('failure')
failure.setAttribute('message', str(message))
failure.setAttribute('type', 'Failure')
self.testcase.appendChild(failure)
def write_toxml(self):
td = datetime.now() - self.pstarttime
td_time = float(
(td.microseconds + (td.seconds + td.days * 24 * 3600) * 10 ** 6)) / 10 ** 6
self.testsuite.setAttribute('time', '%s' % td_time)
self.testsuites.appendChild(self.testsuite)
file = Path('junit') / ('API' + '-' + 'ReportJunit@' + self.nowtime + '.xml')
f = open(file, 'w')
self.doc.writexml(f, indent='', newl='', addindent='', encoding='gbk')
f.close()
testcase.py 代码如下
# -*- coding: UTF-8 -*-
"""
1.执行用例
2.分辨是接口自动化还是ui数据等
3.记录测试结果和输出测试报告
"""
from control.log import logger
from pathlib import Path
from control.utils import Excel, element_tojson
from control.data import replace
from control import httpcaps
class TestCase:
def __init__(self, testcase, junit):
# 用例的总长度
self.junit = junit
# 当前执行的用例
self.testcase = testcase
# 元素和链接的书
# 元素和链接的表格
self.file_element = str(Path('element') / ('elements.xlsx'))
# self.file_element = str(Path('element') / ('1911port-elements.xlsx'))
# 读取链接和元素表格全部内容
self.excel_element = Excel('r', self.file_element)
# 获得数据
self.element_data = self.excel_element.red()
# 元素和接口转换为json,切片是为了去除表格的第一行
self.elements = element_tojson(self.element_data[1:])
# 配置参数可能包含ui的基本信息 是什么浏览器和App的版本信息等
# self.parmars = parmars
# 类型,是接口测试还是ui自动化
# self.genre = self.parmars['genre']
# 处理当前testcase
# 记录执行的步骤结果
# feature定义功能
# 记录多少用例没有通过
self.step_fail = 0
# 记录出错的用例
self.step_error = 0
# 出错用例的功能点
self.errors_detail = ''
# 执行测试用例
def run(self):
steps = []
for index, step in enumerate(self.testcase['steps']):
try:
# 获得当前需要测试的接口内容
url = self.elements['baseurl']['url'] + self.elements[step['element']]['url']
# 当前接口请求的类型
sort = self.elements[step['element']]['type']
# 放入到step里面
step['element'] = url.strip()
# 查看上个测试数据里面有没有这个内容
# 如果里面有#号,则吧测试数据重组
# 将测试数据进行重组,调用自定义函数 计算出结果
if step['data']:
step['data'] = replace(str(step['data']))
result_json = getattr(httpcaps, 'htpp_requests')(step, self.junit, sort)
if result_json['score'] != 'Pass':
self.step_fail += 1
# 执行用例
steps.append(result_json)
except Exception as excepetion:
# 将此用例等于不通过
step['score'] = 'Fail'
step['_resultinfo'] = 'exception:%s' % excepetion
self.step_error += 1
logger.info(step)
self.junit.failure(
'testdot:' + step['testdot'] + ' - ' + 'step:' + step['no'] + ' - ' + 'element:' + step[
'element'] + ' - ' + 'error:%s' % excepetion)
self.errors_detail += step['testdot'] + '--' + '{}'.format(excepetion)
steps.append(step)
logger.error('error:interface and element not found%s' % excepetion)
logger.error('error:%s' % excepetion)
# 参数1:出错的步骤数,参数2:未通过的步骤,参数3:用例总数,参数4:跳过的用例 用例总数-去执行的数
self.junit.suite(self.step_error, self.step_fail, len(self.testcase), '')
self.junit.settime()
# 记录生成的测试结果,生成测试报告excel版本
self.testcase['steps'] = steps
return self.testcase
autotest.py 代码如下
1.记得配置下邮箱账号和密码
2.记得配置下邮箱账号和密码
3.记得配置下邮箱账号和密码
from datetime import datetime
from pathlib import Path
from control.testcase import TestCase
from control.utils import Excel, datatodict, suite_format, mkdir
from control.log import logger
from control.data import testsuite2data
from email.mime.application import MIMEApplication
from pathlib import Path
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from control.junit import Junit
import threading
class Autotest():
def __init__(self, parmars):
self.parmars = parmars
# logger.info(parmars)
# 用例表 强转为str类型 兼容jenkins运行
self.file_testcae = str(Path('testcase') / ('testcase.xlsx'))
# 读取测试用例
self.excel_testcase = Excel('r', self.file_testcae)
# 获得用例的全部内容
self.data = self.excel_testcase.red()
# 转换格式为json
self.data = datatodict(self.data)
# 转换数据格式为测试套件返回的可执行用例json
self.testsuit = suite_format(self.data)
# 用于接受用例的结果
self.result_testuite = []
# 测试报告详细数据
self.report_data = {}
report_file = str(Path('report') / ('api' + '-' + 'report' + '' + '.xlsx'))
self.report_workbook = Excel('w', report_file)
# 生成junit测试报告
self.junit_report = str(Path('junit') / ('api' + '-' + 'junit' + '' + '.xml'))
# 以下为邮件配置
self.report = str(Path('report') / ('api-report.xlsx'))
self.send_user = '1' # 发件人
self.password = '' # 授权码/密码
self.receive_users = '@' # 收件人,可为list
self.subject = 'python自动化测试报告' # 邮件主题
self.email_text = 'hi hello this report ' # 邮件正文
self.server_address = 'smtp.exmail.qq.com' # 服务器地址
self.mail_type = '1' # 邮件类型
# 程序开始时间
self.start_se_time = datetime.now()
self.junit = Junit(self.start_se_time)
# 失败的用例
self.step_fail = 0
# 出错的用例
self.step_error = 0
# 当前时间
self.start = datetime.now()
# 创建文件
files = ('report', 'junit', 'config')
for file in files:
mkdir(file)
txt_path = str(Path('config') / ('txt_final.txt'))
txt = open(txt_path, 'w')
txt.seek(0)
txt.truncate()
txt.close()
def play(self):
# 读取测试套件执行用例
for testcae in self.testsuit:
# 跳过的用例
if testcae['condition'] == 'skip':
for skipcase in testcae['steps']:
logger.info(skipcase)
skipcase['score'] = 'skip'
self.result_testuite.append(testcae)
continue
# 传入当前用例
rcase = TestCase(testcae, self.junit)
# 写入xml测试报告
self.junit.case(testcae['id'], testcae['title'], datetime.now())
# 使用线程增加运行速度
thread = threading.Thread(target=self.result_testuite.append(rcase.run()), name=testcae['title'])
# logger.info(thread.name)
thread.start()
# self.result_testuite.append(rcase.run())
# 收到测试的结果,进行生成测试报告
self.junit.write_toxml()
def crateport(self):
data = testsuite2data(self.result_testuite)
self.report_workbook.write(data, 'repost_data')
# 写一次就关一次
self.report_workbook.close()
# 发送邮箱到测试报告
def sedEmail(self):
# 发送邮件之前获得测试结果
# self.email_text = '用例总数:{},'.format(len(self.result_testuite)) + '成功条数:{}'.format() + '失败条数:{}'.format(3)
# 构造一个邮件体:正文 附件
msg = MIMEMultipart()
msg['Subject'] = self.subject # 主题
msg['From'] = self.send_user # 发件人
msg['To'] = self.receive_users # 收件人
# 构建正文
part_text = MIMEText(self.email_text)
msg.attach(part_text) # 把正文加到邮件体里面去
# 构建邮件附件
# file = file #获取文件路径
part_attach1 = MIMEApplication(open(self.report, 'rb').read()) # 打开附件
part_attach1.add_header('Content-Disposition', 'attachment', filename='1911api-report.xlsx') # 为附件命名
msg.attach(part_attach1) # 添加附件
# 发送邮件 SMTP
smtp = smtplib.SMTP(self.server_address, 25) # 连接服务器,SMTP_SSL是安全传输
# smtp.set_debuglevel(1)
smtp.login(self.send_user, self.password)
smtp.sendmail(self.send_user, self.receive_users, msg.as_string()) # 发送邮件
logger.info('邮件发送成功~~~~~~~~~~~~')
httpstart.py 代码如下
from control.autotest import Autotest
import sys
from datetime import datetime
import os
start_se_time = datetime.now()
# 将工程根目录加入到python搜索路径中
sys.path.append('..')
# 兼容后期格式,是接口自动化还是web自动化app自动化,数据库,小程序 h5等自动化测试,以接口为主
desired_caps = {'genre': 'api'}
autotest = Autotest(desired_caps)
# 执行测试
autotest.play()
# 创建测试报告
autotest.crateport()
# 生成allure测试报告
# 参考资料 生成xml报告形式:https://llg.cubic.org/docs/junit/
os.system('allure serve junit')
# 发送测试报告到邮箱
end_se_time = datetime.now()
print(end_se_time - start_se_time)
####接下来咱们运行httpstart.py文件
####会自动启动allure测试报告,咱们看下~
####这是Excel测试报告
原文链接:https://blog.csdn.net/weixin_45344334/java/article/details/94499604