1、? 背景

本次性能測試的系統(tǒng)是X銀行營銷服務(wù)系統(tǒng)總行版,該系統(tǒng)使用的數(shù)據(jù)庫服務(wù)器、應(yīng)用服務(wù)器均布署在總行機(jī)房,各地分行通過 WEB 方式登錄訪問本系統(tǒng)。系統(tǒng)上線后的總用戶數(shù)(包括各分行、支行主管,客戶經(jīng)理等)在 5000 左右。

該系統(tǒng)采用 DB2 數(shù)據(jù)庫、 WebLogic 應(yīng)用服務(wù)器。

本次性能測試進(jìn)入的條件是系統(tǒng)的代碼已經(jīng)基本完成并經(jīng)過功能測試。

2、? 測試計劃

在確定了本次性能測試的要點后,我們初步擬定一份性能測試計劃,提交給客戶,并獲得了客戶的認(rèn)可。在本文中不列出項目測試計劃中的所有內(nèi)容,僅就主要問題進(jìn)行說明。

測試范圍:在真實業(yè)務(wù)局域網(wǎng)測試環(huán)境下,對系統(tǒng)實施并發(fā)性能測試的同時,監(jiān)控 Web 服務(wù)器和數(shù)據(jù)庫服務(wù)器的系統(tǒng)資源,以及數(shù)據(jù)庫資源的使用情況。

測試內(nèi)容:并發(fā)性能測試、系統(tǒng)資源監(jiān)控。

測試方法與工具:采用自動測試與人工測試相結(jié)合的測試方法,測試工具使用 LoadRunner

測試資源:測試環(huán)境及測試數(shù)據(jù)準(zhǔn)備。

3、? 測試用例

確定了測試計劃,我們針對該系統(tǒng)的特點,從中挑選出三個有代表性的功能點,作為本次性能測試的用例。我們認(rèn)為作為銀行的營銷服務(wù)系統(tǒng),最常使用且對于系統(tǒng)的整體性能有著較大影響的是“客戶信息查詢”和“客戶對賬單查詢”兩個模塊。因此,我們設(shè)計了三個單交易性能測試用例,分別是:“用戶簽到 / 簽退”、“客戶信息查詢”、“客戶對賬單查詢”。然而客戶卻對此提出異議,他們認(rèn)為我們設(shè)計的測試用例數(shù)量太少,要求我們的測試用例應(yīng)包含更多的功能模塊。經(jīng)過會議討論,最終我們根據(jù)客戶給出的一份性能測試大綱,針對其中提出的測試內(nèi)容、測試策略,以及測試目標(biāo),將單交易測試用例增加到十四個。

測試用例采用以下格式:

案例名稱

并發(fā)

用戶數(shù)

數(shù)據(jù)量

操作步驟

備注

?????? 要求清晰地描述出詳細(xì)的操作步驟。

4、? 測試數(shù)據(jù)

針對以上設(shè)計的測試用例,需要準(zhǔn)備大量的業(yè)務(wù)數(shù)據(jù)。本次性能測試的環(huán)境即系統(tǒng)上線后真實運行的環(huán)境,所有的業(yè)務(wù)數(shù)據(jù)均來自興業(yè)銀行的真實核心系統(tǒng)(通過 ETL 轉(zhuǎn)換),數(shù)據(jù)量已經(jīng)能滿足測試的需要。

由于測試用例中要求執(zhí)行并發(fā)操作的時候使用不同身份的用戶登錄系統(tǒng),因此在測試開始前需要準(zhǔn)備一批具有不同身份的用戶名(包括各分支行的主管以及客戶經(jīng)理),并且要有相應(yīng)的操作權(quán)限。

對于“積分轉(zhuǎn)移”、“積分兌換”、“禮品兌換”等等交易,則需要提供一批卡上有足夠積分的客戶理財卡號。

以上測試數(shù)據(jù)由興業(yè)銀行負(fù)責(zé)提供,在性能測試執(zhí)行之前提供給我們。

5、? 測試腳本

使用性能測試工具 LoadRunner 錄制并調(diào)試測試腳本,對相關(guān)的輸入項進(jìn)行參數(shù)化。

6、? 測試實施

LoadRunner 中執(zhí)行測試腳本,實施性能測試。對于每個單交易測試腳本各執(zhí)行一輪測試,并按一定的用戶比例設(shè)計出一個混合交易場景,令其自動持續(xù)運行五小時左右,觀察系統(tǒng)的性能表現(xiàn)。每次執(zhí)行的結(jié)果文件均保存下來,待測試完成后連同性能測試報告一并交付客戶確認(rèn)。在此過程中,需要監(jiān)視相關(guān)的系統(tǒng)資源使用情況,包括:應(yīng)用服務(wù)器和數(shù)據(jù)庫服務(wù)器的所有系統(tǒng)資源指標(biāo),所有數(shù)據(jù)庫資源指標(biāo)。

7、? 測試結(jié)果

經(jīng)過本次性能測試,發(fā)現(xiàn)了系統(tǒng)五個主要的性能問題。我們與程序開發(fā)人員一同分析問題產(chǎn)生的原因,并給出改進(jìn)建議,一起記錄到測試報告中。其中的一個問題在性能測試報告提交客戶之前已經(jīng)過優(yōu)化,得到顯著改進(jìn)。

8、? 測試結(jié)論

測試結(jié)果顯示,系統(tǒng)性能能滿足測試目標(biāo), 交易并發(fā)數(shù)達(dá)到或超過30個,批量交易(查詢記錄50條以上的交易)并發(fā)數(shù)也能達(dá)到或超過10個,交易平均響應(yīng)時間在212秒內(nèi),90%平均響應(yīng)時間在215秒間完成。

混合交易案例持續(xù)運行 5 小時,運行結(jié)果正常,系統(tǒng)沒有報任何錯誤,系統(tǒng)穩(wěn)定, 可用率應(yīng)達(dá)到100

另外如在ETL批處理期間運行 營銷服務(wù)系統(tǒng) ,系統(tǒng)性能明顯下降,建議ETL批處理在夜間處理,避免影響 系統(tǒng)的正常運行

9、? 經(jīng)驗

在本次性能測試的過程中,我們遇到一些問題,通過解決這些問題,從中獲得了一些經(jīng)驗。現(xiàn)總結(jié)如下:

l???????? 問題一

在我們對系統(tǒng)進(jìn)行測試的過程中,某些操作是相關(guān)聯(lián)的。例如我們測試“查看客戶資產(chǎn)歷史”這個交易的系統(tǒng)響應(yīng)時間,這時需要先列出客戶的基本信息,選中一個客戶,點擊打開另一個頁面,才能查看到該客戶的資產(chǎn)歷史信息,同時,在測試腳本中需要對所選擇的客戶編號做一個參數(shù)化,但由于 LoadRunner 不提供像 WinRunner QTP 一樣識別頁面對象的功能,如果在 Vugen 中直接抓取頁面上顯示的客戶編號去參數(shù)化,實現(xiàn)起來將十分煩瑣。考慮到在以上那兩步操作中,第一步“列出客戶基本信息”只是輔助的操作,而第二步操作“查看客戶資產(chǎn)歷史”才是我們要測試的功能點,因此我們忽略了這二者之間的關(guān)聯(lián)性,僅對第二步操作中的客戶編號進(jìn)行參數(shù)化。(只要服務(wù)器端對此不加驗證,甚至我們將第一步操作都忽略掉,也是可行的)。

結(jié)論: LoadRunner 的工作原理是根據(jù)所選擇的協(xié)議組裝成相應(yīng)的報文在前后臺之間通訊,以此達(dá)到模擬實際操作的目的,因此我們只需將要測試的交易或功能點所需要組裝的報文傳送給后臺服務(wù)器即可(因為我們關(guān)注的只是系統(tǒng)的性能,不是功能),而不必像功能測試那樣,按部就班地重現(xiàn)每一步操作。

l???????? 問題二

在測試過程中,我們發(fā)現(xiàn)有一個查詢交易的系統(tǒng)響應(yīng)速度特別慢,無論是在 Controller 中使用單個虛擬用戶執(zhí)行腳本,還是在 Vuser 中直接運行,情況均是如此,然而當(dāng)我們用手工進(jìn)行同樣操作的時候,響應(yīng)時間卻明顯地小于工具統(tǒng)計出來的時間,也就是說,在 LoadRunner 中模擬操作的結(jié)果與真實操作的結(jié)果明顯不一致。經(jīng)過反復(fù)嘗試與觀察,我們才終于找到問題的原因所在:該查詢交易是通過客戶的證件號碼查詢客戶信息,當(dāng)用戶輸入客戶的證件號碼時,如果沒有選擇證件類型,系統(tǒng)會自動將證件類型設(shè)置為默認(rèn)值“身份證”。按“證件類型 + 證件號碼”為組合索引查詢客戶信息表,查詢速度極快,而在我們錄制腳本時,忽視了“證件類型”這項輸入,只有“證件號碼”,因此查詢的效率大為降低。解決辦法:只需在測試腳本中,對 CertType (“證件類型”)一項賦值為“ A ”(“身份證”),此時在 LoadRunner 中重新運行該腳本,響應(yīng)速度提高,統(tǒng)計結(jié)果與實際完全一致!

結(jié)論: LoadRunner 的工作原理是根據(jù)所選擇的協(xié)議組裝成相應(yīng)的報文在前后臺之間通訊,以此達(dá)到模擬實際操作的目的,因此我們在測試腳本中組裝發(fā)送到服務(wù)器端的報文時,注意一定要和實際操作時的發(fā)送報文完全一致,這樣才能保證測試的結(jié)果與真實情況相吻合。這就要求在測試正式開始執(zhí)行時,要對測試腳本進(jìn)行反復(fù)的調(diào)試,通常的做法是:在 Vugen 中執(zhí)行一遍腳本,統(tǒng)計執(zhí)行某個事務(wù)的時間,再用手工實際做一遍同樣的操作,大體上比較一下,確保與實際估算的時間沒有太大出入后,再逐漸增加并發(fā)用戶數(shù),正式開始性能測試。

l???????? 問題三

在我們的每個測試腳本中的 init 部分,都錄制了登錄系統(tǒng)的操作,并且對登錄的用戶名進(jìn)行了參數(shù)化,使用各種不同身份的用戶(分行主管、支行主管、客戶經(jīng)理等)進(jìn)行相同的操作。在并發(fā)測試過程中發(fā)現(xiàn)對某些查詢交易測試的結(jié)果波動較大,系統(tǒng)響應(yīng)時間從零點幾秒到幾十秒不等。經(jīng)檢查后發(fā)現(xiàn)原因在于:使用不同身份的用戶登錄系統(tǒng)后,在輸入查詢條件后,點擊查詢按鈕后會將根據(jù)該用戶的身份,將其所屬的分行機(jī)構(gòu)號、支行機(jī)構(gòu)號、客戶經(jīng)理編號等一并提交,因此在腳本中,就必須根據(jù)不同的用戶身份,分別將其對應(yīng)的分支行機(jī)構(gòu)號等也運用參數(shù)提交,否則在執(zhí)行腳本時就會出現(xiàn)查詢不到記錄或查詢速度變慢等各種問題。解決方法有三個: 1 、修改腳本,使其能夠依據(jù)用戶的身份分別傳送相應(yīng)參數(shù), 2 、針對不同類型的用戶使用不同的腳本分別測試。 3 、輸入?yún)?shù)使用統(tǒng)一的用戶類型。在實際中,我們?yōu)榱撕喕_本的復(fù)雜度,節(jié)省對腳本編程的時間,采取的是第三種方法。

結(jié)論:由于 LoadRunner 的工作原理是根據(jù)所選擇的協(xié)議組裝成相應(yīng)的報文在前后臺之間通訊,因此它會跳過在應(yīng)用程序前臺進(jìn)行的校驗,所以在腳本回放的時候一定要注意在腳本中提前進(jìn)行這些校驗或改由人工控制,以保證發(fā)送報文的正確性(如操作權(quán)限的控制等)。

l???????? 問題四

測試多用戶并發(fā)登錄系統(tǒng)的時候,從虛擬用戶圖和事務(wù)圖上發(fā)現(xiàn),總有一部分用戶在登錄的時候要等待很長時間,用戶登錄的最小時間與最大時間相差非常大。于是我們在讓腳本自動運行的同時,手工再登錄一個用戶,發(fā)現(xiàn)無論如何都不會發(fā)生等待的情況,多次試驗的結(jié)果均是如此,也就是說 LoadRunner 測試的結(jié)果與實際結(jié)果再次發(fā)生了偏差!經(jīng)過反復(fù)的調(diào)試,以及與程序開發(fā)人員溝通,我們終于發(fā)現(xiàn)問題的原因所在:在用戶登錄系統(tǒng)的時候,系統(tǒng)會自動記錄登錄用戶的信息,并產(chǎn)生一個登錄 ID ,以此 ID 做為主鍵,向數(shù)據(jù)庫插入記錄。因此當(dāng)大量用戶在極短的時間內(nèi)同時登錄時,就有可能出現(xiàn)生成相同的登錄 ID 的情況,此時便會造成數(shù)據(jù)庫中的主鍵沖突,導(dǎo)致用戶等待很長時間或登錄失敗。而我們手工測試時卻無法做到在很短的時間內(nèi)同時登錄,因此很難用手工重現(xiàn)此種情況。通過 LoadRunner 的模擬表現(xiàn)出來的狀況,正是我們測試出程序存在的性能問題,并非與實際結(jié)果的偏差。

還有一個例子,在第二輪性能測試中,同樣發(fā)生了類似的情況。在本系統(tǒng)中,如果同一個用戶登錄后,未正常退出超過 5 次,系統(tǒng)將會把該用戶鎖住,使其無法再次登錄,而我們用于參數(shù)化的用戶名個數(shù)有限,因此當(dāng)腳本使用大量用戶同時登錄時,很容易造成同樣的用戶登錄系統(tǒng)而未簽退的情況發(fā)生(腳本正在執(zhí)行,還未能退出),此時將會造成許多用戶操作的失敗。

結(jié)論:使用 LoadRunner 可以模擬出大量用戶同時對系統(tǒng)操作的情況,而這些情況通過手工往往是很難重現(xiàn)出來的。例如大量用戶在同時對系統(tǒng)做某些操作時,很容易造成數(shù)據(jù)庫的死鎖、鎖等待、主鍵沖突、數(shù)據(jù)混亂等等問題,因此在做性能測試的同時,也常常可以連帶測試出系統(tǒng)的一些隱蔽的“缺陷”。在本次性能測試中,這種例子是很多的。對待此類“缺陷”,應(yīng)具體情況具體分析。有些確實是程序的 BUG ,需要修正,而有些可能只是很極端的情況,只有在做壓力測試時才有可能發(fā)生,可不必深究。

l???????? 問題五

此問題發(fā)生在第二輪測試(即回歸測試)中。在第一輪測試中發(fā)現(xiàn)的性能問題,經(jīng)程序員修正后,我們對系統(tǒng)進(jìn)行了第二輪性能測試,以驗證其性能改進(jìn)的效果。在前一輪測試中,我們發(fā)現(xiàn)通過選擇客戶級別為“未評級”時,查詢的速度極慢,經(jīng)過改進(jìn)后,速度應(yīng)有較大提高。然而在回歸測試中,卻依然很慢。經(jīng)過對測試腳本和程序的仔細(xì)檢查,才發(fā)現(xiàn)原來在程序中已將“未評級”這個選項去除,而我們的測試腳本的參數(shù)文件中仍然保留有該選項,因此測試的結(jié)果與前次沒有區(qū)別。在參數(shù)文件中將該選項去掉后,測試結(jié)果正常,查詢效率有所提高。

結(jié)論:使用錄制好的測試腳本進(jìn)行回歸測試之前,一定要先仔細(xì)檢查、了解程序的改動,對原先的測試腳本做必要的修改后,才可以重新測試,否則只是在做無用功。

10、????????????? 教訓(xùn)

在本次測試過程中,由于經(jīng)驗不足,我們也得到了一些教訓(xùn)。前事不忘,后事之師,現(xiàn)總結(jié)出來與大家分享。

l???????? 與客戶的溝通做得不夠,客戶要求我們做的性能測試用例數(shù)量太多,我們未能據(jù)理力爭,最后導(dǎo)致工作量過大。

l???????? 按照原定的項目計劃,我們要在系統(tǒng)的功能測試即將結(jié)束前進(jìn)駐項目組,準(zhǔn)備并進(jìn)行性能測試。然而由于客戶在功能測試的后期仍然不斷的提出新需求,導(dǎo)致開發(fā)人員疲于奔命,系統(tǒng)的性能難以穩(wěn)定下來,性能測試的前期準(zhǔn)備工作也受到很大影響,不能正常開展,浪費了很多人力物力。

l???????? 由于客戶無法提供一個單獨的性能測試環(huán)境,我們的性能測試工作與業(yè)務(wù)組的功能測試在同一個環(huán)境下進(jìn)行,而系統(tǒng)的功能測試遲遲未能完成,加上 ETL (數(shù)據(jù)轉(zhuǎn)換)小組對數(shù)據(jù)庫資源的占用,因此我們的性能測試只能在夜間才能進(jìn)行。導(dǎo)致時間上的浪費,使項目的成本增加。

l???????? 沒有將性能測試中發(fā)現(xiàn)的缺陷記錄到缺陷管理工具中加以跟蹤,而僅僅體現(xiàn)在最后的測試報告上,個人認(rèn)為這是比較不規(guī)范的做法。

l???????? 性能測試前的數(shù)據(jù)準(zhǔn)備不夠充分。客戶提供測試的系統(tǒng)用戶、身份數(shù)量有限,導(dǎo)致許多案例的測試只能使用少量數(shù)據(jù)進(jìn)行參數(shù)化,由此帶來許多本可以避免的問題。

l???????? 測試計劃及測試報告的書寫格式缺乏規(guī)范,尤其測試計劃書未能包含本應(yīng)包含的所有內(nèi)容。

l???????? 在我們將 LoadRunner 的測試結(jié)果文件全部提交給客戶的前提下,客戶仍然要求我們在測試報告中將每一次測試的數(shù)據(jù)均以表格的形式填至測試報告中,此項工作的工作量十分巨大,個人認(rèn)為這樣做并無必要。

以上是在本次性能測試及回歸測試過程中總結(jié)出來的一些經(jīng)驗教訓(xùn),在此做一個小小的總結(jié),以便下次工作中改進(jìn)。