自由,平等,開源,分享

            BlogJava :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
            2 Posts :: 61 Stories :: 3 Comments :: 0 Trackbacks

            隨著 Internet 的日益普及,現(xiàn)在基于 B/S 結(jié)構(gòu)的大型應(yīng)用越來越多,可如何對(duì)這些應(yīng)用進(jìn)行測(cè)試成為日益迫切的問題。有許多測(cè)試人員來信問我 B/S 的測(cè)試如何做,由于工作較繁忙,對(duì)大家提出的問題也是頭痛醫(yī)頭腳痛醫(yī)腳,沒有對(duì) Web 的測(cè)試過程做一個(gè)整體的概述。希望通過本篇能夠讓大家了解大型 Web 應(yīng)用是如何來進(jìn)行測(cè)試的。

            B/S 下的功能測(cè)試比較簡(jiǎn)單,關(guān)鍵是如何做好性能測(cè)試。目前大多數(shù)的測(cè)試人員認(rèn)為只要跑一些測(cè)試工具證明我的產(chǎn)品是可以達(dá)到性能的就 OK 了,為了證明而去測(cè)試是沒有任何價(jià)值的,關(guān)鍵是要發(fā)現(xiàn)產(chǎn)品性能上的缺陷,定位問題,解決問題,這才是測(cè)試要做的。

            首先我們從兩個(gè)方面分析如何進(jìn)行 Web 測(cè)試,從技術(shù)實(shí)現(xiàn)上來講一般的 B/S 結(jié)構(gòu),無論是 .NET 還是 J2EE,都是多層構(gòu)架,有界面層、業(yè)務(wù)邏輯層、數(shù)據(jù)層。而從測(cè)試的流程上來說,首先是發(fā)現(xiàn)問題,分析問題,定位問題,再由開發(fā)人員解決問題。那么 B/S 的結(jié)構(gòu)的測(cè)試如何來做呢?

            如何發(fā)現(xiàn)問題是我首先要介紹的,在做 Web 測(cè)試之前你需要一些資料,比如產(chǎn)品功能說明書,性能需求說明書,不一定很完善,但一定要有,明確測(cè)試目標(biāo),這是基本的常識(shí),可是我往往看到的是已經(jīng)開始動(dòng)手測(cè)了,但還不知自己的系統(tǒng)要達(dá)到的性能指標(biāo)是什么。這里我簡(jiǎn)單講一下測(cè)試的性能指標(biāo):

            通用指標(biāo)(指 Web 應(yīng)用服務(wù)器、數(shù)據(jù)庫(kù)服務(wù)器必需測(cè)試項(xiàng)):

              Processor Time:指服務(wù)器 CPU 占用率,一般平均達(dá)到 70% 時(shí),服務(wù)就接近飽和;
              Memory Available Mbyte:可用內(nèi)存數(shù),如果測(cè)試時(shí)發(fā)現(xiàn)內(nèi)存有變化情況也要注意,如果是內(nèi)存泄露則比較嚴(yán)重;
              Physicsdisk Time:物理磁盤讀寫時(shí)間情況。

            Web 服務(wù)器指標(biāo):

              Avg Rps:平均每秒鐘響應(yīng)次數(shù)=總請(qǐng)求時(shí)間/秒數(shù);
              Avg time to last byte per terstion(mstes):平均每秒業(yè)務(wù)角本的迭代次數(shù),有人會(huì)把這兩者混淆;
              Successful Rounds:成功的請(qǐng)求;
              Failed Rounds:失敗的請(qǐng)求;
              Successful Hits:成功的點(diǎn)擊次數(shù);
              Failed Hits:失敗的點(diǎn)擊次數(shù);
              Hits Per Second:每秒點(diǎn)擊次數(shù);
              Successful Hits Per Second:每秒成功的點(diǎn)擊次數(shù);
              Failed Hits Per Second:每秒失敗的點(diǎn)擊次數(shù);
              Attempted Connections:嘗試鏈接數(shù)。

            數(shù)據(jù)庫(kù)服務(wù)器指標(biāo):

              User 0 Connections:用戶連接數(shù),也就是數(shù)據(jù)庫(kù)的連接數(shù)量;
              Number of deadlocks:數(shù)據(jù)庫(kù)死鎖;
              Butter Cache hit:數(shù)據(jù)庫(kù) Cache 的命中情況。

            上面的指標(biāo)只是一些通用的指標(biāo),起到拋磚引玉的作用,對(duì)于不同的應(yīng)用你還必需作相應(yīng)的調(diào)整,比如程序使用的是 .NET 技術(shù)的,則必需加入一些針對(duì)性的測(cè)試指標(biāo)。對(duì)于這些指標(biāo)的詳細(xì)了解,你可以參考 Windows 下面的 SystemMonitor 的幫助與 LoadRunner、ACT 的幫助。對(duì)于發(fā)現(xiàn)問題,指標(biāo)的設(shè)置非常重要,它會(huì)幫你定性的發(fā)現(xiàn)一些錯(cuò)誤。對(duì)于定性的壓力測(cè)試我就不做過多的分析,工具很多,流行的主要有 LoadRunner、ACT、WAS、WebLoad 各個(gè)工具有它的使用范圍;其中我各個(gè)認(rèn)為:

              LoadRunner 最全面,它提供了多種協(xié)議的支持,對(duì)復(fù)雜的壓力測(cè)試都可以勝任;
              WAS 與 ACT 則對(duì)微軟的技術(shù)支持的比較好,其中 WAS 支持分布式機(jī)群測(cè)試;
              ACT 則是與 .NET 集成比較好,支持 ViewState(.NET 下控件緩存的支持)的測(cè)試。

            在這一階段測(cè)試你要不斷的跟據(jù)系數(shù)的測(cè)試目標(biāo)進(jìn)行變化,一開始由于系統(tǒng)過于龐大,所以我們要分成若干個(gè)子系統(tǒng),各個(gè)子系統(tǒng)的性能目標(biāo)必需明確,主要是并發(fā)指標(biāo)定一個(gè)閾值,同時(shí)設(shè)定一些與系統(tǒng)相關(guān)的測(cè)試參數(shù),應(yīng)用服務(wù)器,數(shù)據(jù)庫(kù)服務(wù)器都要有,對(duì)達(dá)不到閾值的與一些通用參數(shù)有問題的子系統(tǒng)進(jìn)行深入分析。比如它的并發(fā)達(dá)不到你的要求,證明子系統(tǒng)性能有問題,或是數(shù)據(jù)庫(kù)用戶連接過高,程序沒有釋放用戶連接等等。這個(gè)我們要對(duì)子系統(tǒng)進(jìn)行詳細(xì)測(cè)試,由于 B/S 結(jié)構(gòu)下,圖片的請(qǐng)求對(duì)性能的影響較大,所以我們對(duì)子系統(tǒng)測(cè)試時(shí)要分兩個(gè)部分進(jìn)行:

              非程序部分,即圖片等等;
              應(yīng)用程序本身。

            通過事務(wù)或函數(shù)的分離,可以把這兩塊實(shí)現(xiàn)單獨(dú)的測(cè)試,具體做法參考各個(gè)工具的手冊(cè),我這里就不做說明。對(duì)子系統(tǒng)的測(cè)試參數(shù)的設(shè)置要求則更高,它有助你后面精確的定位問題,比如對(duì)異常、死鎖、網(wǎng)絡(luò)流量等等前面沒有注意到的情況的增加;同時(shí)你要注意增加測(cè)試參數(shù)的收集對(duì)系統(tǒng)的性能影響比較大,所以一般不要超過 10 個(gè)。剛剛介紹的整體的性能測(cè)試指標(biāo)也不要增加很多,這樣影響會(huì)小一點(diǎn)。最后在這一階段要說明的是數(shù)據(jù)庫(kù)的數(shù)據(jù)量會(huì)很大程度的影響性能,所以要根據(jù)前面的性能需求說明書向數(shù)據(jù)庫(kù)中模擬相應(yīng)的數(shù)據(jù)量,來進(jìn)行測(cè)試,這樣才有更高的可信度。

            上面所說的是對(duì)問題的發(fā)現(xiàn),下面就是分析問題原因,這一步的要求比較高,一般由測(cè)試人員與程序員配合完成,當(dāng)然如果你有相當(dāng)?shù)拈_發(fā)經(jīng)驗(yàn),再做這方面的測(cè)試,就更為難得。下面我們說說如何精確定位問題,出現(xiàn)問題的可能性可能有很多種,大致分以下幾種:

              性能達(dá)不到目標(biāo);
              性能達(dá)到目標(biāo),但有一些其它的問題,比如異常、死鎖。緩存命中過低,網(wǎng)絡(luò)流量較大;
              服務(wù)器穩(wěn)定性的問題,比如內(nèi)存泄漏等。

            發(fā)現(xiàn)這些問題起馬的要求要有一款使用的比較稱心的性能分析與優(yōu)化工具,比如微軟的 .net 下就有自己開發(fā)的工具,對(duì) Borland 的 Java 開發(fā)工具中也有類似的工具,但我個(gè)人認(rèn)為更好的工具是 Rose 下的 Purify 與 Quantify,主要是他對(duì).net 與 Java、C++ 都有支持,而且分析效果特別專業(yè)。我們先了解一下 Rational Purify。

            Rational Purify 能自動(dòng)找出 Visual C/C++ 和 Java 代碼中與內(nèi)存有關(guān)的錯(cuò)誤,確保整個(gè)應(yīng)用程序的質(zhì)量和可靠性。在查找典型的 Visual C/C++ 程序中的傳統(tǒng)內(nèi)存訪問錯(cuò)誤,以及 Java,C# 代碼中與垃圾內(nèi)存收集相關(guān)的錯(cuò)誤方面;Rational Quantity 則是一款針對(duì)函數(shù)級(jí)的性能分析利器,使用它你可以從圖形化的界面中得到函數(shù)調(diào)用的時(shí)間,百分比與次數(shù),以及子函數(shù)所占時(shí)間,使你可以更快的定位性能瓶頸。

            我們先說性能優(yōu)化與異常的處理,性能優(yōu)化有一個(gè)原則,即用時(shí)間比例最大的進(jìn)行優(yōu)化,效果才最明顯。比如有個(gè)函數(shù)它的執(zhí)行時(shí)間為 30 秒,如果你優(yōu)化了一百倍則執(zhí)行時(shí)間為 0.3 秒,提升了 29.7 秒;而如果它的執(zhí)行時(shí)間為 0.3 秒,優(yōu)化后為 0.003 秒,實(shí)際提升了 0.297 秒,提升的效果并不明顯但寫過程序的人都知道,后者性能優(yōu)化的代價(jià)更大。

            在性能優(yōu)化的過程中,一般是先數(shù)據(jù)庫(kù),后程序。因?yàn)閿?shù)據(jù)庫(kù)的優(yōu)化不需要修改程序,修改的風(fēng)險(xiǎn)很小。但如何才能確定是數(shù)據(jù)庫(kù)的問題,這就需要技巧,在使用 Quantity 時(shí),你一路分析下去,大多數(shù)最終會(huì)發(fā)現(xiàn),是數(shù)據(jù)庫(kù)查詢函數(shù)占用時(shí)間比較大,比如什么 SqlCmd.ExecuteNoQuery 等等數(shù)據(jù)庫(kù)執(zhí)行函數(shù),這時(shí)你就需要分析數(shù)據(jù)庫(kù)。

            數(shù)據(jù)庫(kù)的分析原則是先索引,后存儲(chǔ)過程,最后表結(jié)構(gòu)視圖的優(yōu)化。索引的優(yōu)化是最簡(jiǎn)單也是通常最有效的方法,如果合理的使用會(huì)帶來意想不到不到的效果。在這里我要給大家簡(jiǎn)單的介紹一下我的最愛:SQLProfile、SQL 查詢分析器。

            Precise SQLProfile 是一個(gè) SQL 語句跟蹤器,可以跟蹤程序流程使用的 SQL 語句與存儲(chǔ)過程,結(jié)合查詢分析器對(duì) SQL 的分析,可以對(duì)索引的優(yōu)化做出很好的判斷,但索引也不是萬能的,在增刪改較多的表,索引過多會(huì)引起這些操作的性能下降,所以判斷還是需要一定的經(jīng)驗(yàn)。同時(shí)針對(duì)用戶使用頻度最高的 SQL 進(jìn)行優(yōu)化也是最行之有效的,這時(shí)我則需要 Precise,它可以觀測(cè)某一個(gè)較長(zhǎng)時(shí)間內(nèi)的 SQL 語句的執(zhí)行情況。

            數(shù)據(jù)庫(kù)優(yōu)化的潛能挖光后,如果還是達(dá)不到性能要求或是還有問題,則要從程序來進(jìn)行優(yōu)化,這是程序員做的事。測(cè)試人員要做的,就是告訴他們,哪個(gè)函數(shù)執(zhí)行過多引起了性能下降,比如異常過多,某個(gè)循環(huán)過多,或是 DCOM 調(diào)用過多等等,但說服程序員也是一件不容易的事,你要在這一階段做的出色一定要有幾年的編程經(jīng)驗(yàn),并且要讓程序員感到聽你的性能會(huì)有提升,這是一件很不容易的事情哦。

            內(nèi)存的分析,一般是一個(gè)長(zhǎng)期分析的過程,要做好不容易,首先要有長(zhǎng)期奮戰(zhàn)的準(zhǔn)備,其次內(nèi)存泄漏的分析最好是放在單元測(cè)試之中同步進(jìn)行,而不是要等到最后再去發(fā)現(xiàn)問題,當(dāng)然出了問題也只好面對(duì),一般這類問題都是在服務(wù)器運(yùn)行了很久才暴露出來,一旦發(fā)現(xiàn)問題后,則需要定位問題,分析的原則采用子系統(tǒng)相互獨(dú)立運(yùn)行,找到最小問題的系統(tǒng)集,或是借助內(nèi)存分析工具觀察內(nèi)存對(duì)象情況,初步定位問題,再用 Purify 進(jìn)行運(yùn)行時(shí)分析,通常 C++ 內(nèi)存問題比較多, Java 與 .NET 比較少,一般由 GC 不合理引起。C++ 的內(nèi)存錯(cuò)誤就比較多了,主要常見的有:

              Array Bounds Read(ABR):數(shù)組越界讀
              Array Bounds Write(ABW):數(shù)組越界寫
              Beyond stack Read(BSR):堆棧越界讀
              Free Memory Read(FMR):空閑內(nèi)存讀
              Invalid pointer Read(IPR):非法指針閱讀
              Null Pointer Read(NPR): 空指針閱讀
              Uninitialized Memory Read(UMR):未初始化內(nèi)存讀寫
              Memory Leak:內(nèi)存泄漏

              注:如果需要更多的信息,可以參見 Purify 的幫助信息。

            順便提一句,為什么我要說做單元測(cè)試時(shí)做內(nèi)存分析比較好,由于單元測(cè)試針對(duì)的是單一功能,這時(shí)結(jié)合單元測(cè)試案例做內(nèi)存分析會(huì)更快的定位問題,同時(shí)由于問題較早的發(fā)現(xiàn),則后期的風(fēng)險(xiǎn)則會(huì)減少,當(dāng)然如果結(jié)合代碼覆蓋工具 PureCoverage 來做就更完美了。

            注:本篇只是對(duì) B/S 應(yīng)用的測(cè)試過程作一個(gè)整體的描述,對(duì)某一個(gè)階段使用的工具只是作大概的介紹,你也可使用你比較熟悉的工具達(dá)到相同的目標(biāo)。

          posted on 2008-06-04 17:19 龍震 閱讀(651) 評(píng)論(0)  編輯  收藏 所屬分類: 用軟

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 手游| 蓝田县| 镇坪县| 垦利县| 大足县| 永新县| 墨江| 信宜市| 陕西省| 大安市| 星子县| 水富县| 琼中| 枣阳市| 浠水县| 南岸区| 志丹县| 德州市| 吉安县| 太湖县| 常宁市| 都江堰市| 吉木乃县| 清原| 舟曲县| 西昌市| 青州市| 呼玛县| 沐川县| 伊川县| 高尔夫| 武夷山市| 府谷县| 玉山县| 姚安县| 额尔古纳市| 凤冈县| 称多县| 库尔勒市| 屏东县| 辉南县|