You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Robot Framework测试失败时自动发送指定格式告警邮件

Robot Framework 测试用例失败自动告警邮件实现方案

方案选型

  • 基于Robot Framework原生监听器接口实现,无业务侵入,全局自动生效,无需在单个用例中添加冗余通知逻辑
  • 邮件发送能力基于Python标准库smtplib+email实现,无需额外安装第三方依赖,跨环境兼容性强
  • 支持自定义邮件格式、告警优先级判定规则、收件人分组配置,可直接落地使用

具体实现步骤

第一步:编写自定义失败通知监听器

新建文件FailureEmailListener.py,写入如下代码,可根据自身实际情况修改初始化配置里的SMTP参数、优先级判定关键词:

import smtplib
from email.mime.text import MIMEText
from email.header import Header
from robot.api import logger

class FailureEmailListener:
    ROBOT_LISTENER_API_VERSION = 3
    def __init__(self, smtp_server='smtp.xxx.com', smtp_port=465, sender='test_notify@xxx.com', 
                 sender_pwd='your_smtp_auth_code', receivers=None, p0_keywords=None):
        # SMTP服务配置
        self.smtp_server = smtp_server
        self.smtp_port = smtp_port
        self.sender = sender
        self.sender_pwd = sender_pwd
        # 默认收件人列表,多收件人用逗号分隔
        self.receivers = receivers.split(',') if receivers else ['test_group@xxx.com']
        # P0级告警关键词,用例名称/路径命中这些关键词时,失败直接触发最高优先级告警
        self.p0_keywords = p0_keywords.split(',') if p0_keywords else ['登录', '支付', '下单', '核心主流程']
        self.failed_cases = []

    def end_test(self, data, result):
        # 仅统计执行失败的用例
        if not result.passed:
            # 自动判定告警优先级
            priority = 'P2'
            case_tags = [str(tag).lower() for tag in data.tags]
            case_full_path = f"{data.parent.name}{data.name}".lower()
            if 'p0' in case_tags or any(k.lower() in case_full_path for k in self.p0_keywords):
                priority = 'P0'
            elif 'p1' in case_tags:
                priority = 'P1'
            # 收集失败用例核心信息
            self.failed_cases.append({
                'suite_name': data.parent.name,
                'case_name': data.name,
                'fail_reason': result.message.replace('\n', '<br/>'),
                'priority': priority,
                'duration': round(result.elapsed_time / 1000, 2)
            })

    def close(self):
        # 所有用例执行完成后,存在失败用例则触发邮件通知
        if not self.failed_cases:
            return
        # 组装HTML格式邮件内容,可按需调整格式
        mail_content = """
        <h3>自动化测试执行失败告警</h3>
        <p>本次执行共统计到 <b>{}</b> 个失败用例,详情如下:</p>
        <table border="1" cellpadding="6" cellspacing="0" style="border-collapse: collapse;">
            <tr style="background:#f0f0f0;">
                <th>告警优先级</th>
                <th>所属测试套件</th>
                <th>失败用例名称</th>
                <th>失败原因</th>
                <th>执行时长(秒)</th>
            </tr>
        """.format(len(self.failed_cases))
        # P0级失败用例标红高亮
        for case in self.failed_cases:
            if case['priority'] == 'P0':
                mail_content += f"""
                <tr style="color:#d90000;font-weight:600;">
                    <td>{case['priority']}</td>
                    <td>{case['suite_name']}</td>
                    <td>{case['case_name']}</td>
                    <td>{case['fail_reason']}</td>
                    <td>{case['duration']}</td>
                </tr>
                """
            else:
                mail_content += f"""
                <tr>
                    <td>{case['priority']}</td>
                    <td>{case['suite_name']}</td>
                    <td>{case['case_name']}</td>
                    <td>{case['fail_reason']}</td>
                    <td>{case['duration']}</td>
                </tr>
                """
        mail_content += "</table><p>请相关负责人及时排查问题。</p>"
        # 构造邮件对象
        message = MIMEText(mail_content, 'html', 'utf-8')
        message['From'] = Header("自动化测试告警平台", 'utf-8')
        message['To'] = Header("测试相关人员", 'utf-8')
        top_priority = max([c['priority'] for c in self.failed_cases])
        message['Subject'] = Header(f"【自动化告警】{len(self.failed_cases)}个用例执行失败,最高优先级{top_priority}", 'utf-8')
        # 执行发送
        try:
            smtp_obj = smtplib.SMTP_SSL(self.smtp_server, self.smtp_port)
            smtp_obj.login(self.sender, self.sender_pwd)
            smtp_obj.sendmail(self.sender, self.receivers, message.as_string())
            logger.console("失败告警邮件发送完成")
        except Exception as e:
            logger.error(f"告警邮件发送失败,错误信息:{str(e)}")

第二步:加载监听器生效

执行测试时通过--listener参数加载监听器即可,支持两种常用场景:

  • 命令行执行:直接在执行命令中追加参数,示例:robot --listener FailureEmailListener.py ./test_cases/
  • RIDE图形界面执行:在运行配置的Arguments输入框中填入--listener FailureEmailListener.py即可
  • 自定义参数传入:如果需要临时修改SMTP配置、收件人列表,直接在监听器名称后按构造函数顺序传参即可,示例:
    robot --listener FailureEmailListener.py:smtp.qq.com:465:notify@qq.com:xxxxxx:tester1@xx.com,tester2@xx.com:登录,支付 ./test_cases/

注意:使用QQ邮箱、163邮箱等公共邮箱服务时,sender_pwd字段需要填写邮箱生成的SMTP服务授权码,不能直接填写邮箱登录密码,否则会出现鉴权失败。

第三步:按需调整自定义规则

  • 优先级规则:可直接给测试用例打P0/P1标签,脚本会自动识别标签判定优先级;也可以修改脚本中p0_keywords的配置,匹配核心业务用例
  • 邮件格式:直接修改mail_content中的HTML代码,可新增执行环境、测试报告地址、失败截图链接等自定义字段
  • 发送时机:默认逻辑是所有用例执行完成后汇总发一封告警,避免频繁发信打扰;如果需要单个用例失败立刻发信,把close方法中的邮件发送逻辑移到end_test方法中即可

可选增强能力

  • 失败附件自动添加:如果用例失败时自动保存了截图、日志,可在邮件构造逻辑中添加附件读取代码,把相关文件随邮件一起发送
  • 告警频率限制:可增加本地缓存逻辑,同一个用例连续失败3次以上再触发P0级告警,过滤偶现波动问题
  • 收件人路由:可配置规则,P0级告警额外抄送给项目负责人、开发负责人,P1/P2级告警仅发送给测试组成员

内容的提问来源于stack exchange,提问作者Sudheer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 20:57:22