28. 自动化测试开发框架拓展之邮件模块开发

Python自动化邮件发送类深度解析

一、类结构设计与初始化方法

1.1 类定义与参数说明

class Email:
    def __init__(self,
                 sender: str,          # 发件人邮箱(需开通SMTP服务)
                 receiver: [str, list], # 收件人(支持单个或多个)
                 title: str,           # 邮件主题
                 server: str,          # SMTP服务器地址
                 auth_code: str,       # 邮箱授权码(非登录密码)
                 message: str = None,  # 邮件正文
                 attachment_file: [str, list] = None):  # 附件路径
参数验证逻辑表
参数类型必需性示例值
senderstr“user@qq.com”
receiverstr/list[“user1@qq.com”, …]
auth_codestr“xwjfghxcz…”
serverstr“smtp.qq.com”

二、核心方法实现解析

2.1 邮件发送主流程

def send(self):
    # 构建邮件头
    self.msg['Subject'] = self.title  # 📩 主题编码
    self.msg['From'] = self.sender    # 📧 发件人标识
    self.msg['To'] = ', '.join(self.receiver) if isinstance(self.receiver, list) else self.receiver
    
    # 添加正文(支持HTML)
    if self.message:
        self.msg.attach(MIMEText(self.message, 'html' if '<html>' in self.message else 'plain'))
    
    # 处理附件
    if self.attachment_file: ...  # 见2.2节
    
    # SMTP协议交互
    smtp_server = SMTP(self.server)     # 🔌 建立连接
    smtp_server.login(self.sender, self.auth_code)  # 🔑 认证
    smtp_server.sendmail(...)          # 🚀 发送邮件
    smtp_server.quit()                 # 🛑 关闭连接

2.2 附件处理机制

def _attach_file(self, file_path):
    if not exists(file_path):  # 🛑 文件存在性检查
        raise FileNotFoundError(...)
    
    # 读取文件内容(⚠️ 当前仅支持文本文件)
    with open(file_path, 'r', encoding='utf-8') as f:
        att = MIMEText(f.read(), 'plain', 'utf-8')
    
    # 设置MIME头
    att['Content-Type'] = 'application/octet-stream'  # 📁 二进制流类型
    file_name = re.split(r'[\\|/]', file_path)[-1]    # 🗂 提取文件名
    att['Content-Disposition'] = f'attachment; filename="{file_name}"'  # 💾 下载标识
    self.msg.attach(att)
支持的文件类型
文件类型处理方式限制条件
.txt/.log直接读取需UTF-8编码
.csv/.json同文本文件内容需为文本格式
二进制文件当前不支持会引发解码错误

三、完整使用示例

3.1 测试报告发送场景

# 实例化邮件对象
report_email = Email(
    sender='tester@qq.com',
    receiver=['manager@qq.com', 'dev_team@qq.com'],
    title='[自动化测试报告] 2024-01-01',
    server='smtp.qq.com',
    auth_code='xwjfghxcz...',  # 实际使用环境变量存储
    message='''
    <html>
      <body>
        <h2>测试执行概要</h2>
        <p>成功率:<span style="color:green">95%</span></p>
        <p>详细报告请查看附件</p>
      </body>
    </html>
    ''',
    attachment_file=[
        r'E:\reports\test_result_20240101.html',
        r'E:\logs\execution.log'
    ]
)

# 执行发送
try:
    report_email.send()
    print("✅ 测试报告邮件发送成功")
except Exception as e:
    print(f"❌ 邮件发送失败: {str(e)}")

3.2 实际输出效果

✅ 测试报告邮件发送成功
收件箱显示效果
发件人: tester@qq.com
主题: [自动化测试报告] 2024-01-01
正文: 
  测试执行概要
  成功率:95%
  详细报告请查看附件
附件: 
  test_result_20240101.html (1.2MB)
  execution.log (350KB)

四、代码优化建议

4.1 现存问题清单

问题描述风险等级改进方案
附件仅支持文本文件添加二进制文件处理逻辑
未实现SSL加密传输使用SMTP_SSL类替代SMTP
缺乏重试机制添加失败重试逻辑(最多3次)
收件人列表处理不完善统一转换为列表格式处理

4.2 增强型附件处理

# 支持二进制文件附件
from email.mime.application import MIMEApplication

def _attach_file(self, file_path):
    with open(file_path, 'rb') as f:  # 二进制读取
        att = MIMEApplication(f.read())
    att.add_header('Content-Disposition', 'attachment', 
                   filename=('utf-8', '', file_name))  # 处理中文文件名

4.3 企业级最佳实践

某大厂邮件服务规范要求

  1. 敏感信息(授权码)必须通过环境变量传递
  2. 所有邮件必须包含退订链接(法律合规)
  3. 附件大小超过10MB需使用云存储链接替代
  4. 必须记录邮件发送日志(含时间戳和收件人哈希值)
  5. 实施速率限制(每分钟最多发送10封)
# 安全增强示例
import os
from hashlib import md5

auth_code = os.getenv('SMTP_AUTH_CODE')  # 从环境变量读取

# 记录脱敏日志
def send(self):
    ...
    log_msg = f"[{datetime.now()}] Sent to {md5(receiver.encode()).hexdigest()}"
    logging.info(log_msg)

五、完整代码

# 发件人
# 收件人1,收件人2,...
# 发件人登录邮箱
# 编写主题
# 编写正文
# 添加附件
# 发送邮件

from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from os.path import exists
import re
from smtplib import SMTP


class Email:

    def __init__(self,
                 sender: str,
                 receiver: [str, list],
                 title: str,
                 server: str,
                 auth_code: str,
                 message: str = None,
                 attachment_file: [str, list] = None):
        self.sender = sender
        self.receiver = receiver
        self.title = title
        self.message = message
        self.attachment_file = attachment_file
        self.server = server
        self.auth_code = auth_code

        self.msg = MIMEMultipart('related')

    def send(self):
        self.msg['Subject'] = self.title
        self.msg['From'] = self.sender
        self.msg['To'] = self.receiver

        if self.message:
            self.msg.attach(MIMEText(self.message))

        if self.attachment_file:
            if isinstance(self.attachment_file, str):
                self._attach_file(self.attachment_file)
            if isinstance(self.attachment_file, list):
                for _path in self.attachment_file:
                    self._attach_file(_path)

        smtp_server = SMTP(self.server)
        smtp_server.login(self.sender, self.auth_code)
        smtp_server.sendmail(self.sender, self.receiver, self.msg.as_string())
        smtp_server.quit()


    def _attach_file(self, file_path):
        if not exists(file_path):
            raise FileNotFoundError(f'{file_path}:附件文件不存在或者附件文件路径')
        with open(file_path, 'r', encoding='utf-8') as f:
            att = MIMEText(f.read(), 'plain', 'utf-8')
        att['Content-Type'] = 'application/octet-stream'
        file_name = re.split(r'[\\|/]', file_path)[-1]
        att['Content-Disposition'] = f'attachment; filename="{file_name}"'
        self.msg.attach(att)


email = Email(sender='xxx@qq.com',
              receiver='xxx@qq.com',
              title='title',
              server='smtp.qq.com',
              auth_code='xxxxxx',
              message='xxxxx',
              attachment_file='E:\\Py3Sel3Ifram\\report.html'
              )

「小贴士」:点击头像→【关注】按钮,获取更多软件测试的晋升认知不迷路! 🚀

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值