韋亞軍,張文文
(南京國圖信息產業有限公司,南京 210000)
近年來,隨著計算機網絡化應用的進一步普及,大數據、云計算、區塊鏈等技術快速發展和應用,軟件環境變得極其復雜,通常由網絡、數據庫、負載均衡器、應用服務(中間件)、硬件等多個部分組成,任何一部分都有可能成為整個應用軟件的性能瓶頸,從而導致軟件整體性能低下。同時,軟件業務復雜度日益提升、用戶量急劇增加、操作行為多樣化使得保證軟件性能的過程變得極為困難,而如何對軟件性能進行測試和驗證,一直以來都缺少標準化的流程和方法[1-3]。
針對這一現狀,本文借助常用的性能測試工具LoadRunner,提出一種基于LoadRunner的軟件性能測試標準化流程,并對其中關鍵技術分析研究,以對軟件性能測試過程和方法給出指導。同時,結合淮安市“互聯網+不動產登記”一體化平臺項目對流程進行應用和驗證,結果表明,該流程有效地剔除測試過程中的冗余步驟,提高測試效率,不僅滿足大部分企業級軟件的性能測試和驗證,還可以指導測試人員快速準確地定位軟件的性能瓶頸,分析存在的問題。
軟件性能測試是質量保證過程必不可少的環節,是驗證軟件是否滿足用戶期望的性能需求,發現軟件可能存在的性能瓶頸,分析性能問題,并提供性能優化方案的過程。在實際測試過程中,可以根據具體的性能需求和應用領域采取不同的測試方法,完成對軟件的性能需求和應用領域驗證。常用的性能測試方法主要包括以下幾種[4-8]:
1)驗收性能測試:模擬實際業務量和使用場景,測試軟件性能是否滿足實際生產的性能要求,即在特定運行條件下驗證軟件的能力狀況,是最常見的一種性能測試方法。
2)負載測試:在一定的軟硬件環境下,利用增加虛擬用戶數實現對被測軟件增加負載,直到規定的性能指標或各項資源利用率超過預期目標。該方法可以找到軟件的最大承載能力,了解系統的性能容量。
3)壓力測試:在服務器CPU、內存處于飽和狀態下,測試軟件處理會話的能力、是否會出錯等。一般通過模擬負載實現服務器資源達到較高水平,測試軟件的穩定性。
4)配置測試:通過不斷對軟硬件的各項配置參數進行調整、測試、驗證,掌握軟件在不同環境中的運行效率,從而獲得最優的參數配置。可以用于探索軟件最大的性能潛力。
5)并發測試:測試較多用戶對軟件的同一個功能、同一個接口請求進行訪問時,軟件是否能正確響應。主要驗證軟件是否存在內存泄露、線程鎖或資源競爭等情況。
6)可靠性測試:檢驗軟件在一定的負載壓力下,是否可以持續、穩定的運行。測試時間2~3天,測試過程需隨時關注軟件各項性能指標、資源使用情況是否滿足要求。
7)失效恢復測試:主要針對采用了負載均衡、集群部署、分布式軟件設計,當其中一臺或者多臺服務發生故障時,軟件是否能正常被使用,且各項性能指標是否都滿足要求。
LoadRunner是一款廣泛應用于企業級軟件的性能測試工具,擁有良好的操作界面,可以通過模擬多虛擬用戶對軟件產生負載壓力。同時,還可以與開發工具進行持續集成,實時監控軟件性能測試過程中各項指標的運行情況,支持廣泛的協議和編程技術,適用于多種體系架構的軟件性能測試[9-11]。LoadRunner主要包括用戶腳本生成器、控制器和分析器三大組件[12],其工作原理如圖1所示。
1)用戶腳本生成器(Vugen,virtual user generator),用于捕捉用戶業務操作流并生成腳本。腳本記錄了用戶的操作,同時包含一系列用來監測軟件性能的函數,用戶可以對生成的腳本進行修改完善,來滿足實際性能測試工作的要求。
2)控制器(Controller),是整個軟件性能測試的控制中心,用來構造和維護性能測試場景,管理協調虛擬用戶在系統上的操作行為。同時,通過控制器將任務分派給負載生成器,并收集Vuser、服務器、軟件各項性能指標數據。
3)分析器(Analysis),將控制器收集的各項性能指標數據以圖表的形式進行展示并生成測試報告,供測試人員分析和性能調優。

圖1 LoadRunner工作原理
基于LoadRunner的軟件性能測試流程結合大部分軟件應用現狀,將測試流程分為規劃測試工程、設計測試工程和測試結果分析3個階段,每個階段細分多個工作流程。實現將復雜的測試過程簡單化、流程化,降低測試難度,提高測試效率,為軟件的性能測試過程和方法提供指導。基于LoadRunner的軟件性能測試流程如圖2所示。

圖2 基于LoadRunner的軟件性能測試流程
軟件性能測試通常是利用工具模擬大量用戶操作來驗證軟件能夠承受的負載情況,找出潛在的性能問題,并對問題進行分析、解決,是一項復雜度高、綜合性強的工作,可以將其定義為一項測試工程,在開始階段需對工程進行規劃,主要包括收集并分析性能需求、構建性能模型和制定測試計劃。
3.1.1 需求收集與分析
需求收集與分析主要是了解被測軟件的系統架構、業務流程、用戶特征,以及軟件的運行環境,確定軟件性能測試的目的和范圍,分析哪些業務納入性能測試范圍以及用戶期望的性能指標或測試終止標準,形成需求收集表。同時,還需要分析用戶使用行為、業務分布、業務量統計,并根據分析結果估算出TPS和并發用戶數等指標。
以淮安市“互聯網+不動產登記”一體化平臺項目為例,該平臺主要是面向全市450余萬用戶提供不動產登記業務線上辦理服務。業務需求收集示例表格對部分業務量、未來業務量、響應時間、事務通過率等進行了收集,如表1所示。

表1 業務需求收集示例
3.1.2 模型構建和制定測試計劃
在軟件性能測試過程中,構建性能模型類似編寫測試用例,主要是根據收集的性能需求和應用軟件的相關信息完成模型的構建,指導性能測試的實現和測試結果的輸出。軟件性能模型構建主要包括業務模型和測試模型[13-20]。
1)業務模型(BM,business model),指經過性能需求分析后,明確軟件的各個業務流程、業務相關功能在某個時間段內運行的業務種類及其業務占比,即哪些業務在哪個時間段運行、運行多久、業務量多少、并發用戶多少等。業務模型是構建測試模型的重要基礎,是性能測試關注的重點。
2)測試模型(TM,test model),從業務模型中分析和整理出來需要進行性能測試的業務,通常都是高頻業務、高資源占用的業務,這些業務需要具有可測性、可驗證性。測試模型作為性能測試場景設計的依據,通常會繼承業務模型的大多數業務功能,針對因特殊原因無法進行性能測試的(如第三方非開源加密程序,測試程序無法模擬),測試模型中會去掉這部分業務,或者設計替代的等價方案。以淮安市“互聯網+不動產登記”一體化平臺項目為例,部分測試模型如圖3所示。

圖3 測試模型示例
制定測試計劃的主要目的是用來規劃軟件性能測試工作,保證測試工作高效順利的進行,同時防范和抵御可能出現的各類風險,是正式開展性能測試工作的前提。測試計劃主要包括系統概述、測試環境、測試策略、測試場景、進度計劃等內容。同時還需明確人員安排、系統風險,對測試過程中可能涉及的風險加以評估,確定風險的應對策略,如人員風險可以通過加強人力儲備、采用AB角色、明確各自職責等來完成。
設計性能測試工程主要是利用LoadRunner組件完成測試腳本開發、數據準備、場景設計、執行與監控等工作,是基于LoadRunner的軟件性能測試流程的重要環節。該階段的目標是對測試工程的進一步實現和深化,同時輸出軟件各項指標記錄和報告,為后續性能調優提供數據基礎。
3.2.1 腳本開發與調試
LoadRunner提供了用戶腳本生成器(Vugen)組件,支持Web(HTTP/HTML)、Flex、SAPGUI等多種主流協議和JAVA、C語言、VB等多種編程語言進行測試腳本開發,可以根據系統架構設計選擇對應的協議,參考構建的性能模型完成腳本開發。開發完成后,需對腳本進行回放、調試,同時還可以添加集合點、參數化使腳本更加接近真實用戶操作,也可以插入事務和檢查點來判斷腳本在執行過程中系統是否能正確響應。
以用戶登入業務腳本為例,在腳本上方插入集合點lr_rendezvous(“login”),可以實現不同虛擬用戶在同一時間點執行登入操作,實現真正意義上的并發。在腳本上方添加開始事務lr_start_transaction(“PC_login”),在操作結尾添加結束事務和檢查點,根據響應碼判斷事務成功或失敗,通過該操作可以輸出在指定壓力測試下登入操作的成功率、平均響應時間等性能指標。
lr_rendezvous("login");
lr_start_transaction("PC_login");
web_reg_save_param("access_token","LB="access_token":"","RB=",",LAST);
web_custom_request("newLogin",
"URL=http://localhost/estateplat-register/v2/loginModel/newLogin",
"Method=POST",
"Resource=0",
"RecContentType=application/json",
"Referer=http://localhost/estateplat-register/page/v2.1/login.html",
"Snapshot=t2.inf",
"Mode=HTML",
"EncType=application/json;charset=UTF-8",
"Body={"head":{"origin":"2","sign":"
""data":{"lxDh":"
LAST);
web_reg_find("Search=Body","SaveCount=pass_login","Text=個人中心",LAST);
web_url("new_user_index_個人中心",
"URL=http://localhost/estateplat-register/page/v2.1/new_user_index",
"Resource=0",
"RecContentType=text/html",
"Referer=http://localhost/estateplat-register/page/v2.1/login",
"Snapshot=t9.inf",
"Mode=HTML",
if(web_get_int_property(HTTP_INFO_RETURN_CODE) 200){
lr_end_transaction("PC_login",LR_PASS);
}
else{
lr_end_transaction("PC_login",LR_FAIL);
}
3.2.2 數據準備
如何生成滿足軟件性能測試需要的大批量測試數據非常重要,因為在軟件的實際使用過程中,用戶可能會輸入各種各樣的數據進行操作,LoadRunner提供了多種數據生成方法,主要包括如下幾種:
1)數據生成池技術。在LoadRunner參數列表中,提供了多種數據類型生成技術,包括日期型、隨機數等,在測試腳本中插入定義的參數名或函數,并設置參數循環方式,在腳本回放時就可以自動從數據池取出數據,完成大批量數據測試工作[21-25]。
2)自定義數據文件。用戶可以將自己定義的數據文件(*.dat格式)保存在腳本文件夾下,并對其進行參數化,添加到腳本中。在腳本回放時就可以通過參數化讀取用戶自定義數據文件中的測試數據。
3)執行SQL腳本文件。通過LoadRunner提供的數據庫向導功能,編寫、執行SQL語句從指定的數據庫中批量選擇出滿足要求的測試數據并存儲在本地*.dat文件中,該方法是一種比較高效的測試數據批量生成方法。
在本文項目中,采用第三種方法生成測試數據,即通過執行SQL語句,從數據庫中獲取足夠多的且符合要求的測試數據,并保存至本地*.dat文件,為測試過程做數據準備。當數據庫中的數據量不足以滿足性能測試要求時,可以通過執行自動化腳本或編寫插入數據SQL等方式批量添加數據,當性能測試結束后,需對本輪測試所產生的數據進行清洗或重新恢復數據庫。
3.2.3 場景設計與實現
性能測試場景設計與實現是根據已構建的軟件性能模型設計出相應的測試場景,并利用LoadRunner控制器(Controller)組件,完成測試場景的實現。
1)場景設計:在構建軟件性能模型時已經確定了需要測試的業務種類,場景設計則是結合虛擬用戶,將這些業務種類組合到一個測試單元。以淮安市“互聯網+不動產登記”一體化平臺項目為例,根據收集的需求和構建的性能模型,設計出部分業務場景示例,如表2所示。

表2 場景設計示例
Sec_01基準測試:主要是用來驗證測試環境、測試腳本的正確性、得到軟件的性能基準,為后續的測試執行提供參考依據。基準測試采用單業務場景、單用戶方式來執行,執行時長根據響應時間來調整,測試結果采樣樣本盡量大。如響應時間為1 s,1 000個事務就需要運行1 000 s以上;響應時間200 ms,運行600 s就可以完成3 000個事務的采樣。
Sec_02配置測試:幫助分析軟件相關性能配置,確保軟件配置適合于當前性能需求,一般為綜合場景(多個業務同時執行)。測試過程是一個反復實驗的過程,先找出不合理的配置,然后進行修改、驗證,直到配置滿足要求為止。
Sec_03負載測試:負載測試的目的是找出軟件的性能問題,并對軟件進行定容定量,分析軟件性能變化趨勢,為軟件優化、性能調優提供數據支撐。負載測試分為單場景和綜合場景,單場景可以排除其他業務場景的干擾,有利于分析性能問題;綜合場景更接近用戶實際使用情況,可以對軟件進行綜合的性能評估。
2)場景實現:性能測試場景設計完成后,就可以利用Controller組件來實現具體場景。Controller支持手動場景(manual scenario)和面向目標的場景(goal-oriented scenario)兩種類型,手動場景是指完全由用戶設置每個腳本的虛擬用戶、運行時間等信息;面向目標的場景則是用戶提前設定好性能測試要達到的目標和虛擬用戶的增長模式,場景運行后,直到達到用戶設定的目標后停止。
以Sec_02配置測試為例,選擇手動場景,在Controller中添加測試腳本,設置每個腳本的虛擬用戶數量和行為方式,完成配置測試場景的實現。如圖4所示。

圖4 配置測試場景示例
3.2.4 執行與監控
場景設計與實現完成后,就可以在Controller中運行場景,對軟件進行性能測試,同時,實時監控場景運行情況、獲取虛擬用戶的運行狀態、收集測試結果。測試結果不僅包括平均事務響應時間、事務通過率、吞吐量等軟件性能指標,還包括數據庫性能狀態、JVM使用情況及服務器硬件性能指標,如CPU使用率、內存利用率、磁盤空間等,如表3所示。

表3 性能監控項目
結果分析是測試流程中的一個重要組成部分。場景運行結束后,Analysis組件會自動加載運行數據并生成各類圖表信息,包括虛擬用戶運行狀態、吞吐量、響應時間及硬件資源等。同時,還提供了圖表合并、分解、關聯等功能,可以將多個性能指標數據關聯后進行綜合分析,并確定測試結果是否滿足性能目標要求、是否需要進行性能調優等。
3.3.1 分析測試結果
性能測試結果分析是一項復雜度高且難度大的工作,需結合軟硬件環境、測試報告進行綜合分析,對測試人員綜合能力要求較高,其分析步驟主要包括如下:
1)首先查看性能測試整體運行狀況,收集運行日志信息,檢查運行過程中是否存在異常報錯,若存在,則需進一步分析并確定引起異常報錯的具體原因。
2)其次分析性能測試執行結果,查看響應時間、吞吐量、事務通過率、資源利用率等指標是否滿足性能要求,如圖5所顯示的是部分業務響應時間結果圖。若不滿足要求,則首先需對硬件環境進行排查,分析是否是硬件問題引起的性能瓶頸,硬件問題排除后,則需要對被測軟件本身進行分析,確定引起性能問題的具體原因。

圖5 平均事務響應時間
3.3.2 性能調優
針對不滿足性能需求的指標,需結合硬件、數據庫及被測軟件綜合分析存在的問題,提出解決方案,并進行性能調優。通常性能調優的方法包括空間換時間、時間換空間、并行、異步處理等,其中異步處理是指當業務鏈路上有任務耗時較長,可以拆分業務,甚至使用異步的方式減少阻塞影響,也就是常說的解耦。當性能調優完成后,還需對測試腳本進行更新,以滿足軟件調優后的實際情況,同時對軟件進行性能復測。
在軟件性能測試過程中,除了制定統一、標準化的測試流程外,還需對各個性能指標的度量進行統一,如并發用戶數、每秒事務數、吞吐量等。同時,在工具的應用過程中,為了使得測試結果更加準確和有效,還應結合被測軟件實際情況采用一些增強技術,如腳本參數化、腳本關聯。
并發用戶是指在軟件中操作業務,并對后臺服務器產生壓力的用戶,在性能測試工具中通常被稱為虛擬用戶(VU,virutal user)。并發用戶數是由軟件具體的業務場景來決定,因此,在計算并發用戶數前,需首先確定典型的業務場景、具體的性能需求、業務模型等,然后再根據并發用戶計算公式計算出每個業務場景的并發用戶數[26-30]。
(1)
(2)

示例:以淮安市“互聯網+不動產登記”一體化平臺項目為例,該軟件注冊用戶數為80萬,每天有1.5萬用戶訪問軟件進行各項操作,操作平均時間為0.5小時,該軟件每天對外開放時間為12小時。則根據式(1)和式(2)可以得到:
吞吐量是指單位時間內系統處理客戶請求的數量,直接體現軟件系統的性能承載能力。一般情況下,以不同計量單位來表達吞吐量的方式可以表明軟件受不同層次的制約。如以Bytes/Second和Pages/Second為單位表示的吞吐量主要是受網絡、服務器架構的制約;以Requests/Second為單位表示的吞吐量則主要是受應用服務器、軟件代碼邏輯的制約。
一般情況下,在軟件未遇到性能瓶頸時,吞吐量與并發用戶數之間存在一定的關聯關系,如圖6(a)所示,可以采用式(3)計算吞吐量:
(3)
其中:Fv是指吞吐量,Vu是指并發用戶數,R是指每個用戶的實際請求數量,T是指性能測試場景執行的時長。如果軟件遇到性能瓶頸,如圖6(b)所示,吞吐量與并發用戶數之間就不再存在關聯關系,不能通過式(3)進行計算。

圖6 吞吐量-運行Vuser
參數化是軟件性能測試過程中最常用的技術之一。在腳本錄制時,只是簡單記錄了一組固定從客戶端發送到服務端的數據,這并不符合實際軟件操作情況,同時也不滿足軟件性能測試大數據量的要求,因此就必須將這部分數據設為“參數”,并允許參數以某種方式和形式取值,在腳本運行時就可以通過預先設定的規則獲取不同的值。
如圖7所示,以辦件進度查詢業務為例。對腳本中slbh=2022012405262中的受理編號進行參數化,修改為slbh={slbh},同時在數據池中添加多組不同的受理編號數據,并按照一定規則賦值給slbh參數。當腳本回放時,slbh參數根據規則獲取不同的數據執行腳本,實現進度查詢業務的性能測試。

圖7 參數化示例
由于很多軟件架構都采用SessionID、SeqID等方法來標識不同的任務和數據包,軟件在每次運行時發送的數據并不完全相同。在這種情況下,為了讓腳本能夠滿足測試的要求,就需要對腳本進行關聯處理。
如圖8所示,以用戶登入業務為例。在腳本錄制時,客戶端首先向服務端發送login請求,服務端驗證口令正確后,返回一個以某種規則生成的SessionID,客戶端將sessionID=375825QW7作為URL的一部分提交服務端,服務端返回客戶端相應的信息。在腳本回放時,客戶端發送login請求后,服務端返回新的SessionID,而此時由于測試腳本中的SessionID是寫死的,客戶端會提交過期的SessionID,服務端驗證失敗后,返回會話失敗。

圖8 關聯示例
LoadRunner提供了手動和自動兩種關聯操作方式,并支持了一系列相關函數實現關聯操作。結合上文,需要對腳本進行關聯的條件是:客戶端需要獲取服務端返回的部分數據,并將這部分數據作為下一次請求的一部分發出。一般操作步驟如下:
1)從服務端返回的數據中選取需要進行關聯的數據;
2)將該數據存入腳本的一個參數中;
3)將腳本中需要使用到該參數的地方用參數來替代。
依據該流程對淮安市“互聯網+不動產登記”一體化平臺項目進行性能測試。以負載測試場景為例,對用戶登入業務分別按照200、400、600并發用戶進行負載測試,測試時間為30 min,部分測試結果如表4所示。

表4 負載測試用戶登入業務部分測試結果
測試結果分析顯示,針對該業務,隨著并發用戶的逐步增加,平均響應時間和事務通過率未發生明顯的變化,且均滿足目標要求。同時,系統吞吐量呈倍數遞增趨勢,表明系統在單位時間內處理客戶請求的能力表現良好,且存在進一步提升的空間。在該場景下,應用服務器的CPU使用率、內存利用率均在閾值范圍內,滿足用戶指標要求,如圖9所示。

圖9 用戶登入資源監控
在本項目中,利用該流程成功完成對淮安市“互聯網+不動產登記”一體化平臺的性能測試工作,包括基準性能測試、穩定性測試、可靠性測試及失效恢復性測試四部分,并出具多份規范性測試報告。本次項目實際應用的結果,不僅獲得用戶一致認可,也進一步確定了該流程方法的可行性和正確性。
本文結合目前軟件性能測試現狀,借助常用的軟件性能測試工具LoadRunner,提出了一種標準化的軟件性能測試流程。該流程將測試過程分為規劃測試工程、設計測試工程和結果分析3個階段,每個階段對應不同的工作模塊,如需求收集與分析、性能模型設計、場景設計與實現等。通過該流程,可以將復雜的測試過程簡單化、標準化,有效地降低了測試難度,提高了測試效率。同時,本文還在實際項目中應用該流程,解決了過去在軟件性能測試過程中存在較多冗余步驟、測試不規范等問題。最后,對流程中的關鍵難點分析研究,確定了并發用戶數、吞吐量等常用性能指標的計算方法。
目前,該流程已廣泛應用于不動產統一登記、自然資源一體化審批等相關軟件的性能測試中,反響良好。未來將不斷增加試點項目,優化流程設計,為各類企業的軟件性能測試提供更多參考。