如何在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
相关产品推荐
相关产品推荐

