TestNG在@AfterSuite中发送可邮件报告时总是发送旧报告如何解决
问题原因
TestNG的内置报告生成逻辑的执行时机,晚于所有@AfterSuite注解标注的方法的执行时间,完整执行顺序如下:
- 所有测试用例执行完成
- 执行所有
@AfterSuite标注的方法 - 生成本次测试的最终报告并写入磁盘
你在@AfterSuite方法中调用邮件发送逻辑时,本次的新报告还未生成,读取到的自然是上一次执行留下的旧报告,添加Thread.sleep没有任何作用——只要当前@AfterSuite方法没执行完,报告生成逻辑就不会触发,休眠再久也等不到新报告生成。
解决方案
提供3种可直接落地的修改方案:
方案1:实现TestNG的IReporter监听器(最推荐)
TestNG的IReporter接口的generateReport方法,会在所有测试执行完成、报告数据准备完毕后触发,是发邮件的最佳时机。
- 新增监听器类:
package testOWC; import org.testng.IReporter; import org.testng.ISuite; import org.testng.xml.XmlSuite; import javax.mail.MessagingException; import java.util.List; public class ReportEmailListener implements IReporter { @Override public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites, String outputDirectory) { try { // 直接调用你的邮件发送逻辑 Email_Invoke.main(null); } catch (MessagingException | InterruptedException e) { e.printStackTrace(); } } }
- 在你的testng.xml配置文件中注册监听器:
<listeners> <listener class-name="testOWC.ReportEmailListener" /> </listeners>
- 删除原来
All_TestCases类中@AfterSuite标注的email方法即可。
方案2:拆分测试执行与邮件发送步骤
不要把邮件发送逻辑耦合在TestNG的测试生命周期中,改为独立的两个执行步骤:
- 先执行TestNG测试任务,等测试进程完全退出
- 再单独运行
Email_Invoke的主方法发送邮件
如果是用Maven/Gradle等构建工具执行测试,可以把邮件发送逻辑绑定到test阶段之后的执行节点;如果是用脚本执行,直接按顺序写两条执行命令即可。
方案3:自定义TestNG启动入口
写一个独立的测试启动类,先跑完所有测试再发邮件:
package testOWC; import org.testng.TestNG; import javax.mail.MessagingException; public class CustomTestRunner { public static void main(String[] args) { TestNG testNG = new TestNG(); // 指定要运行的测试类 testNG.setTestClasses(new Class[]{All_TestCases.class}); // 执行测试,会阻塞到所有测试完成、报告生成完毕 testNG.run(); // 发送邮件 try { Email_Invoke.main(null); } catch (MessagingException | InterruptedException e) { e.printStackTrace(); } } }
后续直接运行这个启动类执行测试即可,同样需要删除原来All_TestCases类中的@AfterSuite email方法。
内容的提问来源于stack exchange,提问作者Arpit Sharma
相关产品推荐
相关产品推荐

