Visual Studio进行Web性能测试

Visual Studio进行Web性能测试- Part I

2012-08-29 08:01 by 知平软件, 1010 阅读, 2 评论, 收藏, 编辑

原文作者: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中的主要测试类型。

Visual Studio进行Web性能测试_第1张图片

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应用程序测试。我们将通过选择从测试项目模板创建一个测试项目。

Visual Studio进行Web性能测试_第2张图片

 

一旦你创建好测试项目,右键单击该项目,并添加新的项。选择Web Performance Test,这将在Internet Explorer中打开录制器,并开始录制URL和相关参数。

 
录制

下图显示了Web测试录制器,录制在google上的操作。

Visual Studio进行Web性能测试_第3张图片

在这个例子中,我们记录到谷歌的搜索功能。一旦录制结束,在Web测试录制器中使用“停止”按钮停止录制。这将把录制的URL生成一个Web测试,并添加动态的相关性。

 
相关性(Correlation)

什么是相关性,简而言之就是上一次Web请求的响应和下次请求之间的关联。

例如,当你登录网站时,它会生成一个用于跟踪会话的SID。登录后,这SID被传递给了客户端。随着下一个请求,存储的SID将被发送到服务器。当您使用Web测试录制这一操作时,它会记录这个值并硬编码保存。但是,下一次运行时SID会有所不同。

为了避免这样的情况,需要把登录请求的响应中的SID值关联为下次请求时的参数。 首先,我们将提取的SID值,并储存为一个上下文参数,它将被作为参数传递给下一个请求。

 
上下文参数(Context Parameter)

上下文参数,它就像全局变量一样。如果你想在所有的URL中使用同一个参数,那么把它声明为上下文参数。

例如,我们需要在多种环境中运行该脚本。不需要为每种环境单独录制一遍,而是定义一个名为’WebServer’的上下文参数,并在每个需要用到的URL中使用它。上下文参数需要在两层大括号中引用,如{{Webserver}}。把所有的URL修改为使用相同的上下文参数。当你想在另一个环境中运行该脚本,修改上下文参数的值,所有的URL将自动更新。

Visual Studio进行Web性能测试_第4张图片

 

Query String作为URL的一部分被记录下来。

Visual Studio进行Web性能测试_第5张图片

在测试环境中,Query String输入的值会有所不同,这取决于测试类型:正向测试,反向测试,边界测试等。为了传递多个不同值的参数,我们需要做参数化。

 
参数化(Parameterization)

为了参数化参数(arguments),需要添加数据源用于选取参数值。右键单击Web test - >选择“Add Data Source”选项。

Visual Studio进行Web性能测试_第6张图片

 

选择数据源的类型。数据源可以是数据库,如SQL Server,Oracle和Excel数据,也可以是CSV或XML文件。

Visual Studio进行Web性能测试_第7张图片

 

选择数据文件或数据库,表中包含输入数据。数据预览将显示在向导中。

Visual Studio进行Web性能测试_第8张图片

 

点击Query String来查看Query String的属性。更改该值使用数据源映射如下。

Visual Studio进行Web性能测试_第9张图片

 

数据源绑定将作为Query String的值显示

Visual Studio进行Web性能测试_第10张图片

 

提取规则

提取规则被用于从一个请求的响应中提取的数据。我们有以下提取选项:提取表单字段,提取HTTP头等,提取的值可以用来作为下一个Web请求的一部分,或可用于任何商业决策。

在下面的例子中,我使用”提取文本“选项,提取从服务器传递来的一个id。通过分析HTML输出,我们在规则属性的“Starts With”和“Ends With”中填入对应的匹配值。这个HTML响应将作为最终窗口的一部分显示(不久将讨论)。

Visual Studio进行Web性能测试_第11张图片

 

验证规则

 

验证规则用于确保你处于正确的页面中。例如登录后,你可能会期待页面中包含”SignOut”文本。以下验证规则,验证当前的响应中是否包含“SignOut”文本。

我们可以使用以下验证规则属性中的任何选项形成验证规则。Visual Studio 2010和2008会为录制的测试自动添加响应URL验证。

Visual Studio进行Web性能测试_第12张图片

 
 

事务(Transaction)

 

事务是执行一个特定操作所必需的,一组操作或来回应答的集合。例如,购买一本书的过程中包括的步骤:选择一本书,加入购物车,检查和付款。

定义事务将有助于分析结果。通常情况下,响应时间,响应字节等信息,将分别为每个URL显示。一旦你定义了事务,响应时间和其他衡量数据,将在事务级别显示。

Visual Studio进行Web性能测试_第13张图片

 
 

运行测试

当你运行测试,你将看到如下屏幕,在这里你可以看到每个URL的状态,结果在web浏览器中是如何显示的,哪些参数作为请求的一部分传递,HTML响应,上下文参数和其他一些细节。

Visual Studio进行Web性能测试_第14张图片

 

这是单次运行的情况。如果你想使用参数化来运行多次测试,请单击屏幕顶部的“Edit run Settings“选项。

Visual Studio进行Web性能测试_第15张图片

在这里,您可以指定需要运行测试的次数。每次运行都会从参数数据源中选择一个记录来运行测试。运行次数的同时,我们可以指定浏览器的类型,这样就可以模拟网站在不同的浏览器中的展现。

设置运行设置后,在屏幕顶部选择”Click here to run again“选项。

 
生成代码
 

生成代码选项允许您根据脚本创建对应的代码。

Visual Studio进行Web性能测试_第16张图片

这将生成一份和 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测试脚本或从其生成的代码作为性能测试的输入。自定义的测试可以使我们做到:

参数化 - 使用户输入动态化

关联性 - 提取服务器产生的数据,用于后续请求。

PartII中,我们将探讨负载测试,PartIII是对性能测试结果进行分析和理解的主要性能计数器。

 

 

本文由知平软件的刘斌华翻译,转载请注明出处。原文地址:http://www.dotnetfunda.com/articles/article901-web-performance-test-using-visual-studio-part-i.aspx

知平软件致力于移动平台自动化测试技术的研究,我们希望通过向社区贡献知识和开源项目,来促进行业和自身的发展。

 
分类:  测试技术

随笔分类 -测试技术

Visual Studio进行Web性能测试- Part I

2012-08-29 08:01 by 知平软件, 1301 visits, 网摘, 收藏, 编辑
摘要:原文作者:Ambily.raj Visual Studio是可以用于性能测试的工具之一。Visual Studio Test版或Visual Studio 2010旗舰版为自动化测试提供了支持。本文介绍Visual Studio的Web测试功能。 介绍 对于一个多用户的应用程序,性能是非常重要的。性能不仅是执行的速度,它包括负载和并发方面。性能测试是对以下问题的回答: 我...  阅读全文

扩展iQuery使其支持多种编程语言(上) – 兼编译器的词法分析简介

2012-08-27 12:38 by 知平软件, 997 visits, 网摘, 收藏, 编辑
摘要:iQuery在设计的时候就考虑到对其他编程语言的支持,本文主要是通过讲解iQuery的词法分析,为后文的编程语言扩展做铺垫,读者也可以从中学到实现一门编程语言中使用词法分析的方法。  阅读全文

原创开源项目 - 扩展iQuery

2012-08-24 15:16 by 知平软件, 1419 visits, 网摘, 收藏, 编辑
摘要:为了满足跨平台一致的控件查询这个目标,iQuery支持多种编程语言,通过伪类和伪属性的设计来隐藏各平台的差异性,而无论是伪类、伪属性,还是对多编程语言的支持,iQuery都是可以扩展的,本文介绍扩展iQuery的方法  阅读全文

开源类库iQuery Android版使用说明

2012-08-20 10:44 by 知平软件, 1248 visits, 网摘, 收藏, 编辑
摘要:iQuery是一个通用的跨平台的控件查询类库,其语法类似jQuery,但你可以在iOS、Android、selenium、甚至是桌面GUI程序上使用它。在iQuery之前,要在界面中查询一个控件,特别是自动化测试用例程序中,是比较麻烦的事情,而iQuery不仅可以用一段简洁的文本精准定位控件,还为使用同一个查询语句执行跨平台控件查询提供可能。 继上周发布iQuery iOS版发布之后,我们再接再...  阅读全文

类jQuery selector的控件查询iQuery开源类库介绍

2012-08-14 16:08 by 知平软件, 1466 visits, 网摘, 收藏, 编辑
摘要:iQuery的思路借鉴自jQuery(或者说是CSS)的选择器,一方面提供一个比较简单的方式在自动化测试程序里抓取控件,一方面试图通过将控件归类提供一种跨平台统一的控件抓取表述语法。它是一个多平台通用的控件查询语法,当前已经实现了iOS版,支持在Instrument里使用,本文介绍iQuery在iOS上Instrument中的用法。  阅读全文

在PHP中使用Mockery进行测试驱动开发(TDD) - 上

2012-08-06 10:48 by 知平软件, 1483 visits, 网摘, 收藏, 编辑
摘要:测试驱动开发网上也谈了很多了,PHP方面的文章也有一些,在百度和Google里搜,好像没有看到几篇谈用Mock(伪装对象)的技术的,这里写篇文章讲讲。先过一下测试驱动开发的基本理念:就是先写测试用例(一般这个测试用例都是自动化的单元测试用例,便于快速回滚执行),然后通过逐步修复测试用例的方法补齐产品代码,最后测试用例修复完毕后,产品也就写完了。从我自己的实践中,我认为在类库开发的时候使用测试驱动开发技术是一个很好的方案,理由如下: 能够写出测试用例,即说明对问题域已经有一个清晰的了解, 节省了写文档的时间,测试用例就是类库调用的示例代码了。 代码质量有保证,因为写类库的过程就是修复...  阅读全文

使用allpairs自动设计组合测试用例

2012-07-30 15:42 by 知平软件, 858 visits, 网摘, 收藏, 编辑
摘要:配对测试的基本理念是,虽然程序的某个组件,或者程序自己会接受很多的输入,但大部分情况下,程序的bug不是因为这些输入同时作用而产生的,而是由一到两个输入条件同时作用导致的。因此配对测试在生成测试组合的时候,主要关注将每个条件与其它条件至少配对一次,而不是试图生成全组合,这样就可以大大减少需要测试的组合数,尽而节省测试工作量,同时又能达到满意的测试覆盖率。  阅读全文

你可能感兴趣的:(Visual Studio进行Web性能测试)