zoukankan      html  css  js  c++  java
  • testng + reportng 测试结果邮件发送

    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 FilesJavajdk1.8.0_11jrein"/>
    <property name="java.vm.version" value="25.11-b03"/>
    <property name="java.vm.vendor" value="Oracle Corporation"/>
    <property name="maven.multiModuleProjectDirectory" value="E:eclipseProjectSeewoTraining"/>
    <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;&#10;Build info: version: &apos;2.53.0&apos;, revision: &apos;35ae25b1534ae328c771e0856c93e187490ca824&apos;, time: &apos;2016-03-15 10:43:46&apos;&#10;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;&#10;Driver info: org.openqa.selenium.chrome.ChromeDriver&#10;Capabilities [{applicationCacheEnabled=false, rotatable=false, mobileEmulationEnabled=false, chrome={chromedriverVersion=2.21.371459 (36d3d07f660ff2bc1bf28a75d1cdabed0983e7c4), userDataDir=C:UserscvtpcAppDataLocalTempscoped_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}]&#10;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] ./screenShotslogin-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> ";
    testCasePass += 1;
    }else {
    baseHtml += "<li class="list-group-item list-group-item-danger"><strong>" + xmlParser.
    getElementByAttr(element, "name") + "</strong></li> ";
    testCaseFail += 1;
    }
    }
    baseHtml +="</ul> " +
    "</div> " +
    "</body> " +
    "</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
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    c# 复制整个文件夹的内容,Copy所有文件
    c# 创建文件夹
    c# 访问共享文件
    sublimit 编辑器 设置默认的编码
    WPF xml配置文件里面的大于小于号转义
    c# datatable 分组
    WPF 耗时操作时,加载loging 动画 (BackgroundWorker 使用方法)
    WPF DEV gridcontrol 自定义计算列(TotalSummary)
    postgresql 创建gin索引
    WPF DEV gridcontrol当前项的数据导出为mdb文件
  • 原文地址:https://www.cnblogs.com/ceshi2016/p/10005737.html
Copyright © 2011-2022 走看看