轉:
A. 目標:
實現RobotFramework的腳本定時自動執行,執行完后自動將結果發送到指定郵箱
B. 前提
1、 配置好Robot Framework的環境,腳本可以正常運行
2、 部署好Jenkins的環境,Jenkins的安裝不是本文的重點,不懂的請問度娘(其實很簡單,裝Tomcat,把Jenkins.war包扔到Tomcat的webapp目錄里)
3、 在Jenkins里安裝好以下插件:EmailExtension Plugin、Zentimestamp plugin、Robot Framework plugin
C. 安裝相關插件
Jenkins安裝Email Extension Plugin、Zentimestampplugin、Robot Framework plugin插件
在線直接安裝插件:
在“可選插件”搜索Email Extension Plugin、Zentimestamp plugin、Robot Frameworkplugin插件名,選擇之后,點擊直接安裝
注:建議用在線直接安裝,因為插件與插件中存在相互依賴性,手動處理會很麻煩,但是直接安裝,系統可以直接處理依賴關系
離線安裝插件:(不建議使用)
1) 下載插件(由於無法在線安裝,所以只能走離線安裝)
首先到網址http://updates.jenkins-ci.org/download/plugins/中下載了Email Extension Plugin、Zentimestampplugin、Robot Framework plugin插件:
2) 進入安裝插件界面
點擊 系統管理——>管理插件——>高級
這時候我們是不是看到了中間有個上傳插件的地方(其他地方我們的信息不一樣可以不管)。
點擊選擇文件按鈕,選中剛才我們下載的插件,注意每次只能選中一個文件,所以先選擇依賴文件。然后點擊上傳按鈕。這樣依次就可以將所有的插件離線安裝成功了!如下圖所示:
D. 配置
1. 系統設置
1) 進入【系統管理】-【系統設置】進行如下配置:設置${BUILD_TIMESTAMP}格式
2) 配置 ExtendedE-mail Notification默認設置
設置郵件內容和發送人:
default content type:設置郵件發送的格式:文本格式或者html格式
Use List-ID Email Header:設置郵件的發送的名稱(便於過濾)
Default Recipients:設置默認的收件人
Reply To List:設置默認回復列表
Emergency reroute:相當於一個郵件的轉發(郵件先發送到這里,然后在進行進一步處理)
Excluded Recipients:設置接收的黑名單(就是不發送給這些人)
Default Subject:設置默認的郵件主題
Maximum Attachment Size:這只郵件附件的最大值
Default Content:設置郵件的默認內容(里面可以引用一些環境變量的參數,或者插件的一些變量)
Default Pre-send Script:在發送郵件前執行的腳本
郵件通知:這是默認的郵件發送工具,配置和extemail插件設置差不多,只是不能設置郵件的默認發送策略,和郵件發送的內容等信息
【user name:認證的郵箱;password:認證的密碼(並非郵箱的密碼,是開啟smtp時給的一串字符);如果郵箱是ssl鏈接,就需要勾選use ssl;smtp port :如果你的smtp服務不是465的端口,需要配置對應的端口;charset:郵件編碼設置】
注:這里的密碼並不是我們郵箱真正的密碼,這是QQ郵箱為了給第三方客戶端登錄的授權碼,QQ郵箱是默認關閉SMTP的,所以我們還需要去開通QQ郵箱的SMTP服務,否則第三方客戶端無法正常發送郵件。
QQ郵箱開通的SMTP服務步驟如下:
根據提示發送信息,之后QQ會給一個授權碼,把該授權碼,填到Extended E-mail Notification的密碼即可
Extended E-mail Notification默認設置里Default Content的值是填寫 ${SCRIPT,template=”robot_results.groovy”}設置這個模板:
在$Jenkins_Home/email-templates目錄(如果沒有email-templates請自行創建)下創建一個robot_results.groovy文件,內容如下:
robot_results.groovy文件下載地址:https://download.csdn.net/download/glongljl/10396246
其中Jenkins_Home的路徑不知道在哪里的話,你可以去看一下系統設置頁面,上面有寫有:
2. 創建任務
3. 任務的配置
1) General
選中“Restrict where this project can be run”,其LabelExpression填寫“master”
2) 源碼管理
3) 構建觸發器
4) 構建環境
5) 構建
如果在Windows系統中搭建jenkins的話,在構建中,選擇“Execute Windows batch command”,輸入pybot.bat d:\test.txt (這只是舉個例子,具體執行哪個目錄下的哪些case,根據實際情況決定)
如果不清楚pybot.bat的用法,可以用RIDE跑一個用例,看command信息,先直接拿過來調試用用
6) 構建后操作
Robot results:
構建后的操作,選擇“PublishRobot Framework test results”
*Directory ofRobot output 填一個本地路徑,要根據你的output文件放在哪里了,默認可以不填
*Thresholds forbuild result 閥值設置,如80%和100%,這里應該是測試用例執行成功率和通過率的設置
注:如果不知道Directoryof Robot output填什么路徑,可以通過控制台輸出進行定位,如下:
其實report.html和log.html的輸出路徑是在啟動腳本控制的,如下:
Email 信息:
點擊“增加構建后操作步驟”,然后點擊“Editable Email Notification”,進入郵件內容詳細配置界面。
Default Subject: 郵件主題,可以書寫成:XXX項目自動化測試通知:$PROJECT_NAME- Build # $BUILD_NUMBER - $BUILD_STATUS! 分析下這幾個參數什么意思:$PROJECT_NAME 構建項目的名稱,也就是selenium_2_combat;# $BUILD_NUMBER 構建的號碼;$BUILD_STATUS構建狀態,這幾個參數,它會自動讀取,按照這種格式書寫即可。
Default Content:郵件內容,這塊是重點,最能體現報告的重點,我們需要輸入以下內容:
<hr/>
(本郵件是程序自動下發的,請勿回復!)<br/><hr/>
項目名稱:$PROJECT_NAME<br/><hr/>
構建編號:$BUILD_NUMBER<br/><hr/>
構建狀態:$BUILD_STATUS<br/><hr/>
觸發原因:${CAUSE}<br/><hr/>
測試報告:<ahref="http://192.168.1.106:8080/job/$PROJECT_NAME/ws/autotest/result/test-report/power-emailable-report.html">http://192.168.1.106:8080/job/autotest/ws/autotest/result/test-report/power-emailable-report.html</a><br/><hr/>
構建日志地址:<ahref="${BUILD_URL}console">${BUILD_URL}console/</a><br/><hr/>
構建地址:<ahref="$BUILD_URL">$BUILD_URL</a><br/><hr/>
構建報告:<ahref="${BUILD_URL}testReport">${BUILD_URL}testReport/</a><br/><hr/>
變更集:${JELLY_SCRIPT,template="html"}<br/><hr/>
其中的紅色字體需要修改成自己電腦的IP地址,這樣別人才能訪問到jenkins上的測試結果。
點擊頁面上的Advanced settings設置什么時候觸發發送郵件的功能:
把默認的trigger給刪除掉,然后新增一個trigger,然后選擇Always選項,如此便不管構建成功還是失敗都會發送郵件。
點擊應用后保存,項目配置完成!!!
4. 郵件查收
點擊“立即構建”
執行之后,結果顯示如下:
對應郵箱查收如下
E. Jenkins常錯誤
1. 反向代理設置錯誤
其實就是,系統管理-->系統設置里的Jenkins URL沒有寫對,原因是配置文件/etc/sysconfig/jenkins我修改了jenkins啟動端口,這里沒有相應修改
Jenkins URL
將localhost修改為真實地址即可
修改后已不再提示代理問題
2. 點擊‘立即獲取’插件,報unable to find valid certification path to requested target錯誤
原因是缺少證書
3. 缺少依賴插件
根據提示到http://updates.jenkins-ci.org/download/plugins/下載對應的插件
4. 校驗郵箱的聯通性
如果Test e-mail recipient沒有填郵箱信息,則會報如下錯誤
5. jenkins郵件配置完后發送測試郵件是成功的,並且也能收到的,構建結束成功后log提示成功,但是沒有收到郵件
原因是Extended E-mailNotification 的SMTP服務器配置沒有使用Jenkins自身的需要專門配置。在系統配置里面多配置一次就行
6. jenkins調用robot_results.groovy 未生效
配置如下:
任務配置:Default Content引用$DEFAULT_CONTENT變量
$DEFAULT_CONTENT變量配置:${SCRIPT,template="robot_results.groovy"}
robot_results.groovy文件是在$Jenkins_Home/email-templates目錄下的
robot_results.groovy內容請看如下:
robot_results.groovy文件下載地址:https://download.csdn.net/download/glongljl/10396246
模板一:

<% import java.text.DateFormat import java.text.SimpleDateFormat %> <!-- Robot Framework Results --> <!DOCTYPE html> <html> <style type="text/css"> table {width:720px;table-layout:fixed;} td {width:180px;} td.title { background-color:#343A40; text-align: center; } td.suite{background-color:#EEE8AA;} td.case{background-color:#dff0d8;} td.head{background-color:#1E90FF;} td.error {background-color:#FF6666;} table thead tboday tr td {cellspacing:0px;border:1px;} h2.span{color:white;} span.pass{color:#66CC00;} span.fail{color:#FF3333;} </style> <body> <% def robotResults = false def actions = build.actions // List<hudson.model.Action> actions.each() { action -> if( action.class.simpleName.equals("RobotBuildAction") ) { // hudson.plugins.robot.RobotBuildAction robotResults = true %> <div> <table cellpadding="4" align="left"> <thead> <tr> <td class="title" colspan="4"><h2><span>${project.name}</span><span> 自動化測試報告</span></h2></td> </tr> <tr> <td class="case"><b>詳細報告</b></td> <td colspan="3" class="case"><a href="${rooturl}${build.url}robot/report/report.html">點擊查看報告詳情</a></td> </tr> <tr> <td class="head"><b>用例總數</b></td> <td class="head"><b>通過</b></td> <td class="head"><b>不通過</b></td> <td class="head"><b>通過率</b></td> </tr> <tr> <td class="case"><%= action.result.overallTotal %></td> <td class="case"><b><span class="pass"><%= action.result.overallPassed %></span></b></td> <td class="case"><b><span class="fail"><%= action.result.overallFailed %></span></b></td> <td class="case"><%= action.overallPassPercentage %>%</td> </tr> <tr> <td colspan="2" class="head"><b>Test Name</b></td> <td class="head"><b>Status</b></td> <td class="head"><b>Elapsed Time</b></td> </tr> </thead> <tboday> <% def suites = action.result.allSuites suites.each() { suite -> def currSuite = suite def suiteName = currSuite.displayName //忽略最上層結構兩個占位的元素 while (currSuite.parent != null && currSuite.parent.parent != null) { currSuite = currSuite.parent suiteName = currSuite.displayName + "." + suiteName } %> <tr> <td colspan="4" class="suite"><b><%= suiteName %></b></td> </tr> <% DateFormat format = new SimpleDateFormat("yyyyMMdd HH:mm:ss") def execDateTcPairs = [] suite.caseResults.each() { tc -> Date execDate = format.parse(tc.starttime) execDateTcPairs << [execDate, tc] } //按執行日期、顯示名稱進行排序 execDateTcPairs = execDateTcPairs.sort{ a,b -> a[1].displayName <=> b[1].displayName } execDateTcPairs = execDateTcPairs.sort{ a,b -> a[0] <=> b[0] } execDateTcPairs.each() { def execDate = it[0] def tc = it[1] %> <tr> <td colspan="2" class="case"><%= tc.displayName %></td> <td class="case"><b><span style="color:<%= tc.isPassed() ? "#66CC00" : "#FF3333" %>"><%= tc.isPassed() ? "PASS" : "FAIL" %></span></b></td> <td class="case"><%= tc.getDuration().intdiv(60000)+"分"+(tc.getDuration()-tc.getDuration().intdiv(60000)*60000).intdiv(1000)+"秒" %></td> </tr> <% if(tc.errorMsg != null) { %> <tr> <td class="error"><b><span>錯誤描述:</span></b></td> <td class="error" colspan="3"><span><%= tc.errorMsg%></span></td> </tr> <% }%> <% } // tests } // suites %> </tboday> </table> </div> <% } // robot results } if (!robotResults){ %> <p>No Robot Framework test results found.</p> <%}%> </body> </html>
模板二:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <style type="text/css"> /*base css*/ a{color:#4a72af} body{background-color:#e4e4e4} body,p{margin:0;padding:0} img{display:block} h1,h2,h3,h4,h5,h6{margin:0 0 .8em 0} h3{font-size:28px;color:#444!important;font-family:Arial,Helvetica,sans-serif} h4{font-size:22px;color:#4a72af!important;font-family:Arial,Helvetica,sans-serif} h5{font-size:18px;color:#444!important;font-family:Arial,Helvetica,sans-serif} p{font-size:12px;color:#444!important;font-family:"Lucida Grande","Lucida Sans","Lucida Sans Unicode",sans-serif;line-height:1.5} table.robotstat { border: 1px solid black; border-collapse: collapse; empty-cells: show; margin: 0px 1px; table-layout: fixed; word-wrap: break-word; font-size: 1em; border-width:1px; } tr.test_column_robot { background-color:#C6C6C6; } ol li img{display:inline;height:20px} /*div styles*/ .news{text-align:center;padding-top:15px;} .content{width:720px;margin:0 auto;background-color:white} .round_border{margin-bottom:5px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;margin-top:0;font-size:14px;padding:6px;border:1px solid #ccc} .status{background-color:<%= build.result.toString() == "SUCCESS" ? 'green' : 'red' %>;font-size:28px;font-weight:bold;color:white;width:720px;height:52px;margin-bottom:18px;text-align:center;vertical-align:middle;border-collapse:collapse;background-repeat:no-repeat} .status .info{color:white!important;text-shadow:0 -1px 0 rgba(0,0,0,0.3);font-size:32px;line-height:36px;padding:8px 0} .main img{width:38px;margin-right:16px;height:38px} .main table{font-size:14px;} .main table th{text-align:right;} .bottom-message{width:720px;cellpadding:5px;cellspacing:0px} .bottom-message .message{font-size:13px;color:#aaa;line-height:18px;text-align:center} .bottom-message .designed{font-size:13px;color:#aaa;line-height:18px;font-style: italic;text-align:right} img.cartoon {width: 36px; display:inline} </style> <body> <div class="content round_border"> <div class="status"> <p class="info">構建狀態 <%= build.result.toString().toLowerCase() %></p> </div> <!-- status --> <div class="main round_border"> <table> <tbody> <tr> <th>項目名稱:</th> <td>${project.name}</td> </tr> <tr> <th>構建輪次:</th> <td><a href="${rooturl}${build.url}">${build.displayName}(點擊查看此輪構建信息)</a></td> </tr> <tr> <th>構建時間:</th> <td>${it.timestampString}</td> </tr> <tr> <th>構建時長:</th> <td>${build.durationString}</td> </tr> <tr> <th>構建緣由:</th> <td><% build.causes.each() { cause -> %> ${cause.shortDescription} <% } %></td> </tr> <tr> <th>測試報告:</th> <td><a href="${rooturl}${build.url}robot">點擊查看測試報告詳情</a></td> </tr> <tr> <!-- test stat --> <th>測試統計:</th></br> <td> <table id="robotstat" class="robotstat"> <thead> <tr id="test_column_robot" class="test_column_robot"> <th>測試總用例數</th> <th>失敗用例數</th> <th>測試通過率</th> </tr> </thead> <tbody> <tr> <% def robotTestResultAction = it.getAction("hudson.plugins.robot.RobotBuildAction") %> <td>${robotTestResultAction.getTotalCount()}</td> <td>${robotTestResultAction.getFailCount()}</td> <td>${robotTestResultAction.getOverallPassPercentage()}%</td> </tr> </tbody> </table> </td> </tr> <tr> <th>變更記錄:</th> <td><a href="${rooturl}${build.url}changes">點擊查看變更記錄</a></td> </tr> <tr> <td colspan="2"> </td> </tr> </tbody> </table> </div> <!-- main --> <% def artifacts = build.artifacts if(artifacts != null && artifacts.size() > 0) { %> <div class="artifacts round_border"> <b>Build Artifacts:</b> <ul> <% artifacts.each() { f -> %> <li><a href="${rooturl}${build.url}artifact/${f}">${f}</a></li> <% } %> </ul> </div> <% } %> <!-- artifacts --> <% def changeSet = build.changeSet if(changeSet != null) { def hadChanges = false def count = 0 %> <div class="details round_border"> <b>變更詳細:</b> <ol> <% changeSet.each() { cs -> hadChanges = true def aUser = cs.author %> <li>${cs.msgAnnotated} (${aUser.displayName}) (<a href="${rooturl}${build.url}changes#detail${count}">detail</a>)</li> <% count ++ } %> </ol> </div> <% } %> <!-- details --> </div> <!-- content --> <table class="bottom-message" align="center"> <tr> <td class="message">You are receiving this email because you are relavent with this build<br> </td> </tr> <tr> <td colspan="2" class="designed">designed by @YTO </td> </tr> </table> <!-- bottom message --> </body>
結果郵箱收到時沒有讀取robot_results.groovy的模板內容
經過分析:
是由於缺少groovy-postbuild插件操作的,安裝groovy-postbuild插件
groovy-postbuild插件安裝完之后,重新執行計划,郵箱可以獲取到模板信息的,如下:
7. Robot Framework - Jenkins 的測試報告打不開
點擊郵件的鏈接
以及點擊Jenkins上的鏈接
結果界面都會報如下錯誤:
解決辦法:
1. 如果你是用命令行開啟的
關閉Jenkins,修改開啟命令如下,重新開啟:
java -Dhudson.model.DirectoryBrowserSupport.CSP= -jar E:\Jenkins\jenkins.war
2. 如果你是用msi安裝的
找到jenkins.xml 文件,修改如下
<arguments>-Xrs-Xmx256m -Dhudson.model.DirectoryBrowserSupport.CSP=-Dhudson.lifecycle=hudson.lifecycle.WindowsServiceLifecycle -jar"%BASE%\jenkins.war" --httpPort=8080</arguments>
3. 如果你是用tomcat 啟動的
有個臨時的解決方法
打開jenkins 首頁——>進入系統管理——>進入腳本命令行
在輸入框輸入如下代碼,並執行
System.setProperty("hudson.model.DirectoryBrowserSupport.CSP","")
注:方法3 都可以使用,但是重啟后就失效了,需要重新執行
4. 訪問端解決辦法
以Firefox為例:
到 about:config 設置
security.csp.enable= false
之后問題正常顯示如下:
---------------------
作者:glong168
來源:CSDN
原文:https://blog.csdn.net/glongljl/article/details/80212611
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!