(2023-05-11) 支持测试完成后,通过yagmail发送pytest-html的测试结果邮件
This commit is contained in:
132
case_utils/send_result_handle.py
Normal file
132
case_utils/send_result_handle.py
Normal file
@@ -0,0 +1,132 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# @Time : 2023/5/10 10:43
|
||||
# @Author : chenyinhua
|
||||
# @File : send_result_handle.py
|
||||
# @Software: PyCharm
|
||||
# @Desc:
|
||||
from common_utils.yagmail_handle import YagEmailServe
|
||||
from config.settings import email
|
||||
from config.global_vars import NotificationType
|
||||
from config.settings import SEND_RESULT_TYPE
|
||||
from common_utils.bs4_handle import SoupAPI
|
||||
|
||||
|
||||
def get_test_info_from_html_report(html_report_path):
|
||||
"""
|
||||
从html测试报告中获取测试情况
|
||||
"""
|
||||
bs = SoupAPI(html_report_path)
|
||||
results = {}
|
||||
|
||||
# -------------- 获取测试环境信息 --------------
|
||||
environment_info = bs.get_element_by_id("environment").get_text()
|
||||
new_environment_info = [element for element in environment_info.split("\n") if element != '']
|
||||
for key, value in enumerate(new_environment_info):
|
||||
if value == "Platform":
|
||||
results['platform'] = new_environment_info[key + 1]
|
||||
|
||||
if value == "Python":
|
||||
results['python_version'] = f"Python {new_environment_info[key + 1]}"
|
||||
|
||||
if value == "开始时间":
|
||||
results['start_time'] = new_environment_info[key + 1]
|
||||
|
||||
if value == "项目名称":
|
||||
results['project_name'] = new_environment_info[key + 1]
|
||||
|
||||
if value == "项目环境":
|
||||
results['project_env'] = new_environment_info[key + 1]
|
||||
|
||||
# -------------- 获取测试人员,所属部门,测试用例总数,运行时长 --------------
|
||||
p_elements = bs.get_elements_by_tag("p")
|
||||
for p_element in p_elements:
|
||||
res = p_element.get_text()
|
||||
if "测试人员:" in res:
|
||||
results['tester'] = res.replace("测试人员:", "")
|
||||
if "所属部门: " in res:
|
||||
results['dept'] = res.replace("所属部门: ", "")
|
||||
if "tests ran" in res:
|
||||
new_list = res.split(" ")
|
||||
results['runs_time'] = f"{new_list[4]} 秒"
|
||||
|
||||
# -------------- 获取具体结果 --------------
|
||||
# 通过的用例个数
|
||||
passed = bs.select_element('span.passed')[0]
|
||||
results["passed"] = int(passed.get_text().split(" ")[0])
|
||||
# 跳过的用例个数
|
||||
skipped = bs.select_element('span.skipped')[0]
|
||||
results["skipped"] = int(skipped.get_text().split(" ")[0])
|
||||
# 失败的用例个数
|
||||
failed = bs.select_element('span.failed')[0]
|
||||
results["failed"] = int(failed.get_text().split(" ")[0])
|
||||
# 错误的用例个数
|
||||
error = bs.select_element('span.error')[0]
|
||||
results["error"] = int(error.get_text().split(" ")[0])
|
||||
# 预期失败的用例个数
|
||||
xfailed = bs.select_element('span.xfailed')[0]
|
||||
results["xfailed"] = int(xfailed.get_text().split(" ")[0])
|
||||
# 意外通过的用例个数
|
||||
xpassed = bs.select_element('span.xpassed')[0]
|
||||
results["xpassed"] = int(xpassed.get_text().split(" ")[0])
|
||||
# 重跑的用例个数
|
||||
rerun = bs.select_element('span.rerun')[0]
|
||||
results["rerun"] = int(rerun.get_text().split(" ")[0])
|
||||
# 用例总数
|
||||
results['total_cases'] = results["passed"] + results["skipped"] + results["failed"] + results["error"] + results[
|
||||
"xfailed"] + results["xpassed"]
|
||||
return results
|
||||
|
||||
|
||||
def send_result(results, attachment_path=None):
|
||||
"""
|
||||
根据用户配置,采取指定方式,发送测试结果
|
||||
"""
|
||||
|
||||
# 默认不发送任何通知
|
||||
if SEND_RESULT_TYPE == NotificationType.DEFAULT.value:
|
||||
pass
|
||||
# 发送邮件通知
|
||||
elif SEND_RESULT_TYPE == NotificationType.EMAIL.value:
|
||||
email_settings = email
|
||||
yag = YagEmailServe(user=email_settings.get("user"), password=email_settings.get("password"),
|
||||
host=email_settings.get("host"))
|
||||
info = {
|
||||
"subject": f"{results.get('project_name', None)} 接口自动化报告_{results.get('start_time', None)}",
|
||||
"contents": f"""
|
||||
各位同事, 大家好:
|
||||
|
||||
自动化用例于{results.get('start_time', None)}开始运行,运行时长:{results.get('runs_time', None)}, 目前已执行完成。
|
||||
-----------------------------------------------------------------------------------------------------------
|
||||
测试人:{results.get('tester', None)} / {results.get('dept', None)}
|
||||
测试平台:{results.get('platform', None)} / {results.get('python_version', None)}
|
||||
测试环境:{results.get('project_env', None)}
|
||||
---------------------------------------------------------------------------------------------------------------
|
||||
执行结果如下:
|
||||
用例运行总数: {results.get("total_cases", None)} 个
|
||||
通过用例个数(passed): {results.get("passed", None)} 个
|
||||
失败用例个数(failed): {results.get("failed", None)} 个
|
||||
异常用例个数(error): {results.get("error", None)} 个
|
||||
跳过用例个数(skipped): {results.get("skipped", None)} 个
|
||||
预期失败用例个数(xfailed): {results.get("xfailed", None)} 个
|
||||
意外通过用例个数(xpassed): {results.get("xpassed", None)} 个
|
||||
失败重试用例个数 * 次数之和(rerun): {results.get("rerun", None)} 个
|
||||
成 功 率: {(results.get("passed") / results.get("total_cases")) * 100} %
|
||||
|
||||
**********************************
|
||||
jenkins地址:https://xxxxxxxxx
|
||||
详细情况可登录jenkins平台查看,非相关负责人员可忽略此消息。谢谢。
|
||||
""",
|
||||
"to": email.get("to"),
|
||||
"attachments": attachment_path
|
||||
|
||||
}
|
||||
yag.send_email(info)
|
||||
# 发送钉钉通知
|
||||
elif SEND_RESULT_TYPE == NotificationType.DING_TALK.value:
|
||||
pass
|
||||
# 发送企业微信通知
|
||||
elif SEND_RESULT_TYPE == NotificationType.WECHAT.value:
|
||||
pass
|
||||
# 全部渠道都发送通知
|
||||
else:
|
||||
pass
|
||||
@@ -19,3 +19,13 @@ class CaseFileType(Enum):
|
||||
YAML = 1
|
||||
EXCEL = 2
|
||||
ALL = 0
|
||||
|
||||
|
||||
class NotificationType(Enum):
|
||||
""" 自动化通知方式 """
|
||||
DEFAULT = 0
|
||||
DING_TALK = 1
|
||||
WECHAT = 2
|
||||
EMAIL = 3
|
||||
ALL = 4
|
||||
|
||||
|
||||
@@ -6,9 +6,13 @@
|
||||
# @Software: PyCharm
|
||||
# @Desc: 项目配置文件
|
||||
|
||||
|
||||
# ------------------------------------ 配置信息 ----------------------------------------------------#
|
||||
# 0代表执行Excel和yaml两种格式的用例, 1 代表 yaml文件,2 用例代表Excel用例
|
||||
CASE_FILE_TYPE = 0
|
||||
|
||||
# 0表示默认不发送任何通知, 1代表钉钉通知,2代表企业微信通知, 3代表邮件通知, 4代表所有途径都发送通知
|
||||
SEND_RESULT_TYPE = 3
|
||||
|
||||
# 测试报告的定制化信息展示
|
||||
REPORT_TITLE = "自动化测试报告"
|
||||
REPORT_NAME = f"apiautotest-report-"
|
||||
@@ -19,7 +23,7 @@ DEPARTMENT = "所属部门: 开源中心"
|
||||
# 指定日志收集级别
|
||||
LOG_LEVEL = "INFO"
|
||||
|
||||
# 测试数据
|
||||
# ------------------------------------ 测试数据 ----------------------------------------------------#
|
||||
test = [
|
||||
{
|
||||
# 示例测试环境及示例测试账号
|
||||
@@ -44,3 +48,13 @@ live = [
|
||||
"project": ""
|
||||
}
|
||||
]
|
||||
|
||||
# ------------------------------------ 邮件配置信息 ----------------------------------------------------#
|
||||
|
||||
# 发送邮件的相关配置信息
|
||||
email = {
|
||||
"user": "******", # 发件人邮箱
|
||||
"password": "******", # 发件人邮箱授权码
|
||||
"host": "smtp.qq.com",
|
||||
"to": ["******", "******"] # 收件人邮箱
|
||||
}
|
||||
|
||||
12
conftest.py
12
conftest.py
@@ -13,6 +13,7 @@ import pytest
|
||||
from py._xmlgen import html # 安装pytest-html,版本最好是2.1.1
|
||||
from time import strftime
|
||||
from config.settings import test, live, REPORT_TITLE, PROJECT_NAME, TESTER, DEPARTMENT
|
||||
from case_utils.send_result_handle import get_test_info_from_html_report, send_result
|
||||
|
||||
|
||||
# ------------------------------------- START: 配置运行环境 ---------------------------------------#
|
||||
@@ -54,6 +55,7 @@ def get_config(request):
|
||||
|
||||
|
||||
# ------------------------------------- END: 配置运行环境 ---------------------------------------#
|
||||
|
||||
# ------------------------------------- START: 报告处理 ---------------------------------------#
|
||||
def pytest_collection_modifyitems(items):
|
||||
"""# 测试用例执行收集完成时,将收集到的item的name和nodeid的中文显示在控制台上"""
|
||||
@@ -71,7 +73,6 @@ def pytest_runtest_makereport(item, call):
|
||||
report = outcome.get_result()
|
||||
# TODO:由于目前无法动态将用例数据中的title写入测试方法中的文档注释,因此该处理方法暂时搁置
|
||||
# 将测试方法的文档注释作为结果表的Description的值,如果文档注释为空,则测试方法名作为结果表的Description的值
|
||||
logger.debug(f"文档注释:{item.function.__doc__}")
|
||||
report.description = str(item.function.__doc__)
|
||||
report.nodeid = report.nodeid.encode("utf-8").decode("unicode_escape")
|
||||
|
||||
@@ -104,6 +105,15 @@ def pytest_sessionfinish(session, exitstatus):
|
||||
session.config._metadata['项目环境'] = GLOBAL_VARS.get("host", "")
|
||||
|
||||
|
||||
@pytest.hookimpl(hookwrapper=True)
|
||||
def pytest_terminal_summary(terminalreporter, exitstatus, config):
|
||||
yield
|
||||
# 获取测试报告路径,并发送测试结果
|
||||
report_path = config.getoption('--html')
|
||||
results = get_test_info_from_html_report(report_path)
|
||||
send_result(results, report_path)
|
||||
|
||||
|
||||
def pytest_html_results_summary(prefix, summary, postfix):
|
||||
"""
|
||||
修改Summary部分的信息
|
||||
|
||||
Reference in New Issue
Block a user