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

Selenium邮件测试用例编写及邮件发送故障排查求助

解决Selenium WebDriver(Java)邮件发送失败及场景化通知问题

作为Selenium新手碰到邮件发不出去的问题太正常了,咱们一步步来排查问题,同时实现「根据测试场景成功/失败触发邮件通知」的功能。

一、先排查邮件发送失败的核心原因

结合你提供的测试场景截图(登录用户信息、无效用户详情、预订数据)和代码,先检查这几个关键节点:

  • Gmail权限限制:现在Gmail默认禁用了低安全性应用访问,你需要先开启「两步验证」,再创建应用专用密码,替换代码里的"Admin12!@"——直接用原账号密码会被Google拦截。
  • 依赖缺失:确保项目引入了JavaMail相关依赖,Maven项目可以在pom.xml里添加:
<dependency>
    <groupId>javax.mail</groupId>
    <artifactId>javax.mail-api</artifactId>
    <version>1.6.2</version>
</dependency>
<dependency>
    <groupId>com.sun.mail</groupId>
    <artifactId>javax.mail</artifactId>
    <version>1.6.2</version>
</dependency>
  • 文件路径有效性:代码里的filename = "C://Users//aniket//sampleseleniumproject//test-output//emailable-report.html"要确认文件真实存在,路径分隔符用/或\\都可以,但一定要保证文件没被删除或路径写错。
  • 网络/端口拦截:如果是公司网络,465端口可能被防火墙拦截,可以切换到587端口的TLS模式,修改配置:
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.port", "587");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.auth", "true");
// 删掉socketFactory相关配置,TLS模式不需要它

二、实现根据测试结果触发邮件通知

要把邮件发送和测试结果绑定,最优雅的方式是用TestNG监听器,也可以直接在测试用例里判断结果后调用邮件方法,两种方案都给你:

方案1:TestNG监听器推荐

创建一个监听器类,监听测试用例的成功/失败事件,自动触发对应邮件:

import org.testng.ITestListener;
import org.testng.ITestResult;

public class TestResultListener implements ITestListener {
    private final SendEmail emailSender = new SendEmail();

    @Override
    public void onTestSuccess(ITestResult result) {
        // 发送测试成功通知
        emailSender.sendResultEmail(result.getName(), "SUCCESS", "测试用例执行成功");
    }

    @Override
    public void onTestFailure(ITestResult result) {
        // 发送测试失败通知,附带错误信息
        String errorMsg = result.getThrowable().getMessage();
        emailSender.sendResultEmail(result.getName(), "FAILURE", "测试用例执行失败:" + errorMsg);
    }

    // 其他监听器方法可以空实现
}

然后改造你的SendEmail类,新增支持动态传参的邮件方法:

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.util.FileDataSource;
import java.util.Properties;

public class SendEmail {
    private final String fromEmail = "seleniumtest201@gmail.com";
    private final String appPassword = "你的Gmail应用专用密码";
    private final String toEmail = "aniketgupta1993@gmail.com";

    public SendEmail() { }

    // 通用结果通知邮件方法
    public void sendResultEmail(String testCaseName, String status, String content) {
        Properties props = new Properties();
        // 用587端口的TLS配置更稳定
        props.put("mail.smtp.host", "smtp.gmail.com");
        props.put("mail.smtp.port", "587");
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.auth", "true");

        Session session = Session.getInstance(props, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(fromEmail, appPassword);
            }
        });

        try {
            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress(fromEmail));
            message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toEmail));
            message.setSubject(String.format("测试用例[%s]执行结果:%s", testCaseName, status));

            // 构建邮件内容(文本+附件)
            Multipart multipart = new MimeMultipart();

            // 文本内容
            MimeBodyPart textPart = new MimeBodyPart();
            textPart.setText(content + "\n\n详细测试报告见附件");
            multipart.addBodyPart(textPart);

            // 测试报告附件
            String reportPath = "C://Users//aniket//sampleseleniumproject//test-output//emailable-report.html";
            MimeBodyPart attachmentPart = new MimeBodyPart();
            FileDataSource source = new FileDataSource(reportPath);
            attachmentPart.setDataHandler(new DataHandler(source));
            attachmentPart.setFileName("emailable-report.html"); // 重命名附件,避免路径过长
            multipart.addBodyPart(attachmentPart);

            message.setContent(multipart);
            Transport.send(message);
            System.out.println("=====结果通知邮件已发送=====");
        } catch (MessagingException e) {
            e.printStackTrace();
            throw new RuntimeException("邮件发送失败:" + e.getMessage());
        }
    }
}

最后在你的测试类上添加监听器注解:

import org.testng.annotations.Listeners;
import org.testng.annotations.Test;

@Listeners(TestResultListener.class)
public class YourTestClass {
    @Test
    public void testValidLogin() {
        // 你的登录测试逻辑
    }

    @Test
    public void testBookingFlow() {
        // 你的预订测试逻辑
    }
}

方案2:直接在测试用例里判断结果

如果不想用监听器,也可以在测试用例里捕获异常,手动触发邮件:

import org.testng.Assert;
import org.testng.annotations.Test;

@Test
public void testInvalidLogin() {
    try {
        // 无效登录测试逻辑
        Assert.assertFalse(driver.findElement(By.id("error")).isDisplayed());
        // 测试成功时发邮件
        new SendEmail().sendResultEmail("testInvalidLogin", "SUCCESS", "无效登录测试用例执行成功");
    } catch (AssertionError | Exception e) {
        // 测试失败时发邮件
        new SendEmail().sendResultEmail("testInvalidLogin", "FAILURE", "无效登录测试用例执行失败:" + e.getMessage());
        throw e; // 抛出异常让TestNG记录失败状态
    }
}

三、额外优化建议

  • 配置外置化:把邮箱地址、密码、SMTP参数放到mail.properties文件里,避免硬编码,方便后续修改。
  • 添加日志:用SLF4J或Java自带日志替换System.out.println,更便于排查问题。
  • 附件校验:在发送邮件前检查附件文件是否存在,避免因为文件缺失导致邮件发送失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:56:59