Visual Studio進行Web性能測試


【轉http://www.cnblogs.com/vowei/archive/2012/08/29/2661306.html

 

原文作者:Ambily.raj

Visual Studio是可以用於性能測試的工具之一。Visual Studio Test版或Visual Studio 2010旗艦版為自動化測試提供了支持。本文介紹Visual Studio的Web測試功能。

介紹

對於一個多用戶的應用程序,性能是非常重要的。性能不僅是執行的速度,它包括負載和並發方面。性能測試是對以下問題的回答:

  • 我們如何確保我們的新的應用程序將支持預期的用戶負載?
  • 如何避免在實際負載條件下會出現的問題?
  • 如何確定響應時間?
  • 如何規划服務器的容量?

Visual Studio是可以用於性能測試的工具之一。Visual Studio Test版或Visual Studio 2010旗艦版為自動化測試提供了支持。

 

這將是第一部分的一系列文章。

  • Part I: Web測試和配置

  • Part II:負載測試,RIG和負載測試術語。

  • Part III:性能計數器,負載測試結果分析。

 

VS 2010測試類型

Visual Studio支持多種可用於執行自動化測試的測試類型。圖1顯示了VSTS 2010中的主要測試類型。

Basic Unit Test,Unit TestUnit Test Wizard幫助創建新的單元測試的類文件。這將有助於開發人員和測試人員執行單元測試。

Coded UI test用於從手工測試中錄制UI活動。

Database Unit Test用於測試存儲過程和函數。

Generic Test用於把一個可執行文件封裝成一個測試方法。您可以把一個可執行文件封裝成一個測試方法並把它包含在自動化測試中。

Ordered test是在一個特定的順序中執行多個測試腳本。

Web Performance Test用於錄制URL並生成用於性能測試的代碼。

 

Web測試

Web Performance Test或者Web test,可以執行Web應用程序測試。我們將通過選擇從測試項目模板創建一個測試項目。

 

一旦你創建好測試項目,右鍵單擊該項目,並添加新的項。選擇Web Performance Test,這將在Internet Explorer中打開錄制器,並開始錄制URL和相關參數。

 
錄制

下圖顯示了Web測試錄制器,錄制在google上的操作。

在這個例子中,我們記錄到谷歌的搜索功能。一旦錄制結束,在Web測試錄制器中使用“停止”按鈕停止錄制。這將把錄制的URL生成一個Web測試,並添加動態的相關性。

 
相關性(Correlation)

什么是相關性,簡而言之就是上一次Web請求的響應和下次請求之間的關聯。

例如,當你登錄網站時,它會生成一個用於跟蹤會話的SID。登錄后,這SID被傳遞給了客戶端。隨着下一個請求,存儲的SID將被發送到服務器。當您使用Web測試錄制這一操作時,它會記錄這個值並硬編碼保存。但是,下一次運行時SID會有所不同。

為了避免這樣的情況,需要把登錄請求的響應中的SID值關聯為下次請求時的參數。 首先,我們將提取的SID值,並儲存為一個上下文參數,它將被作為參數傳遞給下一個請求。

 
上下文參數(Context Parameter)

上下文參數,它就像全局變量一樣。如果你想在所有的URL中使用同一個參數,那么把它聲明為上下文參數。

例如,我們需要在多種環境中運行該腳本。不需要為每種環境單獨錄制一遍,而是定義一個名為’WebServer’的上下文參數,並在每個需要用到的URL中使用它。上下文參數需要在兩層大括號中引用,如{{Webserver}}。把所有的URL修改為使用相同的上下文參數。當你想在另一個環境中運行該腳本,修改上下文參數的值,所有的URL將自動更新。

 

Query String作為URL的一部分被記錄下來。

在測試環境中,Query String輸入的值會有所不同,這取決於測試類型:正向測試,反向測試,邊界測試等。為了傳遞多個不同值的參數,我們需要做參數化。

 
參數化(Parameterization)

為了參數化參數(arguments),需要添加數據源用於選取參數值。右鍵單擊Web test - >選擇“Add Data Source”選項。

 

選擇數據源的類型。數據源可以是數據庫,如SQL Server,Oracle和Excel數據,也可以是CSV或XML文件。

 

選擇數據文件或數據庫,表中包含輸入數據。數據預覽將顯示在向導中。

 

點擊Query String來查看Query String的屬性。更改該值使用數據源映射如下。

 

數據源綁定將作為Query String的值顯示

 

提取規則

提取規則被用於從一個請求的響應中提取的數據。我們有以下提取選項:提取表單字段,提取HTTP頭等,提取的值可以用來作為下一個Web請求的一部分,或可用於任何商業決策。

在下面的例子中,我使用”提取文本“選項,提取從服務器傳遞來的一個id。通過分析HTML輸出,我們在規則屬性的“Starts With”和“Ends With”中填入對應的匹配值。這個HTML響應將作為最終窗口的一部分顯示(不久將討論)。

 

驗證規則

 

驗證規則用於確保你處於正確的頁面中。例如登錄后,你可能會期待頁面中包含”SignOut”文本。以下驗證規則,驗證當前的響應中是否包含“SignOut”文本。

我們可以使用以下驗證規則屬性中的任何選項形成驗證規則。Visual Studio 2010和2008會為錄制的測試自動添加響應URL驗證。

 
 

事務(Transaction)

 

事務是執行一個特定操作所必需的,一組操作或來回應答的集合。例如,購買一本書的過程中包括的步驟:選擇一本書,加入購物車,檢查和付款。

定義事務將有助於分析結果。通常情況下,響應時間,響應字節等信息,將分別為每個URL顯示。一旦你定義了事務,響應時間和其他衡量數據,將在事務級別顯示。

 
 

運行測試

當你運行測試,你將看到如下屏幕,在這里你可以看到每個URL的狀態,結果在web瀏覽器中是如何顯示的,哪些參數作為請求的一部分傳遞,HTML響應,上下文參數和其他一些細節。

 

這是單次運行的情況。如果你想使用參數化來運行多次測試,請單擊屏幕頂部的“Edit run Settings“選項。

在這里,您可以指定需要運行測試的次數。每次運行都會從參數數據源中選擇一個記錄來運行測試。運行次數的同時,我們可以指定瀏覽器的類型,這樣就可以模擬網站在不同的瀏覽器中的展現。

設置運行設置后,在屏幕頂部選擇”Click here to run again“選項。

 
生成代碼
 

生成代碼選項允許您根據腳本創建對應的代碼。

這將生成一份和 web test對應的C#代碼,同時為它創建一個單獨的測試。我們可以修改代碼,而不會影響原有的web test,反之亦然。

我們可以使用C#的功能,來自定義這種編碼的Web測試。可以使用循環迭代一個操作或用ADO.NET連接到數據庫為請求提取一些數據,強制執行思考時間(在PartII中討論)和處理WCF Services。

 

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30128.1
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace  GoogleTestProject
{
     using  System;
     using  System.Collections.Generic;
     using  System.Text;
     using  Microsoft.VisualStudio.TestTools.WebTesting;
     using  Microsoft.VisualStudio.TestTools.WebTesting.Rules;
 
     public  class  WebTest1Coded : WebTest
     {
         public  WebTest1Coded()
         {
             this .Context.Add( "WebServer" , "www.google.co.in" );
             this .PreAuthenticate = true ;
         }
         public  override  IEnumerator<WebTestRequest> GetRequestEnumerator()
         {
             // Initialize validation rules that apply to all requests in the WebTest
             if  (( this .Context.ValidationLevel >= Microsoft.VisualStudio.TestTools.WebTesting.ValidationLevel.Low))
             {
                 ValidateResponseUrl validationRule1 = new  ValidateResponseUrl();
                 this .ValidateResponse += new  EventHandler<ValidationEventArgs>(validationRule1.Validate);
             }
             if  (( this .Context.ValidationLevel >= Microsoft.VisualStudio.TestTools.WebTesting.ValidationLevel.Low))
             {
                 ValidationRuleResponseTimeGoal validationRule2 = new  ValidationRuleResponseTimeGoal();
                 validationRule2.Tolerance = 0D;
                 this .ValidateResponseOnPageComplete += new  EventHandler<ValidationEventArgs>(validationRule2.Validate);
             }
             WebTestRequest request1 = new  WebTestRequest( "http://www.google.com/" );
             request1.ThinkTime = 1;
             request1.ExpectedResponseUrl = "http://www.google.co.in/" ;
             ExtractHiddenFields extractionRule1 = new  ExtractHiddenFields();
             extractionRule1.Required = true ;
             extractionRule1.HtmlDecode = true ;
             extractionRule1.ContextParameterName = "1" ;
             request1.ExtractValues += new  EventHandler<ExtractionEventArgs>(extractionRule1.Extract);
             yield  return  request1;
             request1 = null ;
             WebTestRequest request2 = new  WebTestRequest( "http://clients1.google.co.in/generate_204" );
             yield  return  request2;
             request2 = null ;
             WebTestRequest request3 = new  WebTestRequest( "http://www.google.co.in/csi" );
             request3.QueryStringParameters.Add( "v" , "3" , false , false );
             request3.QueryStringParameters.Add( "s" , "webhp" , false , false );
             request3.QueryStringParameters.Add( "action" , "" , false , false );
             request3.QueryStringParameters.Add( "e" , "17259,18168,23730,24808" , false , false );
             request3.QueryStringParameters.Add( "ei" , "gV_yS7vIKYqC7QPFmZznCw" , false , false );
             request3.QueryStringParameters.Add( "expi" , "17259,18168,23730,24808" , false , false );
             request3.QueryStringParameters.Add( "imc" , "1" , false , false );
             request3.QueryStringParameters.Add( "imn" , "1" , false , false );
             request3.QueryStringParameters.Add( "imp" , "1" , false , false );
             request3.QueryStringParameters.Add( "rt" , "prt.77,xjsls.102,ol.1085,iml.353,xjses.1817,xjs.1849" , false , false );
             yield  return  request3;
             request3 = null ;
             WebTestRequest request4 = new  WebTestRequest( "http://clients1.google.co.in/complete/search" );
             request4.QueryStringParameters.Add( "hl" , this .Context[ "$HIDDEN1.hl" ].ToString(), false , false );
             request4.QueryStringParameters.Add( "client" , "hp" , false , false );
             request4.QueryStringParameters.Add( "expIds" , "17259,18168,23730,24808" , false , false );
             request4.QueryStringParameters.Add( "q" , "as" , false , false );
             request4.QueryStringParameters.Add( "cp" , "2" , false , false );
             yield  return  request4;
             request4 = null ;
             WebTestRequest request5 = new  WebTestRequest( "http://clients1.google.co.in/complete/search" );
             request5.QueryStringParameters.Add( "hl" , this .Context[ "$HIDDEN1.hl" ].ToString(), false , false );
             request5.QueryStringParameters.Add( "client" , "hp" , false , false );
             request5.QueryStringParameters.Add( "expIds" , "17259,18168,23730,24808" , false , false );
             request5.QueryStringParameters.Add( "q" , "asp" , false , false );
             request5.QueryStringParameters.Add( "cp" , "3" , false , false );
             yield  return  request5;
             request5 = null ;
             WebTestRequest request6 = new  WebTestRequest( "http://clients1.google.co.in/complete/search" );
             request6.QueryStringParameters.Add( "hl" , this .Context[ "$HIDDEN1.hl" ].ToString(), false , false );
             request6.QueryStringParameters.Add( "client" , "hp" , false , false );
             request6.QueryStringParameters.Add( "expIds" , "17259,18168,23730,24808" , false , false );
             request6.QueryStringParameters.Add( "q" , "asp." , false , false );
             request6.QueryStringParameters.Add( "cp" , "4" , false , false );
             yield  return  request6;
             request6 = null ;
             WebTestRequest request7 = new  WebTestRequest( "http://clients1.google.co.in/complete/search" );
             request7.QueryStringParameters.Add( "hl" , this .Context[ "$HIDDEN1.hl" ].ToString(), false , false );
             request7.QueryStringParameters.Add( "client" , "hp" , false , false );
             request7.QueryStringParameters.Add( "expIds" , "17259,18168,23730,24808" , false , false );
             request7.QueryStringParameters.Add( "q" , "asp.n" , false , false );
             request7.QueryStringParameters.Add( "cp" , "5" , false , false );
             yield  return  request7;
             request7 = null ;
             WebTestRequest request8 = new  WebTestRequest(( "http://"
             + ( this .Context[ "WebServer" ].ToString() + "/" )));
             request8.ExpectedResponseUrl = "http://www.google.co.in/#hl=en&source=hp&q=asp.net&rlz=1R2ADFA_enIN375&aq=f&aqi=&"  +
             "aql=&oq=&gs_rfai=&fp=4a7b17d2fd7e8e7" ;
             yield  return  request8;
             request8 = null ;
             WebTestRequest request9 = new  WebTestRequest( "http://clients1.google.co.in/complete/search" );
             request9.QueryStringParameters.Add( "hl" , this .Context[ "$HIDDEN1.hl" ].ToString(), false , false );
             request9.QueryStringParameters.Add( "client" , "hp" , false , false );
             request9.QueryStringParameters.Add( "expIds" , "17259,18168,23730,24808" , false , false );
             request9.QueryStringParameters.Add( "q" , "asp.net" , false , false );
             request9.QueryStringParameters.Add( "cp" , "7" , false , false );
             yield  return  request9;
             request9 = null ;
             WebTestRequest request10 = new  WebTestRequest( "http://www.google.co.in/search" );
             request10.ThinkTime = 1;
             request10.QueryStringParameters.Add( "hl" , this .Context[ "$HIDDEN1.hl" ].ToString(), false , false );
             request10.QueryStringParameters.Add( "source" , this .Context[ "$HIDDEN1.source" ].ToString(), false , false );
             request10.QueryStringParameters.Add( "q" , "asp.net" , false , false );
             request10.QueryStringParameters.Add( "rlz" , "1R2ADFA_enIN375" , false , false );
             request10.QueryStringParameters.Add( "aq" , "f" , false , false );
             request10.QueryStringParameters.Add( "aqi" , "" , false , false );
             request10.QueryStringParameters.Add( "aql" , "" , false , false );
             request10.QueryStringParameters.Add( "oq" , "" , false , false );
             request10.QueryStringParameters.Add( "gs_rfai" , "" , false , false );
             request10.QueryStringParameters.Add( "fp" , "4a7b17d2fd7e8e7" , false , false );
             yield  return  request10;
             request10 = null ;
             WebTestRequest request11 = new  WebTestRequest( "http://www.google.co.in/csi" );
             request11.QueryStringParameters.Add( "v" , "3" , false , false );
             request11.QueryStringParameters.Add( "s" , "web" , false , false );
             request11.QueryStringParameters.Add( "action" , "" , false , false );
             request11.QueryStringParameters.Add( "ei" , "hl_yS7TeHYTHrAfgy7jKDQ" , false , false );
             request11.QueryStringParameters.Add( "e" , "17259,18168,23730,24808" , false , false );
             request11.QueryStringParameters.Add( "cp" , "false" , false , false );
             request11.QueryStringParameters.Add( "imp" , "0" , false , false );
             request11.QueryStringParameters.Add( "imn" , "1" , false , false );
             request11.QueryStringParameters.Add( "rt" , "prt.586,pprt.599,ol.599,jsrt.565,iml.599" , false , false );
             yield  return  request11;
             request11 = null ;
             WebTestRequest request12 = new  WebTestRequest( "http://clients1.google.co.in/generate_204" );
             yield  return  request12;
             request12 = null ;
         }
     }
}

總結

Web Performance Test可以記錄網站鏈接跳轉並生成代碼。我們可以使用Web測試腳本或從其生成的代碼作為性能測試的輸入。自定義的測試可以使我們做到:

參數化 - 使用戶輸入動態化

關聯性 - 提取服務器產生的數據,用於后續請求。

 

介紹

對於一個多用戶的應用程序,性能是非常重要的。性能不僅是執行的速度,它包括負載和並發方面。性能測試是對以下問題的回答

  • 我們如何確保我們的新的應用程序將支持預期的用戶負載?
  • 如何避免在實際負載條件下會出現的問題?
  • 如何確定響應時間?
  • 如何規划服務器的容量?

Visual Studio是可以用於性能測試的工具之一。Visual Studio Test版或Visual Studio 2010旗艦版為自動化測試提供了支持。

這將是一系列文章的第二部分。

  • Part I: Web測試和配置

  • Part II:負載測試,RIG和負載測試術語。

  • Part III:性能計數器,負載測試結果分析。

 

負載測試(Load Test)

Load test 用於執行程序的負載測試。它可以模擬多個虛擬用戶並執行測試腳本,以模擬真實用戶在不同的服務器,如應用服務器,數據庫服務器和Web服務器的負載。Load test可以使用任何的測試腳本。

術語說明
Think Time

Think Time是兩個請求之間的時間。這可能是用戶填寫表單,瀏覽頁面,或閱讀一些文字等時花費的時間。Think Time用於模擬在真實用戶的場景下,系統如何和一個真實用戶的交互。

Constant Load (恆定負載)

Constant Load是指從測試開始到結束,有恆定數量的用戶不間斷地操作該網站。比如在1個小時的時間內,有25個用戶正在使用該系統。所有25個用戶不斷地訪問該系統。這種測試類型主要用於壓力測試。

Step Load(階躍負載)

在Step Load中,用戶將階梯式地加入。就是說在不同時期有不同的用戶操作系統,並且用戶的數量也不是恆定不變的。在Step Load模式下需要指定如下參數:

    • Start user count: -  測試開始時,有多少用戶操作該系統
    • Step duration:- 每隔多少秒后下一批用戶將加入該系統
    • Step user count:- 一個階梯時間段后,多少個用戶將加入系統
    • Maximum user count:- 最大的用戶數是多少。

 

測試組合(Test Mix)

測試組合指定不同的場景在系統中如何被執行或使用。不同的測試組合的設定是通過對系統使用情況的研究來形成的。

例如,如果我們在做某網絡營銷網站的負載測試,約60%的人會進行產品搜索,30%會買一些產品和10%會把產品保存為書簽。根據這種使用情況的信息,就可以形成一個測試組合:60%的模擬用戶將執行搜索腳本,30%將執行購買產品的腳本,其余的10%將執行把產品保存為書簽的腳本。

 
負載測試的創建

在項目上點擊鼠標右鍵,選擇Add- >New Test - >Load test模板。這將打開新的負載測試向導 
Ambily.raj_634152917086831719_1  

接下來,指定場景的名稱,如"booking the ticket","searching a book"等。接下來指定Think Time profile。我們可以使用Web測試中記錄的錄制的的Think Time,也可以使用時間正態分布的Think Time。我們還可以使用第三個選項來避免使用Think Time。 
Ambily.raj_634152917088931328_2  

接下來,指定負載模式。指定我們是否要使用constant load還是step load模式。在constant load模式中指定用戶數。在step load的情況下,指定start user count,step duration,step user count和maximum user count。  
Ambily.raj_634152917089321953_3
接下來,指定測試組合模式。提供的不同的選項有:

[下面的定義來自Visual Studio] 

基於總測試數(Base on the total number of tests)

確定虛擬用戶啟動測試迭代時運行哪個 Web 性能或單元測試。 在負載測試結束時,運行特定測試的次數與分配的測試分布相匹配。 使測試組合基於 IIS 日志或生產數據中的事務百分比時,可使用此測試組合模型。

 

基於虛擬用戶數(Based on the number of virual users)

確定將運行特定 Web 性能或單元測試的虛擬用戶的百分比。 在負載測試中的任何時候,運行特定測試的用戶數都與分配的分布情況相符。 使測試組合基於運行特定測試的用戶的百分比時,可使用此測試組合模型。

 

基於用戶節奏(Based on user pace)

在負載測試過程中,每個用戶每小時運行每個 Web 性能測試或單元測試指定的次數。 如果希望虛擬用戶在負載測試過程中以特定節奏運行測試,則可使用此測試組合模型。

 

基於順序測試順序(Based on sequential test order)

每個虛擬用戶按照在方案中定義測試的順序運行 Web 性能測試或單元測試。 虛擬用戶以此順序持續循環進行測試,直到負載測試完成為止。

(譯者:簡單來說,第一種配置每個虛擬用戶每次執行的腳本都是隨機的,所有用戶執行的腳本總數的比例是確定的;第二種配置每個用戶都執行固定的一個腳本,所有用戶執行的腳本的總數的比例是確定的;第三種指定每個腳本在一個小時內需要運行的次數,客戶端只需要完成這些工作量;第四種每個用戶都循環地順序地執行每個腳本)

Ambily.raj_634152917089644219_4

 

接下來,指定測試組合。在測試組合中,我們將添加多個Web測試腳本到負載測試中。如果我們只有一個腳本,所有用戶都將執行相同的任務。如果我們有2個或更多的腳本,我們可以指定有多少用戶需要執行特定的任務。

例如,我們有兩個腳本,一個用於搜索一本書,另一個用於購買一本書。在我的負載測試中,我可以指定70%的用戶做搜索,剩下的30%做另一個操作。

測試組合是模擬真實的用戶體驗。有些功能被很多用戶用到而另一些則沒有那么頻繁第被使用。取決於功能的使用情況,來測試系統,這將提供一個真正的性能結果。

Ambily.raj_634152917090073906_5

在下面的例子中,我們選擇了兩個Web測試腳本,並指定測試組合為65%的用戶將執行Webtest1,35%將執行Webtest2。



接下來,指定網絡組合(Network Mix)。在這里,我們可以模擬網絡如局域網,廣域網或互聯網,並且對系統在不同網絡中的性能進行比較。

Ambily.raj_634152917090698906_7  

接下來,指定瀏覽器的組合(Browser Mix)。這對於確定系統是如何在不同的瀏覽器中執行是非常有用的。

Ambily.raj_634152917091196953_8

 

接下來,增加作為web服務器、應用程序服務器和數據服務器的計算機系統,用於收集性能計數。為每個系統添加所需的性能計數器。

(譯者:確保你的帳號被添加到各個服務器的Performance Monitor Users組中,這樣控制器才有權限訪問各個服務器)

Ambily.raj_634152917655181328_9

接下來,指定測試的持續時間或迭代次數。如果設置了一個預熱期,負載測試會在預熱期逐漸地自動增加負荷。

Ambily.raj_634152917655532891_10  

一旦您完成創建負載測試,它會創建一個象下面這樣的.loadtest文件。從下面的界面中,我們可以直接編輯和添加的所有設置。 
Ambily.raj_634152917655943047_11

 

選擇constant Load模式,並選擇相應的屬性。從屬性面板中,我們可以改變負載模式為Constant, Step或者 Goal based。

Goal based load test(基於目標的負載測試)用於找到滿足條件的最大用戶負載。例如,在這里,我們設定的目標為平均響應時間應為8分鍾,一旦系統達到的目標,將停止執行。同樣的方法,我們可以通過使用基於目標的測試,以找到處理器利用率70%的最大負荷。  

 

從Run Settings屬性,我們可以改變的運行時間(Run Duration),網絡測試連接池的大小(WebTest Connection Pool Size),網絡測試連接模式(WebTest Connection Model),預熱持續時間(Warm-up Duration)等。

Ambily.raj_634152918027339531_13

我們可以指定計數器的閾值。一旦達到警戒水平時,它會顯示警告。當它達到臨界閾值時,請求將啟動失敗。  
Ambily.raj_634152918027945000_14

 

您可以添加自定義計數器和計數器集到計數器集合。

Ambily.raj_634152918028530938_15

從Scenario的屬性中,我們可以改變的思考時間配置和對應的思考時間。 
Ambily.raj_634152918028960625_16

 
 
執行負載測試

選擇“Run Test”來執行負載測試。


Ambily.raj_634152918029282891_17

一旦測試開始,你可以在下面的屏幕中觀察到不同的性能計數器和測試狀態。您可以拖動左側的計數器把它放置到圖形區域,這將為相應的計數器顯示圖形。請求匯總和測試匯總下可以在概覽部分中觀察到。 
Ambily.raj_634152918029751641_18

我們可以從表格項中觀察到的請求,錯誤,頁面,事務和其他的細節,比如失敗的次數,響應時間,內容長度。

Ambily.raj_634152918030093438_19

您可以更改圖形顯示選項,如只顯示一個圖形,或兩個垂直圖,四縱板等 
Ambily.raj_634152918030552422_20

結果

一旦執行負載測試完成后,顯示如下的匯總報告。

Ambily.raj_634152918338853203_21

我們可以可以使用”Create Excel Report”來將報表導出到Excel。它創建了一個Excel報表的多個工作表來描述平均響應時間,測試運行,頁面時間等, 
我們可以創建兩種類型的報告:

    • 趨勢 - 創建一個Excel報表為選定的運行結果創建趨勢圖。
    • 比較 - 創建一個Excel報表來比較兩個或更多運行結果。 
      Ambily.raj_634152918339136406_22  
    • Detail選項將允許我們在點狀圖中研究的測試結果。我們可以在底部區域選擇一段時間,研究在特定的時期的趨勢。

Ambily.raj_634152918339585625_23

 

Rig(遠程測試機組)

有時,在性能測試中,我們需要對系統進行非常高負載的測試。每台機器能夠產生的負載時有限的。在一個電腦系統中,我們可以產生最多500至800個用戶的負載。如果你需要更多的負載,我們需要添加多個電腦系統來執行負載測試。如果我們從多個系統中運行它,那么測試結果的分析和綜合報告的創建將是困難的。

Rig是在多個客戶端系統運行負載測試的解決方案。我們需要在一個系統上安裝負載控制器(Load Controller)並在其他系統上安裝負載代理(Load agent)。VSTS的Rig的是一組系統,它包括一個控制器和一個或多個代理。控制器將工作分配給代理,並且收集所有代理的數據,並建立一個單一的報告。

負載控制器,負載代理的安裝和配置,請參考http://blogs.msdn.com/b/edglas/archive/2007/02/17/load-agent-and-load-controller-installation-and-configuration-guide.aspx

總結

Load test可用於在系統上執行不同的性能測試。我們可以通過設置不同的測試組合,用戶負載,壓力條件,網絡組合,瀏覽器和負載模式來測試系統。通過查詢下SQLEXPRESS中的LoadTest或者LoadTest2010數據庫,Load test會生成一個詳細的報告,此外,從結果中,我們可以創建一個Excel的趨勢報告或比較報告。總結報告可以保存為HTML文件。

 

 

介紹

對於一個多用戶的應用程序,性能是非常重要的。性能不僅是執行的速度,它包括負載和並發方面。性能測試是對以下問題的回答

  • 我們如何確保我們的新的應用程序將支持預期的用戶負載?
  • 如何避免在實際負載條件下會出現的問題?
  • 如何確定響應時間?
  • 如何規划服務器的容量?

 

Visual Studio是可以用於性能測試的工具之一。Visual Studio Test版或Visual Studio 2010旗艦版為自動化測試提供了支持。

這將是一系列文章的第三部分。

  • Part I: Web測試和配置

  • Part II:負載測試,RIG和負載測試術語。

  • Part III:性能計數器,負載測試結果分析。

 

 

 

 

 

性能計數器

性能計數器可以是系統預定義或用戶自定義的,用來衡量系統的性能。性能測試結果分析完全依賴於作為測試的一部分而捕獲的性能計數器。因此,為了有更好的測試結果和更好的分析,我們首先需要了解每個服務器相關的的重要的計數器。

我們可以使用性能監視器(這篇文章中討論的)或使用Visual Studio本身,來捕捉性能計數器。為了獲取相應的服務器的計數器,在需要在Load test中把服務器添加到computer section。

 

 

添加計算機來收集性能計數器

在Load test中,右鍵單擊Run Settings 下的 Counter Set Mappings,選擇Manage Counter Sets選項。

Ambily.raj_3703_1

 

Manage Counter Sets窗口將被打開,在這里我們可以添加計算機。添加計算機系統,並選擇相應的計數器。

Ambily.raj_0734_2

 

當負載測試執行時,我們可以在Visual Studio中觀察到每個計算機系統對應的計數器。

Ambily.raj_4250_3

 

在性能監視器中添加計數器

本文也將討論設置性能監視器來捕獲計數器。如果您使用性能監視器來捕獲計數器,那么我們就需要確保在負載測試前啟動計數器,並在負載測試完成后再關閉它。還需要從多台服務器合並結果並生成報告。

(譯者:在Run中輸入perfmon,來打開性能監視器。在性能工具->性能監視器下打開性能監視器圖表,在性能監視器圖表中,點擊+或右鍵菜單來添加計數器)


重要的計數器

我們根據服務器和服務器上的應用程序來捕獲對應的計數器。例如,一個數據庫服務器所需的計數器和web服務器上的不同。另外,我們需要為每個服務器設置通用的計數器,如處理器利用率,內存利用率等。在本節中,我們將討論通用計數器和應用程序服務器以及數據庫服務器所需的重要的計數器。在這里,我們將討論一些重要的計數器,但不是全部。

通用計數器

\Processor(*)\%Processor time -這個計數器衡量處理器的利用率。在所有服務器上捕捉這個計數器,並測量平均使用率。在空閑的情況下,處理器的利用率應低於80%。

\Process(*)\Private Bytes - 指示分配給該進程的內存的字節數。該計數器指示進程的內存使用率。

\Network Interface\Bytes Received/sec, \Network Interface\Bytes Sent/sec, \Network Interface\Bytes Total/sec -這三個計數器指示了服務器的網絡使用率。

ASP.NET Web應用程序服務器計數器

\.Net CLR Data\ -這個計數器組包含與以下相關的計數器:連接池的數量,失敗的連接嘗試的數量和在應用程序服務器上運行的特定進程的連接池的數量。

(譯者:.net連接池用於ADO.net和數據庫連接,可以參考.NET連接池救生員一文)

\.Net CLR LocksAndThreads\ -這個計數器組包含物理和邏輯線程數和發生競爭(Contentions)的數量。

(譯者:邏輯線程指托管線程;物理線程指操作系統線程;Contentions指試圖獲取托管鎖發生的錯誤)

\.Net CLR Memory\ -這個計數器組包括Gen 0,Gen 1和Gen 2的垃圾回收數量和堆的大小。指示了垃圾收集率和應用程序每輪的內存管理。

\.Net Memory Cache4.0\ -這個計數器組幫助你了解應用程序的緩存實現。

\ASP.Net Applications\ -這個計數器組提供請求處理和應用管理的概覽:有多少請求被處理,拒絕,排隊或斷開,緩存命中率和失誤,錯誤,身份驗證失敗,輸出緩存請求數和失敗數,活躍和被丟棄的會話,提交和中止的事務。

數據庫服務器計數器

\Database\ -數據庫相關的計數器,如數據庫高速緩存的大小,數據庫I / O讀取和寫入,頁面轉換和記錄轉換。SQL Server特定的計數器被定義在單獨的計數器組。

\SQLAgent:Jobs\ -該計數器組包含的計數器指示了SQL Server中運行的作業的狀態。指示了有多少作業是是活動的,失敗的,正在排隊,或已成功執行。

\SQLServer:Locks\ -這個計數器指示在應用程序執行中有多少次死鎖發生。

 

通用術語

在討論的計數器以及如何理解它們前,我們需要研究性能測試相關的多個術語。

響應時間(Response Time)

大多數的性能測試是為了了解在給定負載情況下應用程序的響應時間。如果應用程序沒有完成性能測試,那么預期的用戶負載的響應時間可能不會被定義。

響應時間是指一個頁面或者事務響應用戶所花費的時間。8秒是一個網頁標准的最大響應時間。如果頁面有很多的圖像或視頻,它可能需要更多的時間來加載。為了更好的使用,我們可以加載頁面中使用異步調用和Ajax。如果響應時間是非常高的,用戶的體驗將變得糟糕,對應用的使用方法也可能會影響到響應時間。減少響應時間的同時保持豐富的用戶界面是一項挑戰。

吞吐量(Throughput)

吞吐量是每秒由服務器處理的事務或輸入的數量。這指示了服務器每次可以處理的負載或請求的數量。根據吞吐量和響應時間的要求,我們可以來規划的服務器集群。

資源利用(Resource Utilization)

資源利用包括服務器的處理器,內存和網絡的利用率。應用程序對服務器資源的利用率確定了,我們是部署一台服務器,還是需要部署多台服務器。

 

這是三個主要的性能測試術語或者指標。除了這些衡量指標以外,我們有網絡時間,等待時間,請求時間,測試組合,負載組合等指標,我們將在后面討論。

 

 

結果分析

現在,我們有所需的計數器數據和性能數據,如響應時間和吞吐量等。對於不同場景的性能結果分析,無法在一兩個文檔中解釋清楚。取決於我們收到的作為性能測試的結果數據,分析會有所不同。

例如,假設你得到很高的響應時間,同時具有良好的資源利用率。簡單來說這意味着,高響應時間不是由於任何資源的問題引起的,它可能是由於你的SQL部分或前端代碼引起。查看SQL計數器,並確定是否有特定的頁面做了某些數據庫調用並產生大量的讀,寫或占用大量CPU時間。如果是這樣的話,這個問題在於數據庫查詢或存儲過程。而后,我們縮小到數據庫級別的問題,然后我們就可以使用數據庫工具,如SQL Execution plan或Data engine tuning advisor,了解並解決此問題。

如果問題出在應用程序的代碼上,然后我們需要研究的問題是,問題是否是由高速緩存,圖像,線程,連接池的問題導致的。

 

 

結論

我們在下一篇文章中我們將使用一些示例場景來更深入討論性能測試的結果分析。

 

本文由知平軟件劉斌華翻譯,轉載請注明出處。原文地址:http://www.dotnetfunda.com/articles/article1563-web-performance-test-using-visual-studio-part-iii.aspx

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM