如何用Nodemailer按测试用例结果发不同主题邮件及解决邮件未触发问题
解决方案:Protractor测试完成后通过Nodemailer发送结果邮件
看起来你遇到的核心问题是测试钩子的使用时机错误,加上缺少Nodemailer的实际发送逻辑,导致带if-else判断的代码无法触发邮件发送。我来帮你拆解问题并给出可行的修复方案:
问题诊断
specDone钩子的误用:specDone是单个测试用例(spec)执行完成后就触发的钩子,你的代码在每个用例结束时都创建了mailOptions,但既没有初始化Nodemailer的发送器(transporter),也没有调用sendMail方法发送邮件——这就是为什么移除if-else后能发送的原因:你大概率在移除分支后补充了发送逻辑,但在分支代码里漏掉了。- 未全局统计测试结果:在
specDone里直接判断单个用例的结果并准备邮件,会导致每个用例结束都尝试发送一次(如果有发送逻辑的话),而不是在所有测试完成后发送最终报告。
修复步骤
1. 全局维护测试失败状态
在测试代码的最外层定义一个变量,用来记录是否有测试用例失败:
let hasFailedTests = false;
2. 在specDone中更新失败状态
不要在specDone里直接准备邮件,只更新全局失败标记:
this.specDone = function(result) { // 只要有一个用例失败,就将全局标记设为true if (result.failedExpectations.length > 0) { hasFailedTests = true; } };
3. 在afterAll钩子中统一发送邮件
afterAll是所有测试用例执行完成后才触发的钩子,在这里根据全局状态准备邮件并调用Nodemailer发送:
const nodemailer = require('nodemailer'); // 初始化Nodemailer发送器(根据你的邮箱服务商配置,这里以Gmail为例) const transporter = nodemailer.createTransport({ service: 'Gmail', auth: { user: 'xxx@xx.com', // 你的发件邮箱 pass: 'your-app-specific-password' // 邮箱密码或应用专用密码 } }); this.afterAll(function(done) { let mailOptions; // 根据全局失败状态设置邮件内容 if (hasFailedTests) { mailOptions = { from: '"Mathur, Shruti" <xxx@xx.com>', to: 'xxx@xx.com', subject: 'Liability Management automation Report-Test Suite Failure', text: 'Test case completed', html: 'Hi Team,<br><br> Test Automation for <b>Liability Management UI</b> through Protractor has been completed. There is <b>failure</b> for one or more test suites.<br>Please find the attached report for reference.', attachments: [{ path: 'C:/Shruti/Protractor_Autodistribution/my-app/Test/report.zip' }] }; } else { mailOptions = { from: '"Mathur, Shruti" <xxx@xx.com>', to: 'xxx@xx.com', subject: 'Liability Management automation Report-All Test Suite Passed', text: 'Test case completed', html: 'Hi Team,<br><br> Test Automation for <b>Liability Management UI</b> through Protractor has been completed. All Test suites are <b>passed</b> successfully.<br>Please find the attached report for reference.', attachments: [{ path: 'C:/Shruti/Protractor_Autodistribution/my-app/Test/report.zip' }] }; } // 发送邮件并通知Protractor测试结束 transporter.sendMail(mailOptions, function(error, info) { if (error) { console.error('邮件发送失败:', error); } else { console.log('邮件发送成功:', info.response); } done(); // 必须调用done(),否则Protractor会一直等待测试结束 }); });
额外注意事项
- 如果你使用Gmail,需要开启应用专用密码(如果开启了两步验证),或者暂时允许低安全性应用访问(不推荐生产环境)。
- 确保附件的绝对路径是正确的,测试时可以先打印
C:/Shruti/Protractor_Autodistribution/my-app/Test/report.zip确认文件存在。 afterAll中的done()必须调用,否则Protractor会一直挂起,不会退出测试进程。
内容的提问来源于stack exchange,提问作者Shruti
相关产品推荐
相关产品推荐

