前期的工作,做的已經差不多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='\\t', newl='\\n', addindent='\\t', 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
閱讀更多 任性的90後boy 的文章