# 讓開發自動化: 自動負載測試
_使用 Apache Ant 和 Apache JMeter 頻繁進行負載測試_
負載測試通常在開發周期的后期執行,但是并不一定要這樣。在 [_讓開發自動化_](http://www.ibm.com/developerworks/cn/java/j-ap/)的這一期,自動化專家 Paul Duvall 將向您描述如何創建一個運行 JMeter 測試的預訂集成構建,發現和修復開發周期中出現的問題。
您的軟件系統可供多少用戶同時訪問?在不引起性能下降的前提下可以加載多少數據?您的系統有多大的吞吐量需求?間隔多久測試一次這些需求?如果您每天至少可以指定并確認一次這些負載和性能需求得到了滿足,又會怎樣?通過將負載測試作為預定的自動構建的一部分來運行,您可以更快地確定您的系統在某些負載條件下的執行情況,并快速適應變化。
## 關于本系列
作為開發人員,我們的工作就是為終端用戶實現過程自動化;然而,很多開發人員卻忽略了將自己的開發過程自動化的機會。為此,我編寫了 [_讓開發自動化_](http://www.ibm.com/developerworks/cn/java/j-ap/)這個系列的文章,專門探討軟件開發過程自動化的實際應用,并教您 _何時_以及 _如何_成功地應用自動化。
我曾經參與過的一個項目建立了一組很好的自動化測試,可以對應用程序進行負載測試,同時它還可以運行多個事務。問題是,這些測試需要進行一些手動調節,所以開發團隊無法在沒有人工干預的情況下運行這些測試。這限制了測試器可用時(通常僅工作幾個小時)進行測試的次數。在實踐中,測試要隔好幾天才進行一次 —間隔時間太長,無法及時檢測問題。
在本文中,我將探討如何使用 JMeter 創建自動化測試、將測試作為自動構建的一部分運行,以及將測試設置為每天自動運行(通常當機器的使用率低時)。將測試作為預定構建的一部分運行可以讓您:
* 在任何時候執行負載測試
* 在開發過程的初期檢測并解決負載和性能問題
* 監視構建服務器的最新的負載測試和性能測試報告
* 減少依靠單個人配置和運行測試時可能出現的瓶頸和錯誤
## 使用 JMeter 提升性能
Apache JMeter 是一個開放源碼項目,您可以用來在服務器上模擬重負載(有關 JMeter 的更多信息,請參閱 [參考資料](#resources))。JMeter 的文檔集描述了如何使用它的很多功能,并提供了大量例子。
### 運行 JMeter
下載并解壓縮 JMeter ZIP 文件(請參閱 [參考資料](#resources)獲得下載 JMeter 的鏈接)之后,使用命令提示符進入您解壓縮 JMeter 的位置,并鍵入 `cd bin`更改 bin 目錄。從 bin 目錄鍵入 `jmeter`打開 JMeter Swing 應用程序,如圖 1 所示:
##### 圖 1\. JMeter GUI

### 創建測試計劃
## 通過示例編寫測試
JMeter 附帶了很多示例測試計劃和腳本。不必從頭創建測試計劃,您可以使用 docs 目錄中的例子,并隨著項目的發展逐步配置測試計劃。復雜之處主要在于學習編寫可以有效模擬負載和性能需求的負載測試。
您可以使用 JMeter GUI 創建 _測試計劃_。JMeter 中的不同測試計劃類型包括:
* Web 測試計劃
* 數據庫測試計劃
* FTP 測試計劃
* LDAP 測試計劃
* 擴展 LDAP 測試計劃
* Web 服務測試計劃
* JMS 點對點測試計劃
* JMS 主題測試計劃
* 監視器測試計劃
* 偵聽器
每個測試計劃都以 XML 格式存儲在一個后綴名為 .jmx 的文件中。這種非二進制的格式使以后編輯計劃更容易。盡管您可以通過以下 JMeter XML 模式來創建測試計劃,但是使用 GUI 要容易得多。稍后您將看到一個例子,該例子用參數表示 JMeter 的配置值,以自定義測試的運行方式。
* * *
## 節省勞力的負載測試
使用 GUI 運行測試,需要一個 _人_來親自執行它們。這會增加過程瓶頸和知識筒倉的可能性。 通過自動構建(比如 Ant 構建)運行測試,您可以配置 JMeter 測試來運行,而無需打開 JMeter 應用程序。另外,該測試每次都以同樣的方式運行 —不會增加額外的工作。
### 使用 Ant 操作 JMeter 測試
學習了如何使用 GUI 軟件工具后,我想看看它是否可以從命令行運行某些實用工具,這樣我就不需要反復執行同樣的操作。例如,每次打開 JMeter 應用程序時,我喜歡選擇 File > Open 來打開文件,然后運行一次或多次測試。我可以為這些組操作編寫一個腳本,每次以同樣的方式運行它們。幸運的是,已經有人編寫了一個 Ant 任務來為 JMeter 做這件事:它執行負載測試,同時提供了一種傳入可選參數和屬性的方式。
## 示例構建腳本
JMeter 分區的 extras 目錄包含一個示例 build.xml 腳本,說明了 JMeter Ant 任務的用法。
在清單 1 中,我使用 Ant 的 `taskdef`任務定義 JMeter 任務,我將其命名為 `jmeter`,這樣我可以在該 Ant 腳本的其他地方使用它。要使用該腳本,您的 Ant 類路徑中必須存在 ant-jmeter.jar 文件(請參閱 [參考資料](#resources)獲得下載鏈接)。
##### 清單 1\. 在 Ant 中定義 JMeter 任務
```
<taskdef name="jmeter" classname="org.programmerplanet.ant.taskdefs.jmeter.JMeterTask"/>
```
[清單 2](#listing2)中的示例代碼運行一個 JMeter 負載測試 BreweryTestPlan.jmx。要運行某個目錄中的所有測試,只需輸入 `*.jmx`,而不是特定的文件名。`jmeter`任務所需的屬性為 `jmeterhome`、`testplan`(`s`)以及 `resultlog`或 `resultlogdir`。(清單 2 未顯示 `resultlogdir`,因為它使用 `resultlog`。)
##### 清單 2\. 從 Ant 運行 JMeter
```
<jmeter
jmeterhome="${jmeter.home}"
resultlog="${basedir}/target/JMeterResults.xml">
<testplans dir="${basedir}/tests/load" includes="BreweryTestPlan.jmx"/>
</jmeter>
```
清單 2 中的 Ant 代碼創建了一個名為 JMeterResults.xml 的輸出文件,用于創建 HTML 報告。
### 使用 XSLT 呈現報告
將 JMeterResults.xml 文件作為清單 3 中的 `xslt`Ant 任務的輸入,可以為清單 2 中運行的所有 JMeter 測試生成一個 HTML 報告。在 JMeter extras 目錄中提供的 XSL 樣式表(jmeter-results-detail-report_21.xsl)用于將 JMeterResults 文件轉換為 HTML。
##### 清單 3\. 使用 XSLT 創建 JMeter HTML 報告
```
<xslt in="${basedir}/target/JMeterResults.xml"
out="${basedir}/target/JMeterResults.html"
style="${jmeter.home}/extras/jmeter-results-detail-report_21.xsl"/>
```
JMeter 也提供了一個不太詳細的 XSL 樣式表文件,用于總結負載測試的結果。
### 在 HTML 中顯示報告
圖 2 是一個使用清單 3 中的 `xslt`任務生成的 HTML 報告的例子。它顯示了每個運行的負載測試,以及測試狀態、時間和所有測試的聚合狀態和時間。
##### 圖 2\. 生成 JMeter HTML 報告

稍后我將在本文中向您展示如何從 CruiseControl Continuous Integration (CI) 服務器(請參閱 [參考資料](#resources))中顯示這些報告。
### 向 JMeter 傳遞參數
根據您運行的測試類型,您可能想要傳遞參數和屬性,以改變單個測試或一組測試執行的方式。例如,清單 4 展示了如何增加 JVM 內存并指定線程和循環的數量:
##### 清單 4\. 向 JMeter 傳遞可選參數和屬性
```
<jmeter
jmeterhome="${jmeter.home}"
resultlog="${basedir}/target/JMeterResults.xml">
<jvmarg value="-Xincgc"/>
<jvmarg value="-Xmx128m"/>
<jvmarg value="-Dproperty=value"/>
<property name="request.threads" value="5"/>
<property name="request.loop" value="50"/>
<property name="jmeter.save.saveservice.assertion_results" value="all"/>
<property name="jmeter.save.saveservice.output_format" value="xml"/>
<testplans dir="${basedir}/tests/load" includes="BreweryTestPlan.jmx"/>
</jmeter>
```
可以使用很多內置的其他參數和屬性來修改 JMeter 測試運行的方式(有關詳細信息,請參閱 [參考資料](#resources))。
在執行負載測試的方式上,使用參數和屬性提供了一定的靈活性,但是它不能解決如何在不同的目標環境中運行負載測試的問題,比如測試和驗證環境。要向測試計劃添加特定于環境的信息,您需要在 .jmx 文件中放入一些記號,以便當負載測試在自動構建腳本中運行時可以對 .jmx 文件進行過濾和修改。
* * *
## 及時負載測試
使用自動構建運行負載測試時,將其安排為按某個周期運行,比如每晚運行一次。您可以使用 CI 或構建管理服務器來實現。
### 安排 CruiseControl 每天運行負載測試
使用 CI 服務器的目的在于,只要向項目的版本控制存儲庫應用了更改,就運行一個自動構建。您也可以將其配置為按特定次數運行構建。由于負載測試通常需要較多的計算資源,在這些資源未被占用時運行測試(例如深夜或清早)會比較好。
在 [清單 5](#listing5)中,一個自動構建被安排在晚上 11:00 點 (2300) 使用 CruiseControl(請參閱 [參考資料](#resources))運行。您可以修改 CruiseControl 配置文件,以使用一個特定的 Ant 目標運行一個委托構建,比如一個給定的 `run-load-tests`構建。
##### 清單 5\. 使用 CruiseControl 運行預定的負載測試
```
...
<modificationset>
<svn RepositoryLocation="${svnrepo.location}"/>
<timebuild username="admin" time="2300"/>
</modificationset>
...
```
通過將負載測試安排在晚上運行(如清單 5 中一樣),您將不會聽到有關加班、休假或忘記運行測試等借口 —它們會自動運行。
### 在 CruiseControl 中顯示報告
您已經看到了如何使用 Ant 顯示 JMeter 測試報告。但是,JMeter 報告只能與單個機器上的一個開發人員通信。負載測試會影響整個應用程序,所以整個團隊都會希望看到結果。好處在于,您可以輕松配置您的 CI 服務器,以顯示這些報告。因為已經使用 Ant 生成了這些報告,所以只需要使 JMeter HTML 報告可以從 CruiseControl 項目儀表板訪問。您可以向 CruiseControl 的 config.xml 文件添加幾行代碼來實現這個目的,如清單 6 所示:
##### 清單 6\. 配置 CruiseControl 來顯示 JMeter 報告
```
<project name="brewery">
...
<log>
<merge dir="merge dir="projects/${project.name}/reports/jmeter" />
</log>
...
</project>
```
現在,團隊中的每個人都可以(真正地)共享這些信息了。很多其他 CI 和構建管理服務器也提供類似的報告集成功能。
* * *
## 結束語
在本文中,我展示了如何向您的開發工具箱添加自動化負載測試。通過使用自動構建運行負載測試,然后將測試安排為定期運行,您可以在系統容量問題出現之前及時發現它們。這種方法使得評估架構和數據更改的影響變得更加容易。當與本文章 [系列](http://www.ibm.com/developerworks/cn/java/j-ap/)中描述的其他技術結合使用時,開發團隊常常能夠交付更高質量的軟件。
* * *
## 下載
| 描述 | 名字 | 大小 |
| --- | --- | --- |
| 本文的示例 Ant 腳本 | [j-ap04088-jmeter-example.zip](http://www.ibm.com/developerworks/apps/download/index.jsp?contentid=310260&filename=j-ap04088-jmeter-example.zip&method=http&locale=zh_CN) | 6KB |
- 讓開發自動化
- 讓開發自動化: 部署自動化模式,第 2 部分
- 讓開發自動化: 部署自動化模式,第 1 部分
- 讓開發自動化: 使用基于向導的安裝程序
- 讓開發自動化: 針對廣大開發人員的并行開發
- 讓開發自動化: 實現自動化數據庫遷移
- 讓開發自動化: 持續重構
- 讓開發自動化: 文檔化一鍵通
- 讓開發自動化: 利用 Ivy 管理依賴項
- 讓開發自動化: 自動負載測試
- 讓開發自動化: 使用自動化加速部署
- 讓開發自動化: 持續集成反模式
- 讓開發自動化: 斷言架構可靠性
- 讓開發自動化: 持續測試
- 讓開發自動化: 用 Eclipse 插件提高代碼質量
- 讓開發自動化: 除掉構建腳本中的氣味
- 讓開發自動化: 選擇持續集成服務器
- 讓開發自動化: 持續檢查