https://blog.csdn.net/qq744746842/article/details/51497506

其实大多数的时候我们的测试报告的发送可能都是结合Jenkins发送的,所以这方面更多的都是依赖于它,可是如果有的时候我们不需要Jenkins的时候,我们应该如何去处理这部分的内容呢

项目情况
由于我们使用的是maven,所以我们主要来看看pom.xml的情况

<plugin>
<groupId>org.apache.maven.plugins</groupId><!--使用该插件设置TESTNG的配置文件位置-->
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>test</goal>
</goals>
</execution>
</executions>
<version>2.19</version>
<configuration>

<properties>
<property>
<name>usedefaultlisteners</name>
<value>false</value>
</property>
<property>
<name>listener</name>
<value>org.uncommons.reportng.HTMLReporter,org.uncommons.reportng.JUnitXMLReporter</value>
</property>
</properties>
<suiteXmlFiles>
<suitXmlFile>testSuits/seewotraining.xml</suitXmlFile>
</suiteXmlFiles>
<reportsDirectory>./target/${timestamp}</reportsDirectory>
<systemPropertyVariables>
<org.uncommons.reportng.escape-output>false</org.uncommons.reportng.escape-output>
</systemPropertyVariables>
</configuration>
</plugin>
maven-surefire-plugin 这个插件主要是用于testng的。我们通过该插件,在对应的目录下./target/${timestamp}生成我们的测试报告目录。我们可以看到这个目录的结构。

这里实际上就是reportng的测试报告的生成路径。但是我们想要通过邮件发送会很难,因为html的内容需要加在额外的css,以及js文件。而邮件实际上是不支持外部的css以及js文件的。

html的生成
所以就需要我们自己想办法来,既然这样子那我们就自己写一个html就可以了。那么我们要怎么才能够知道测试结果的情况呢,我们可以从这个文件里面获取到TEST-TestSuit.xml 我们可以看看这个xml的内容

<?xml version="1.0" encoding="UTF-8"?>
<testsuite xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://maven.apache.org/surefire/maven-surefire-plugin/xsd/surefire-test-report.xsd" name="TestSuite" time="78.567" tests="2" errors="0" skipped="0" failures="2">
<properties>
<property name="java.runtime.name" value="Java(TM) SE Runtime Environment"/>
<property name="sun.boot.library.path" value="C:\Program Files\Java\jdk1.8.0_11\jre\bin"/>
<property name="java.vm.version" value="25.11-b03"/>
<property name="java.vm.vendor" value="Oracle Corporation"/>
<property name="maven.multiModuleProjectDirectory" value="E:\eclipseProject\SeewoTraining"/>
<property name="java.vendor.url" value="http://java.oracle.com/"/>
<property name="sun.cpu.isalist" value="amd64"/>
</properties>
<testcase name="login" classname="com.seewo.training.TestSeewoTraining" time="60.103">
<failure message="Timed out after 30 seconds waiting for visibility of Proxy element for: DefaultElementLocator &apos;By.xpath: //*[@id=&apos;username&apos;]&apos; Build info: version: &apos;2.53.0&apos;, revision: &apos;35ae25b1534ae328c771e0856c93e187490ca824&apos;, time: &apos;2016-03-15 10:43:46&apos; System info: host: &apos;cvtpc-PC&apos;, ip: &apos;127.0.0.1&apos;, os.name: &apos;Windows 7&apos;, os.arch: &apos;amd64&apos;, os.version: &apos;6.1&apos;, java.version: &apos;1.8.0_11&apos; Driver info: org.openqa.selenium.chrome.ChromeDriver Capabilities [{applicationCacheEnabled=false, rotatable=false, mobileEmulationEnabled=false, chrome={chromedriverVersion=2.21.371459 (36d3d07f660ff2bc1bf28a75d1cdabed0983e7c4), userDataDir=C:\Users\cvtpc\AppData\Local\Temp\scoped_dir31352_25457}, takesHeapSnapshot=true, databaseEnabled=false, handlesAlerts=true, hasTouchScreen=false, version=47.0.2526.106, platform=XP, browserConnectionEnabled=false, nativeEvents=true, acceptSslCerts=true, locationContextEnabled=true, webStorageEnabled=true, browserName=chrome, takesScreenshot=true, javascriptEnabled=true, cssSelectorsEnabled=true}] Session ID: c0c126ea4d4db0e1c3e2ca8352645830" type="org.openqa.selenium.TimeoutException">org.openqa.selenium.TimeoutException:
</failure>
</testcase>
<testcase name="login2" classname="com.seewo.training.TestSeewoTraining" time="11.999">
<failure type="java.lang.NullPointerException">java.lang.NullPointerException
at com.seewo.training.TestSeewoTraining.login2(TestSeewoTraining.java:25)
</failure>
<system-out><![CDATA[2016-05-23 20:27:45 dev_log : [INFO] login Failure
2016-05-23 20:27:45 dev_log : [INFO] ./screenShots\login-20160523202745.png
2016-05-23 20:27:45 dev_log : [INFO] login2 Start
]]></system-out>
</testcase>
</testsuite>
以上的内容我删除掉了部分property的内容。从这里我们就可以通过<testcase>的标签来识别出是有一条测试用例,并且通过<failure>是否存在来判断这条测试用例是成功还是失败的。

下来看看我们生成html的代码吧。

/**
* 判断字符串中是否包含数字
* @param content 查找的字符串
* @return 是否包含
*/
public static boolean hasDigit(String content) {

boolean flag = false;

Pattern p = Pattern.compile(".*\\d+.*");

Matcher m = p.matcher(content);

if (m.matches())

flag = true;

return flag;

}

/**
* 获取到最新的目录
* @return 返回目录的名称
*/
private static String getLastesFolder() {
File path=new File("./target/");
//列出该目录下所有文件和文件夹
File[] files = path.listFiles();
//按照文件最后修改日期倒序排序
Arrays.sort(files, new Comparator<File>() {
@Override
public int compare(File file1, File file2) {
return (int)(file2.lastModified()-file1.lastModified());
}
});
//取出第一个(即最新修改的)文件,打印文件名
for (File file : files) {
System.out.println(file.getName());
if (hasDigit(file.getName())) {
return file.getName();
}
}
return files[0].getName();
}

/**
* 读取Suite.xml文件
* @return 对应的html内容
*/
public static String readSuitsXml() {
XmlParser xmlParser = new XmlParser("./target/"+getLastesFolder()+"/TEST-TestSuite.xml");
List elements = xmlParser.getElementsByTag(xmlParser.getRootElement(), "testcase");
int testCasePass = 0, testCaseFail = 0, testCaseSkip = 0;
for (Object element1 : elements) {
Element element = (Element) element1;
if (xmlParser.getElementByTag(element, "failure") == null) {
baseHtml += "<li class=\"list-group-item list-group-item-success\"><strong>" + xmlParser.
getElementByAttr(element, "name") + "</strong></li>\n";
testCasePass += 1;
}else {
baseHtml += "<li class=\"list-group-item list-group-item-danger\"><strong>" + xmlParser.
getElementByAttr(element, "name") + "</strong></li>\n";
testCaseFail += 1;
}
}
baseHtml +="</ul>\n" +
"</div>\n" +
"</body>\n" +
"</html>";
baseHtml = baseHtml.replace("SUCCESSCOUNT", String.valueOf(testCasePass));
baseHtml = baseHtml.replace("FAILCOUNT", String.valueOf(testCaseFail));
baseHtml = baseHtml.replace("SKIPCOUNT", String.valueOf(testCaseSkip));
return baseHtml;
}
以上中还少了个base_html的定义,因为那部分比较长,主要是一些css的定义,采用bootstrap中的部分css。

生成html后,实际如果写入到一个html中的话,就可以变成下图这样子了。

邮件的发送
既然邮件不能够依赖jenkins,那肯定得自己去实现这部分的内容了。所以我们还是得依赖一些第三方的jar包。我们在pom.xml配置。

<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.1</version>
</dependency>
下来再来看看具体的发送邮件的代码吧

String to[] = { "xxxx.com" };
// 配置发送邮件的环境属性
final Properties props = new Properties();
/*
* 可用的属性: mail.store.protocol / mail.transport.protocol / mail.host /
* mail.user / mail.from
*/
// 表示SMTP发送邮件,需要进行身份验证
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.host", "smtp.cvte.com");
// 发件人的账号
props.put("mail.user", "xxx@cvte.com");
// 访问SMTP服务时需要提供的密码
props.put("mail.password", "xxxxx");

// 构建授权信息,用于进行SMTP进行身份验证
Authenticator authenticator = new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
// 用户名、密码
String userName = props.getProperty("mail.user");
String password = props.getProperty("mail.password");
return new PasswordAuthentication(userName, password);
}
};
// 使用环境属性和授权信息,创建邮件会话
Session mailSession = Session.getInstance(props, authenticator);
// 创建邮件消息
MimeMessage message = new MimeMessage(mailSession);
// 设置发件人
InternetAddress form = new InternetAddress(props.getProperty("mail.user"));
message.setFrom(form);

// 设置收件人
String toList = "xxxx";
InternetAddress[] iaToList = new InternetAddress().parse(toList); // 设置多个收件人
message.setRecipients(RecipientType.TO, iaToList);

// 设置抄送
// InternetAddress cc = new InternetAddress("wuguohui@cvte.com");
// message.setRecipient(RecipientType.CC, cc);

// 设置密送,其他的收件人不能看到密送的邮件地址
// InternetAddress bcc = new InternetAddress("aaaaa@163.com");
// message.setRecipient(RecipientType.CC, bcc);

// 设置邮件标题
message.setSubject("Web Auto Test Mail");

message.setContent(GenerateHtml.readSuitsXml(), "text/html;charset=UTF-8");

// 发送邮件
Transport.send(message);
System.out.println("成功发送邮件");
这里就是发送的邮件的方法了,可是又来问题了,我们需要在什么时候调用这个发送邮件的方法呢。一开始的想法是在aftersuite方法后调用。结果发现问题来了,我们在aftersuite的时候,测试报告实际上还没有生成,所以我们根本就拿不到数据,那还有其他办法吗。答案当然是有的啦。

exec-maven-plugin
这个插件就能够帮我们解决问题了。这个插件的作用就是调动某个java文件的main方法。所以我们只要在前面的pom.xml之后再配置。

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1.1</version>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<includePluginDependencies>true</includePluginDependencies>
<mainClass>com.seewo.training.utils.SendMail</mainClass>
<arguments>
<argument>11</argument>
<argument>22</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
指明我们运行的阶段以及运行的java类就可以了。但是这里有两点需要注意

java类必须在目录 main/java下才行。不能够在test目录下。
如果testng的配置中没有增加<testFailureIgnore>true</testFailureIgnore>这句的话,一旦有测试用例执行失败了发送邮件的java类也不会被执行的。
以上两点是需要注意的地方了。
---------------------
作者:saii
来源:CSDN
原文:https://blog.csdn.net/qq744746842/article/details/51497506
版权声明:本文为博主原创文章,转载请附上博文链接!

testng + reportng 测试结果邮件发送的更多相关文章

  1. Python+request+ smtplib 测试结果html报告邮件发送(下)《六》

    目录结构如下: 1.cfg.ini的配置信息写法如下: [email] ;--------------------------使用腾讯企业邮箱作为发件人的操作如下------------------- ...

  2. python学习笔记(SMTP邮件发送:带附件)

    博主有段时间没有更新博客了 先整理一个之前整理过的SMTP邮件发送,这次是带附件的功能 #!/usr/bin/env python # -*- coding: utf_8 -*- from email ...

  3. Spring 邮件发送

      前言:以前都是直接用Java自带的邮件工具发送邮件,现在Spring帮我们做了封装,提供了更好用更简单的发送邮件工具JavaMailSender 关于邮件服务器的设置就不在这里说了,直接去QQ邮箱 ...

  4. python---网络之邮件发送

    在发送邮件之前需要先设置邮件开启了SMTP等功能,对于163还需要获取授权码 这里设置保存修改 这里获取授权码 完整封装发送邮件类 import smtplib from email.mime.tex ...

  5. shell邮件发送功能实现

    本文中以163邮箱为例,测试shell邮件发送功能.常见的工具有:mailx.sendmail.mutt等. 1.设置邮件客户端 (1)启用pop3.smtp服务,以支持第三方客户端支持 (2)设置授 ...

  6. python学习笔记(SMTP邮件发送)

    想着给框架添加邮件发送功能.所以整理下python下邮件发送功能 首先python是支持邮件的发送.内置smtp库.支持发送纯文本.HTML及添加附件的邮件 之后是邮箱.像163.qq.新浪等邮箱默认 ...

  7. c# stmp邮件发送

    最近用到了邮件发送功能,因为stmp设置.参数传递错误等一些问题走了弯路,虽然代码很简单,这里还是记录一下,方便下次查阅. 用个人163邮箱测试的邮件发送 class Program { static ...

  8. sql 邮件发送测试情况

    sql 邮件发送测试情况 select * from msdb.dbo.sysmail_allitems select * from msdb.dbo.sysmail_event_log

  9. jmeter SMTP Sampler取样器发送测试结果邮件

    原理: 先用结果类监听器(用表格察看结果.聚合报告)将测试结果以csv文件保存到本地. 然后再用SMTP Sampler取样器把本地的测试结果文件发送到指定邮箱 具体步骤如下: 1.下载javamai ...

随机推荐

  1. Codeforces Gym100543B 计算几何 凸包 线段树 二分/三分 卡常

    原文链接https://www.cnblogs.com/zhouzhendong/p/CF-Gym100543B.html 题目传送门 - CF-Gym100543B 题意 给定一个折线图,对于每一条 ...

  2. {}动态规划}记忆化dp

    先搞个模板 #include<stdio.h> #include<string.h> using namespace std; typedef long long ll; ]; ...

  3. Java大数相加-hdu1047

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1047 题目描述: 题意有点绕,但是仔细的读了后就发现是处理大数相加的问题.注意:输入数据有多组,每组输 ...

  4. MLR:利用多元线性回归法,从大量数据中提取五个因变量来预测一个自变量—Jason niu

    from numpy import genfromtxt from sklearn import linear_model datapath=r"Delivery_Dummy.csv&quo ...

  5. Sublime text 3搭建Python开发环境及常用插件安装

    参考  https://www.cnblogs.com/honkly/p/6599642.html 一.环境准备 1.官方网站地址 2.Windows 10 3.Sublime Text 3 + 官网 ...

  6. Team Queue POJ - 2259 (队列)

    Queues and Priority Queues are data structures which are known to most computer scientists. The Team ...

  7. HDU 5493 Queue 【线段树】

    <题目链接> 题目大意:给你n个人的身高和他前面或者后面身高大于他的人的个数,求一个字典序最小的满足此条件的序列,如果不存在输出“impossible”. 解题分析: 因为要保证字典序最小 ...

  8. 简单封装kafka相关的api

    一.针对于kafka版本 <dependency> <groupId>org.apache.kafka</groupId> <artifactId>ka ...

  9. Codeforces.1110F.Nearest Leaf(线段树)

    题目链接 \(dls\)讲过这道题,所以这不是线段树裸题吗,这场没打气气气气气=-= 现在是写着玩=v= \(Description\) 给定一棵\(n\)个点的树.\(q\)次询问,每次询问给定\( ...

  10. Units of CSS

    地址:https://www.w3schools.com/css/css_units.asp https://www.cnblogs.com/xiaohuochai/p/5485683.html em ...