jenkins+ant+jmeter html報告文件作為附件發送(ant-jmeter支持javamail)


前言:由於ant-jmeter目前的版本不支持javamail,也就是說發送郵件時只能借助jenkins自帶的發送郵件插件來發送報告。

但是jenkins發送郵件支持發送郵件內容(且有價值、有營養的內容也只能是借用jenkins的宏),不允許上傳附件。

總的來說若借助jenkins自帶的郵件插件來發送報告的話,內容空洞、沒價值

jenkins自帶的郵件系統配置內容如下:

 

郵件內容為:

從圖種可以看出,發送一個報告的連接,相對來說不直觀,且如果要保持這個連接一直有效,那必須要做備份處理!!

缺點很多,就不一一列舉~

因此這么多缺點,是必須要做出優化了!!!!!!

再此,對ant-jmeter進行二次開發,讓他支持javamail。

二次開發支持的功能:①支持上傳附件②支持郵件內容是以文件的方式輸出

首先反編譯jmeter自帶的ant-jmeter,之后增加2個類,

一個JavaMail類(方法實現),一個MailTask類(方法執行)。ps:關於javamail網上很多材料,現成的的代碼,稍微坐下修改就可以~

JavaMail類具體實現:

package org.programmerplanet.ant.taskdefs.jmeter;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.text.DecimalFormat;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;

public class JavaMail {
    
    static File mailAttachmentFile;
    
    static public void sendMail(int all, int successnum, int failnum, String htmlstring, String mailSubject, String mailAttachment, String mailAddress) throws MessagingException, UnsupportedEncodingException {  
        String s;
        DecimalFormat df = new DecimalFormat("0.00");
        
        if(all == 0){
            s = "0";
        } else {
            s = df.format((float)successnum/(float)all*100);
        }
        
        Properties props = new Properties();
        // 開啟debug調試
        //props.setProperty("mail.debug", "true");
        // 發送服務器需要身份驗證
        props.setProperty("mail.smtp.auth", "false");
        // 設置郵件服務器主機名(ip或者域名)
        props.setProperty("mail.smtp.host", "10.64.1.85");
        // 發送郵件協議名稱
        props.setProperty("mail.transport.protocol", "smtp");
    
        // 設置環境信息
        Session session = Session.getInstance(props);
    
        // 創建郵件對象
        Message msg = new MimeMessage(session);
        
        // 設置發件人
        msg.setFrom(new InternetAddress("XXX@XXX.com.cn"));
        
        // 設置收件人
        @SuppressWarnings("static-access")
        Address[] addresses = new InternetAddress().parse(mailAddress);
        msg.setRecipients(Message.RecipientType.TO,addresses);
        // 設置主題
        if(mailSubject != null){
            msg.setSubject(mailSubject);
        }else{
            msg.setSubject("接口測試報告");
        }
        
        // 設置郵件內容
        
        BodyPart bp = new MimeBodyPart();
        Multipart mp = new MimeMultipart();  
        bp.setContent("<!DOCTYPE html>"
                + "<html lang=\"en\">"
                + "<head><META http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">"
                + "<meta content=\"shanhe.me\" name=\"Author\">"
                + "<title>JMeter Test Results</title>"
                + "<style type=\"text/css\">"
                + "* { margin: 0; padding: 0 }"
                + "html{ font-size: 12px; margin: auto; }"
                + "body { width: 80%; margin: 0 auto; text-align:center; font-size:62.5%;}"
                + "table { font-size:12px;border-collapse: collapse; table-layout: fixed;word-wrap:break-word;word-break:break-all; }"
                + "th{border:1px solid black;color: #ffffff;font-weight: normal;text-align:center;background:#2674a6;}"
                + "td {border:1px solid black;font-weight:normal;}"
                + "</style></head></head><body>"
                + "<h2>接口測試報告概要(詳細內容見郵件附件)</h2>"
                + "<table width=\"100%\"class=\"details\" align=\"center\">"
            + "<tr style=\"line-height:2em;\" valign=\"middle\">"
            + "<th width=\"50%\">執行總數</th>"
                + "<th>失敗數</th>"
                + "<th>成功率</th>"
            + "</tr>"
            + "<tr style=\"line-height:2em;\" valign=\"middle\">"
            + "<td align=\"center\">"+all+"</td>"
            + "<td align=\"center\">"+failnum+"</td>"
            + "<td align=\"center\">"+s+"%</td>"
            + "</tr>"
            +htmlstring
            + "</table></body></html>", "text/html;charset=utf-8");
        
        mp.addBodyPart(bp);
        
        //附件為空時不發附件
        mailAttachmentFile = new File(System.getProperty("user.dir")+mailAttachment);
        if(mailAttachmentFile.exists()){
            System.out.println("把mailAttachment報告文件作為附件發送");
            bp = new MimeBodyPart();
            FileDataSource fileds = new FileDataSource(System.getProperty("user.dir")+mailAttachment); 
            bp.setDataHandler(new DataHandler(fileds)); 
            bp.setFileName(MimeUtility.encodeText(fileds.getName(),"UTF-8","B"));
            mp.addBodyPart(bp); 
        }else{System.out.println("mailAttachment文件不存在,郵件添加附件失敗,請檢查!");}
        
        msg.setContent(mp);
        msg.saveChanges(); 

        Transport transport = session.getTransport();
        // 連接郵件服務器
        transport.connect();
        // 發送郵件
        Transport.send(msg);
        // 關閉連接
        transport.close();
    } 
    
    //測試
    public static void main(String[] args) throws MessagingException, UnsupportedEncodingException {
        
        String ContentString = "<tr valign=\"middle\" style=\"line-height:2em;\">"
                + "<th>接口</th>"
                    + "<th>執行結果</th>"
                    + "<th>執行時間</th>"
                + "</tr>";
        String ContentString2 = "<tr valign=\"middle\" style=\"color:black;background:#D1F3FE;line-height:2em;\">"
            + "<td align=\"left\">"+"/portal/home/pc/search/popup報告測試"+"</td>"
            + "<td align=\"center\">"+"成功"+"</td>"
            + "<td align=\"center\">"+"100ms"+"</td>"
            + "</tr>";

        sendMail(5,5,0,ContentString+ContentString2,"/portal/home/pc/search/popup接口報告", "111","XXX@XXX.com.cn");
    }
}

 

 

MailTask類具體實現:

package org.programmerplanet.ant.taskdefs.jmeter;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.mail.MessagingException;
import java.io.UnsupportedEncodingException;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;

public class MailTask extends Task {
    
    private String mailAddress=null;
    
    private String mailSubject=null;
    
    private String mailAttachment=null;
    
    private String resultLog=null;
    File resultLogFile;
    File htmlFile;
    
    //jtl文件
    public void setResultLog(String resultLog) {
        this.resultLog = resultLog;
    }

    public String getResultLog() {
        return resultLog;
    }
    
    //郵件主題
    public void setMailSubject(String mailSubject) {
        this.mailSubject = mailSubject;
    }

    public String getMailSubject() {
        return mailSubject;
    }
    
    //附件  html報告文件
    public void setMailAttachment(String mailAttachment) {
        this.mailAttachment = mailAttachment;
    }

    public String getMailAttachment() {
        return mailAttachment;
    }
    
    //收件地址,多個逗號(英文)隔開
    public void setMailAddress(String mailAddress) {
        this.mailAddress = mailAddress;
    }

    public String getMailAddress() {
        return mailAddress;
    }
    
    /**
     * @see org.apache.tools.ant.Task#execute()
     * task執行的入口
     */
    public void execute() throws BuildException {
        System.out.println("開始執行發送郵件task");
        resultLogFile = new File(System.getProperty("user.dir")+resultLog);
        if (mailAddress != null && resultLogFile.exists()){
            
            System.out.println("開始解析resultLog");
            
            try {
                analyseResultLog();
            } catch (MessagingException e) {
                e.printStackTrace();
            }
        }else{System.out.println("resultLog不存在,請檢查!");}
    }
    
    /**
     * 計算統計數據
     * @throws MessagingException 
     */
    private void analyseResultLog() throws BuildException, MessagingException {
        
        String htmlString = "<tr valign=\"top\">"
            + "<th width=\"50%\">接口</th>"
                + "<th>執行結果</th>"
                + "<th>執行時間</th>"
            + "</tr>";
        String time;
        String name;
        int count=0;
        String color;
        String color1="#FFFFFF";
        String color2="#E1F3FE";
        int successnum = 0;
        int failnum = 0;
        try {
            
            FileInputStream fis = new FileInputStream(System.getProperty("user.dir")+resultLog);   
            InputStreamReader isr = new InputStreamReader(fis, "UTF-8");   
            BufferedReader br = new BufferedReader(isr);   
            String line = null;
            while ((line = br.readLine()) != null) {
                if (line.indexOf("<httpSample ") !=-1) {
                    count = count +1;
                    color = (count%2<1)?color1:color2;
                    if (line.indexOf(" s=\"true\"") !=-1) {
                        successnum = successnum + 1;
                        time = line.split("\"")[1];
                        name = line.split("\"")[13];
                        htmlString = htmlString +"<tr valign=\"middle\" style=\"background:"+color+";line-height:2em;\">"
                    + "<td align=\"left\">"+name+"</td>"
                    + "<td align=\"center\">成功</td>"
                    + "<td align=\"center\">"+time+"ms</td>"
                    + "</tr>";
                    }else{
                        failnum = failnum + 1;
                        time = line.split("\"")[1];
                        name = line.split("\"")[13];
                        htmlString = htmlString +"<tr valign=\"middle\" style=\"color:red;background:"+color+";line-height:2em;\">"
                    + "<td align=\"left\">"+name+"</td>"
                    + "<td align=\"center\">失敗</td>"
                    + "<td align=\"center\">"+time+"ms</td>"
                    + "</tr>";
                    }
                }
            }
            if(successnum+failnum > 0){
                //有http請求才發郵件
                JavaMail.sendMail(successnum+failnum,  successnum, failnum, htmlString, mailSubject, mailAttachment, mailAddress);
                System.out.println("郵件發送成功");

            }
            br.close();
            isr.close();
            fis.close();
        }catch (IOException e) {
            throw new BuildException("Could not read jmeter resultLog: " + e.getMessage());
        }
    }
    
    //測試
        public static void main(String[] args) throws MessagingException, UnsupportedEncodingException {
            MailTask mt = new MailTask();
            mt.setResultLog("/jtls/AutoInterface測試報告.jtl");
            mt.setMailAttachment("/htmls/AutoInterface測試報告.html");
            mt.setMailAddress("178772275@qq.com");

            mt.execute();
            
        }
    
}

至此代碼已經開發結束,還需要三個步驟。

第一:把反編譯的ant-jmeter  jar包經過二次開發重新編譯打包成jar文件。

具體如何反編譯修改后再重新編譯打包操作略~

新編譯的ant-jmeter進行覆蓋

ps:依賴jar包有ant.jar,activation.jar,mail.jar

 

第二:在bulid.xml文件增加javamail發送

在target 父目錄depends增加mail,如下配置:

<target name="all" depends="run,report,mail"/>

在target父目錄下增加target標簽,配置郵件地址等,如下配置:

<target name="mail">
        <taskdef name="javamail" classname="org.programmerplanet.ant.taskdefs.jmeter.MailTask"/>

        <javamail
            resultLog="/jtls/${ReportName}.jtl"
            mailSubject="${ReportName}"
            mailAttachment="/htmls/${ReportName}.html"
            mailAddress="XXX@XXX.com.cn">
        </javamail>
        <echo>發送報告郵件 at ${report.datestamp}</echo>
    </target>

 

 第三:刪除jenkins配置的郵件通知,否則會發送2份郵件!!!

最后展示下優化結果:

 

希望閱讀此文章的上神,若有好的建議,可以保持溝通~

ps:jenkins+ant+jmeter+DB如何配置如何搭建以及邏輯校驗和關鍵字封裝,之前已經寫過這方面的內容~

本人就對jenkins如何配置再進行下說明,比較邏輯教研和關鍵字封裝涉及到代碼了~而且在我的博客中不斷提及過!

 

為什么介紹下jenkins如何配置,因為本身個人好久沒配置過了,且我博客上沒有關於jenkins配置的文檔,

現在重新配置都有些生疏了~因此希望輸出文檔鞏固下~

首先:tomcat+jenkins基礎搭建就不說了~就直接從jenkins配置說起!!!

首先根據自己項目需要下載jenkins組件,如:
Ant Plugin:用來執行Ant

HTML Publisher plugin:html報告展示

Email Extension Plugin:發郵件

Subversion Plug-in 從SVN上拉去jmx文件

下載完插件后配置jenkins!~

步驟1:系統管理方面的配置

1. 系統管理(manage jenkins) ---》進入系統配置(configure system)---》基本信息

 

 2. 系統管理(manage jenkins) ---》進入系統配置(configure system)---》jenkins location

 

 3. 系統管理(manage jenkins) ---》進入系統配置(configure system)---》Extended E-mail Notification

 

 步驟2:job方面的配置

1.新建一個job(建議自由風格的~)

2.構建觸發器(Build Triggers)

ps:說下源碼管理(Source Code Management)由於我本地搭建自己測試用的就沒用SVN,若是放在公共的環境下,建議用SVN這樣大家提交jmx文件也不會出現沖突的問題!!!

3.增加構建步驟(Build)

ps:構建步驟Invoke Ant 這項可有可無,因為可以直接在Execute Windows batch command里控制

 

 4.增加后置步驟(Post-build Actions)

OK配置結束~

 

補充!!!

部署遇見的難題!!!!

win7 64位機子上若用JDK64版本,在本地dos下ant直接執行沒有錯誤,但通過jenkins點擊構建會報錯,錯誤信息如下:

網上上神們給出的解決方案

https://hub.jmonkeyengine.org/t/solved-java-se-platform-binary-has-stopped-working-on-win-7-x64-when-running-tests/19369

重點如下面上神回答,需要一個jdk 32位的版本

抱着調試的心態,jdk換成32位版本后,重新配置環境變量,該問題解決


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM