Visual Studio進行Web性能測試- Part I


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

介紹

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

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

Visual Studio是能夠用於性能測試的工具之一。Visual Studio Test版或Visual Studio 2010旗艦版爲自動化測試提供了支持。數據庫

 

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

  • Part I: Web測試和配置服務器

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

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

 

VS 2010測試類型asp.net

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

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 性能測試中添加 Web 錄製,參見 https://docs.microsoft.com/zh-cn/previous-versions/ff406969(v=vs.110)

在這個例子中,咱們記錄到谷歌的搜索功能。一旦錄製結束,在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。

 

//------------------------------------------------------------------------------ // <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測試腳本或從其生成的代碼做爲性能測試的輸入。自定義的測試可使咱們作到:

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

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

PartII中,咱們將探討負載測試,PartIII是對性能測試結果進行分析和理解的主要性能計數器。

相關文章
相關標籤/搜索