email_notifier.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import smtplib
  2. from email.mime.text import MIMEText
  3. from email.mime.multipart import MIMEMultipart
  4. from email.mime.application import MIMEApplication
  5. from pathlib import Path
  6. from core.config.config_manager import ConfigManager
  7. from core.utils.logger import Logger
  8. from core.singleton import Singleton
  9. class EmailNotifier(metaclass=Singleton):
  10. def __init__(self):
  11. self.config = ConfigManager()
  12. self.logger = Logger.get_logger()
  13. self.smtp_config = self.config.get('email', {})
  14. def send_email(self, recipients, subject, body, attachments=None):
  15. """发送邮件"""
  16. try:
  17. # 获取SMTP配置
  18. smtp_server = self.smtp_config.get('smtp_server')
  19. smtp_port = self.smtp_config.get('smtp_port', 587)
  20. username = self.smtp_config.get('username')
  21. password = self.smtp_config.get('password')
  22. if not all([smtp_server, username, password]):
  23. self.logger.warning("邮件配置不完整,无法发送邮件")
  24. return False
  25. # 创建邮件
  26. msg = MIMEMultipart()
  27. msg['From'] = username
  28. msg['To'] = ', '.join(recipients)
  29. msg['Subject'] = subject
  30. # 添加正文
  31. msg.attach(MIMEText(body, 'plain', 'utf-8'))
  32. # 添加附件
  33. if attachments:
  34. for attachment_path in attachments:
  35. if isinstance(attachment_path, str):
  36. attachment_path = Path(attachment_path)
  37. if attachment_path.exists():
  38. with open(attachment_path, 'rb') as f:
  39. part = MIMEApplication(f.read(), Name=attachment_path.name)
  40. part['Content-Disposition'] = f'attachment; filename="{attachment_path.name}"'
  41. msg.attach(part)
  42. # 连接SMTP服务器并发送邮件
  43. with smtplib.SMTP(smtp_server, smtp_port) as server:
  44. server.starttls()
  45. server.login(username, password)
  46. server.sendmail(username, recipients, msg.as_string())
  47. self.logger.info(f"邮件已成功发送给: {', '.join(recipients)}")
  48. return True
  49. except Exception as e:
  50. self.logger.error(f"发送邮件失败: {str(e)}")
  51. return False
  52. def send_test_report(self, report_paths, test_results, execution_time):
  53. """发送测试报告邮件"""
  54. # 获取收件人列表
  55. recipients = self.smtp_config.get('recipients', [])
  56. if not recipients:
  57. self.logger.warning("未配置邮件收件人,跳过发送测试报告")
  58. return False
  59. # 准备邮件内容
  60. subject = self.smtp_config.get(
  61. 'email_subject',
  62. '自动化测试报告 - {date}'
  63. ).format(date=datetime.now().strftime('%Y-%m-%d %H:%M'))
  64. # 统计测试结果
  65. total_tests = len(test_results)
  66. passed = sum(1 for r in test_results if r['status'] == 'PASS')
  67. failed = sum(1 for r in test_results if r['status'] == 'FAIL')
  68. error = sum(1 for r in test_results if r['status'] == 'ERROR')
  69. success_rate = (passed / total_tests) * 100 if total_tests > 0 else 0
  70. # 构建邮件正文
  71. body = f"""
  72. 自动化测试执行完成
  73. 执行时间: {execution_time:.2f} 秒
  74. 总测试数: {total_tests}
  75. 通过: {passed}
  76. 失败: {failed}
  77. 错误: {error}
  78. 通过率: {success_rate:.2f}%
  79. 测试环境: {self.config.get('environment', '未知环境')}
  80. 请查看附件中的详细测试报告。
  81. """
  82. # 发送邮件
  83. return self.send_email(recipients, subject, body, report_paths)