zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    VMWare安装Solaris虚拟机的网络设置
    PeopleTools预警程序制作
    listener.ora增加监听端口
    用.Net Mage工具更新WPF ClickOnce应用程序部署清单
    基本测试方法用例场景
    Qt Vs msvc debug版本没有问题但release版本出现异常
    Qt 打包release发布问题
    Qt 鼠标悬浮按钮上出现浮窗效果
    Qt 样式对于QPushbutton 增加 hover press release效果
    阿里云ECS无法通过SSL远程链接问题。
  • 原文地址:https://www.cnblogs.com/ahjxxy/p/2688999.html
Copyright © 2011-2022 走看看