目的
jmeter很早就接觸了,最近又在接觸專案的時候整了一下。寫這篇部落格主要有兩個目的
1,為了給自己搭建jmeter做一個總結。
2,在部署過程中遇到過一些坑,在這分享出來,也希望能給需要的人一個參考。
介面測試概述
詳細介紹jmeter介面測試環境之前,先簡單介紹下介面測試
API testing is a type of software testing that involves testing application programming interfaces (APIs) directly and as part of integration testing to determine if they meet expectations for functionality, reliability, performance, and security. Since APIs lack a GUI, API testing is performed at the message layer.[2] API testing is now considered critical for automating testing because APIs now serve as the primary interface to application logic and because GUI tests are difficult to maintain with the short release cycles and frequent changes commonly used with Agile software development and DevOps).
WIKI定義:介面測試作為整合測試的一部分,通過直接控制API來判斷系統的功能性,可靠性,效能與安全性。API測試是沒有介面的,執行在通訊層。API 測試在自動化測試中有著重要的地位,因為API一般是應用邏輯的主要介面,而GUI測試在敏捷開發和DevOps的快速迭代和頻繁變更中很難維護。
分類
介面測試是測試系統元件間介面的一種測試。介面測試主要用於檢測外部系統與系統之間以及內部各個子系統之間的互動點。測試的重點是要檢查資料的交換,傳遞和控制管理過程,以及系統間的相互邏輯依賴關係等。
介面測試適用於為其他系統提供服務的底層框架系統和中心服務系統,主要測試這些系統對外部提供的介面,驗證其正確性和穩定性。介面測試同樣適用於一個上層系統中的服務層介面,越往上層,其測試的難度越大。
介面測試實施在多系統多平臺的構架下,有著極為高效的成本收益比,介面測試天生為高複雜性的平臺帶來高效的缺陷監測和質量監督能力。平臺越複雜,系統越龐大,介面測試的效果越明顯。
基於介面測試的重要性,以及它比較容易自動化的特性,通過持續整合的介面監控能夠及時的發現專案中存在的問題,這對持續運營的專案來說,非常重要。
模組介面測試
模組介面測試是單元測試的基礎。它主要測試模組的呼叫與返回。經常需要編寫一些樁模組與驅動模組。
主要測試要點如下:
檢查介面返回的資料是否與預期結果一致。
檢查介面的容錯性,假如傳遞資料的型別錯誤時是否可以處理。
介面引數的邊界值。例如,傳遞的引數足夠大或為負數時,介面是否可以正常處理。
介面的效能,介面處理資料的時間也是測試的一個方法。牽扯到內部就是演算法與程式碼的優化。
介面的安全性
WEB介面測試
web介面測試又可分為兩類:伺服器介面測試和外部介面測試。
伺服器介面測試:是測試瀏覽器與伺服器的介面。使用者輸入的資料是輸入到的前端頁面上,怎樣把這些資料傳遞的後臺的呢?通過http協議的get與post請求來實現前後端的資料傳遞。這也可認為是介面測試。
外部介面測試:這個很典型的例子就是第三方支付,比如在我們應用中在充流量時,交話費時,都會呼叫第三方支付介面。
主要測試要點如下:
請求是否正確,預設請求成功是200,如果請求錯誤也能返回404、500等。
檢查返回資料的正確性與格式;json是一種非常常見的格式。
介面的安全性,一般web都不會暴露在網上任意被呼叫,需要做一些限制,比如鑑權或認證。
介面的效能,這直接影響使用者的使用體驗。
介面測試工具
SOAPUI
JMeter
Grinder
Suds Python
介面測試的流程
1、 專案啟動後,測試人員要儘早找到開發人員拿到介面測試文件
2、 獲取介面測試文件後,就可以進行介面用例的編寫和除錯
3、 介面用例編寫除錯完成後,部署到持續整合的測試環境中,
4、 設定指令碼執行頻率,告警方式等基本引數,進行介面的日常監控
5、 每日進行介面指令碼的維護更新,介面異常的處理
測試用例設計與原則
測試用例
正面測試用例:
-
覆蓋所有的必選引數
-
組合可選引數
-
引數邊界值
-
如果引數的取值範圍是列舉變數,需要覆蓋所有列舉值
-
還應考慮實際業務應用場景,去設計輸入引數的組合。(這些用例可用來測試功能,作為SMOKE用例。也可將來用於壓力測試模擬實際業務場景,但要注意保證用例的獨立性,因為壓力測試是多執行緒的。比如我們測試ACCOUNT 建立介面,NAME是不能重的,在寫測試用例時,給NAME賦值時可以加一個時間戳, 這樣用例在多執行緒併發測試時也不會有問題)
負面測試用例:
-
空資料
-
包含特殊的字元
-
越界的資料
-
錯誤的資料
驗證點:
-
status code (正常情況下,所有請求都應該返回200)
-
響應資訊資料結構(目前大多數情況下,返回資訊都是JSON, 我們應該驗證相應的結構當資料資訊發生改變時)
-
驗證結點的型別
-
驗證結點的值 (主要是針對固定的值或者值遵循某些規則,我們能知道預期的結果的)
-
對於列表,應該根據請求引數,也應該驗證列表的長度是否與期望值一致
-
負面測試用例,應驗證ERROR INFO是否與實際相匹配
測試原則
測試應該是獨立的、可讀的、抗變的、可維護的,其實這也是所有自動測試應該遵循的原則
-
每個測試用例都是獨立的
-
測試用例都是可重複執行的 (這主要是說一些測試資料不能寫死,不同的環境資料可能不同。在實際工作中,解決方案有二:自已建立所需要的資料,比如你要測試介面需要輸入引數ACCOUNTID,你可以先呼叫建立ACCOUNT API, 然後從響應值拿到ACCOUNTID, 當你測試完你要測的介面後,再把新建的ACCOUNT刪除,也就是說一個測試用例分了三步。另外一種方法就是讀取資料庫,從資料庫獲取資料,這種方法在測試開發與測試環境還OK,但如果測線上環境就比較困難了,因為我們不能隨意更新上面的資料,也不能放過多的測試資料在上面。因此我個人比較推崇第一種方法,雖然增加開發用例的工作量,但一勞永逸)
-
測試能被執行在不同的環境裡(平常測試環境至少會分DEV/TEST/STAGING/ONLINE,我們在測試過程中,應該把域名,token/apikey等應放在一個變數裡,當切換環境時,我們只需改變變數的值即可
-
測試資料與業務相分離(測試資料包括引數介面資料/ 測試執行所需要的系統資料)
-
儘量統一共用的測試環境變數
-
測試完成後,要刪除不必要的測試資料。
為什麼要用Jmeter做介面測試
很大的一個原因是考慮了在部門內進行推廣的成本問題,另外也有開發能力較弱,時間有限不能充分去研究。jmeter自身也是非常好的一個介面測試工具,有以下一些優點:
- Jmeter支援錄製,工具有Gui介面,入手相對簡單。
- Gui便於除錯,本地除錯通過上傳,管理容易。
- 維護成本很小,Jmeter功能比較全面,不會讓自己陷入不停的維護框架的坑。
- Jmeter Case是基於xml的(雖然字尾是jmx格式),執行結果也可以匯出xml格式(結果為jtl字尾)
Jmeter做介面測試的缺陷:
- 單條Case執行依賴本地
- Jmeter編寫Case有一定學習成本
- 擴充性稍差,Case基於xml格式管理,後續如果想要自己編寫平臺,匯出這些Case是個不小的工作量
Jmeter+Jenkins+Ant實施方案的適用範圍
- 小型公司或小團隊,大公司有自己的平臺,後續需求也多,還是自己寫一套吧。
- 測試團隊較小,沒有專門的測試開發部門支援。
- 程式設計不是很牛逼的,如果你很厲害,自己能搞定所有前端,後臺,自己搞比較好。
- 需要立刻出活的,不想將有限的精力放到後期維護當中的
環境搭建
Jmeter相關外掛安裝:
Jmeter的外掛安裝很簡單,只需要下載對應外掛解壓即可。
- 下載地址:http://jmeter-plugins.org/downloads/all/
- 下載後解壓放入:apache-jmeter-2.7\lib\ext\目錄下
- 重啟jmeter ps:資料庫連結驅動如果需要需要專門下載,例如mysql需要jdbc的jar包,地址:http://dev.mysql.com/downloads/file/?id=462850
用例生成
生成原則:
- 每個功能模組為一個獨立的jmx檔案。增加可維護性。(儘量不要將一個jmx檔案放入太多功能,後期維護成本會很高。)
- 模組的私有變數儲存在模組中,多模組共有的(例如伺服器ip埠等)可以考慮存在單獨的檔案中讀取。
- 介面測試不要放太多執行緒,畢竟不是做壓力測試,意義也不大。
- 匯出方法:
- 編寫測試用例
- 檔案——儲存為——指定路徑——確定:
Jmeter配置檔案修改:
為什麼要修改配置檔案
- jmeter執行結果檔案預設儲存的不是xml格式,無法轉化成html格式
- jmeter執行結果檔案預設有很多執行資料是不儲存的,而測試報告需要這些資料
- 配置檔案路徑 ${jmeterhome}/bin/jmeter.profile
- 配置檔案修改內容: 修改jtl檔案格式
- 2.7預設實際已是xml,但是在2.7之前的版本還是csv
去掉註釋(#),修改csv為xml
新增jtl檔案結果引數:
根據想要儲存的引數修改,若不會可參照後文第三方模板網址給出的引數修改。(後面會提到修改jmeter自帶的報告模板,部分資料需要在這裡配置進行展示)
修改後別忘記去掉註釋(#)
Jenkins相關外掛介紹與配置:
Jenkins外掛安裝方法本文不做介紹,感興趣的可以看我jenkins相關的部落格。
Jmeter外掛:Performance plugin
- 功能:用來展示jmeter執行結果
- 配置截圖
- 配置說明:
- Report files:配置jtl檔案路徑,相對路徑與絕對路徑均可,圖為相對路徑
- 其他選項:配置失敗比例顯示圖形等引數,按需配置
Ant外掛:Ant Plugin
- 功能:用來執行Ant
- 配置截圖:
- 配置說明:
- Ant Plugin可以在構建步驟中新增,直接執行構建。
- targets:執行執行目標
- build files:指定執行build.xml路徑
除了Ant外掛執行,也可以選擇命令列執行:
- 新增shenll指令碼(windows下新增dos指令碼)執行構建
- 相比用外掛構建,命令列構建有以下優缺點:
- 需要在伺服器中直接安裝ant並配置環境變數,確保jenkins可以直接執行ant命令
- 如果Jenkins是放在tomcat容器中,需要在tomcat中配置環境變數,否則會報找不到Ant命令,具體配置如下:
-
編輯catalina.sh檔案,加入環境變數,否則jenkins會報找不到Ant錯誤() #See the license for the…… JAVA_HOME=/usr/lib/jvm/jdk1.8.0_31 Export JENKINS_HOME="/root/.jenkins"
-
靈活性更強,可以直接指定Ant的執行引數
Svn外掛:Subversion Plug-in
- 功能:版本管理,按需使用
- 配置截圖:
- 配置說明:
- Reponsitory URL:填寫倉庫url地址
- Add按鈕:新增svn的使用者名稱密碼
- 其他選項:按需配置
Html展示外掛:HTML Publisher plugin
- 配置說明:
- HTML directory to archive:填寫生成html檔案的路徑
- index page[s]:填寫展示報告的主頁
- 其他選項:按需填寫
- 原理說明:
- 本外掛並不會自己產生html檔案,而是通過xslt轉化xml生成的報告
- xslt可以自己在伺服器中安裝,也可以通過通過Ant配置檔案指定jar包,本文就是通過Ant指定jmeter內部整合的jar包生成的html檔案並不是在jenkins中預設的報告路徑展示,而是會複製到${jenkinshome}/jobs/projectname/htmlreports/HTML_REPORT目錄下
每次只能展示最新版本的html報告,也就是說上一次編譯的html報告會被覆蓋,因為jenkins安全性的問題,預設載入出來的報告是無css的,通過以下配置解決:
HTML Publisher Plugin 外掛在新的Jenkins版本中會導致開啟的網頁中無法載入CSS以及無法點選按鈕的情況,由於CSP導致,可在Jenkins控制檯中執行:System.setProperty("hudson.model.DirectoryBrowserSupport.CSP", "")
以解決此問題。其他由於CSP原因導致的html外掛也可用此方法解決
Jenkins專案總體配置:
- 伺服器環境與依賴
- Jdk:安裝並配置環境變數
- Ant:安裝並配置環境變數
- Jmeter:安裝並新增需要的外掛
- 其他:
- Jmeter+Ant,需要將${jmeterhome}/extras/ant-jmeter-1.1.1.jar檔案拷貝到${anthome}/lib目錄下,否則編譯會報錯
- Jmeter如需連結資料庫,需新增jdbc外掛
- 如果不引入jmeter中的xslt,需要手動安裝該軟體
- Jenkins專案配置:
- jenkins的工作路徑,同樣的jar包都可能會生成不同的路徑。 jenkins——系統設定——高階
Ant相關使用:
定製整合Ant配置檔案:
<?xml version="1.0" encoding="UTF-8"?> <project name="ant-jmeter-test" default="all" basedir="."> <tstamp> <format property="time" pattern="yyyyMMddhhmm" /> </tstamp> <!-- 需要改成自己本地的 Jmeter 目錄--> <property name="jmeter.home" value="D:\Devlop\jmeter\apache-jmeter-2.7" /> <!-- jmeter生成jtl格式的結果報告的路徑--> <property name="jmeter.result.jtl.dir" value="D:\API\JF_API\Report\jtl" /> <!-- jmeter生成html格式的結果報告的路徑--> <property name="jmeter.result.html.dir" value="D:\API\JF_API\Report\html" /> <!-- 生成的報告的字首 --> <property name="ReportName" value="TestReport" /> <!-- 需要輸出html報告的時候,html附帶時間 <property name="jmeter.result.jtlName" value="${jmeter.result.jtl.dir}/${ReportName}${time}.jtl" /> <property name="jmeter.result.htmlName" value="${jmeter.result.html.dir}/${ReportName}${time}.html" /> --> <property name="jmeter.result.jtlName" value="${jmeter.result.jtl.dir}/${ReportName}.jtl" /> <property name="jmeter.result.htmlName" value="${jmeter.result.html.dir}/${ReportName}.html" /> <!-- Diffrent version of Jmeter has its own ant-jmeter.jar,Please input the right versioin --> <path id="ant.jmeter.classpath"> <pathelement location="${jmeter-home}/extras/ant-jmeter-1.1.1.jar" /> </path> <!-- use this config to generate html report; if not, may not display Min/Max Time in html--> <path id="xslt.classpath"> <fileset dir="${jmeter.home}/lib" includes="xalan-2.7.1.jar"/> <fileset dir="${jmeter.home}/lib" includes="serializer-2.7.1.jar"/> </path> <target name="all"> <antcall target="test" /> <antcall target="report" /> </target> <target name="test"> <taskdef name="jmeter" classname="org.programmerplanet.ant.taskdefs.jmeter.JMeterTask" /> <jmeter jmeterhome="${jmeter.home}" resultlog="${jmeter.result.jtlName}"> <!-- 宣告要執行的指令碼。"*.jmx"指包含此目錄下的所有jmeter指令碼 --> <testplans dir="D:\API\JF_API\Test_Play" includes="*.jmx" /> <property name="jmeter.save.saveservice.output_format" value="xml"/> </jmeter> </target> <target name="report"> <xslt in="${jmeter.result.jtlName}" out="${jmeter.result.htmlName}" classpathref="xslt.classpath" style="${jmeter.home}/extras/jmeter-results-detail-report_30.xsl.xml" /> <xslt in="${jmeter.result.jtlName}" out="${jmeter.result.html.dir}\TestLog.html" classpathref="xslt.classpath" style="${jmeter.home}/extras/jmeter-results-shanhe-me.xsl" /> <!-- 因為上面生成報告的時候,不會將相關的圖片也一起拷貝至目標目錄,所以,需要手動拷貝 --> <copy todir="${jmeter.result.html.dir}"> <fileset dir="${jmeter.home}/extras"> <include name="collapse.png" /> <include name="expand.png" /> </fileset> </copy> </target> </project>
- 如上,有文字標示的地方需要修改,對應的路徑需要修改為自己的本地路徑
- style引數為生成html檔案的模板檔案,可以修改為自己的模板檔案,jmeter提供了多個模板檔案可供使用,我這裡呼叫了兩個style檔案
Case管理目錄結構:
- ./Test_Play/目錄用來放Jmeter生成的Case檔案(編寫時注意,不要用絕對路徑,否則後續維護成本會提高)
- ./Test_suit/目錄用來放Jmeter測試需要的相關配置檔案
- ./資源/目錄用來存放專案相關的一些文件資訊
- build.xml檔案,Ant的配置檔案
- 閱讀build.xml檔案,會發先還有一個自動生成的目錄./report,該目錄下有兩個目錄jtl以及html,用來放置不同格式的測試報告。
測試執行與報告優化:
- jmeter自帶模板
- jmeter自帶了4個模板
- 模板路徑:${jmeterhome}/extras/jmeter-results*.xsl
- 模板效果(jmeter-results-detail-report_30.xsl.xml):
- 模板使用:
- 修改${jmeterhome}/bin/jmeter.profile配置檔案,新增所需的報告引數
- build.xml檔案中指定,(演示效果指定了兩個模板 1.jmeter-results-detail-report_30.xsl.xml 2.jmeter-results-shanhe-me.xsl 兩個模板都可在網上進行下載)
- 下載地址:http://shanhe.me/node/18/314
注意事項:
- 千萬不要忘記修改jmeter.profile檔案
- 地址中介紹build.xml檔案以及jmeter.profile檔案具體的引數修改,不要忽視
指定從第一個跳轉到第二個Log網頁也很簡單,jenkins要用的時候把兩份都上傳了就好