前言:由於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位版本后,重新配置環境變量,該問題解決