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中的主要测试类型。
Basic Unit Test,Unit Test 和 Unit 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。
//------------------------------------------------------------------------------
// <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测试功能。 介绍 对于一个多用户的应用程序,性能是非常重要的。性能不仅是执行的速度,它包括负载和并发方面。性能测试是对以下问题的回答: 我... 阅读全文
7 Comment Categories: 测试技术
扩展iQuery使其支持多种编程语言(上) – 兼编译器的词法分析简介 2012-08-27 12:38 by 知平软件, 997 visits, 网摘 , 收藏 , 编辑
摘要: iQuery在设计的时候就考虑到对其他编程语言的支持,本文主要是通过讲解iQuery的词法分析,为后文的编程语言扩展做铺垫,读者也可以从中学到实现一门编程语言中使用词法分析的方法。 阅读全文
0 Comment Categories: Android , iOS , 知平开源项目 , 测试技术
原创开源项目 - 扩展iQuery 2012-08-24 15:16 by 知平软件, 1419 visits, 网摘 , 收藏 , 编辑
摘要: 为了满足跨平台一致的控件查询这个目标,iQuery支持多种编程语言,通过伪类和伪属性的设计来隐藏各平台的差异性,而无论是伪类、伪属性,还是对多编程语言的支持,iQuery都是可以扩展的,本文介绍扩展iQuery的方法 阅读全文
1 Comment Categories: Android , iOS , 知平开源项目 , 测试技术
开源类库iQuery Android版使用说明 2012-08-20 10:44 by 知平软件, 1248 visits, 网摘 , 收藏 , 编辑
摘要: iQuery是一个通用的跨平台的控件查询类库,其语法类似jQuery,但你可以在iOS、Android、selenium、甚至是桌面GUI程序上使用它。在iQuery之前,要在界面中查询一个控件,特别是自动化测试用例程序中,是比较麻烦的事情,而iQuery不仅可以用一段简洁的文本精准定位控件,还为使用同一个查询语句执行跨平台控件查询提供可能。 继上周发布iQuery iOS版发布之后,我们再接再... 阅读全文
4 Comment Categories: Android , 知平开源项目 , 测试技术
类jQuery selector的控件查询iQuery开源类库介绍 2012-08-14 16:08 by 知平软件, 1466 visits, 网摘 , 收藏 , 编辑
摘要: iQuery的思路借鉴自jQuery(或者说是CSS)的选择器,一方面提供一个比较简单的方式在自动化测试程序里抓取控件,一方面试图通过将控件归类提供一种跨平台统一的控件抓取表述语法。它是一个多平台通用的控件查询语法,当前已经实现了iOS版,支持在Instrument里使用,本文介绍iQuery在iOS上Instrument中的用法。 阅读全文
0 Comment Categories: iOS , 知平开源项目 , 测试技术 Tags: 测试 , Android , iOS , Open Source , GPL
在PHP中使用Mockery进行测试驱动开发(TDD) - 上 2012-08-06 10:48 by 知平软件, 1483 visits, 网摘 , 收藏 , 编辑
摘要: 测试驱动开发网上也谈了很多了,PHP方面的文章也有一些,在百度和Google里搜,好像没有看到几篇谈用Mock(伪装对象)的技术的,这里写篇文章讲讲。先过一下测试驱动开发的基本理念:就是先写测试用例(一般这个测试用例都是自动化的单元测试用例,便于快速回滚执行),然后通过逐步修复测试用例的方法补齐产品代码,最后测试用例修复完毕后,产品也就写完了。从我自己的实践中,我认为在类库开发的时候使用测试驱动开发技术是一个很好的方案,理由如下: 能够写出测试用例,即说明对问题域已经有一个清晰的了解, 节省了写文档的时间,测试用例就是类库调用的示例代码了。 代码质量有保证,因为写类库的过程就是修复... 阅读全文
0 Comment Categories: Web测试 , 测试技术 Tags: 测试 , TDD
使用allpairs自动设计组合测试用例 2012-07-30 15:42 by 知平软件, 858 visits, 网摘 , 收藏 , 编辑
摘要: 配对测试的基本理念是,虽然程序的某个组件,或者程序自己会接受很多的输入,但大部分情况下,程序的bug不是因为这些输入同时作用而产生的,而是由一到两个输入条件同时作用导致的。因此配对测试在生成测试组合的时候,主要关注将每个条件与其它条件至少配对一次,而不是试图生成全组合,这样就可以大大减少需要测试的组合数,尽而节省测试工作量,同时又能达到满意的测试覆盖率。 阅读全文
0 Comment Categories: 测试技术 Tags: 测试
作者: Leo_wl
出处: http://www.cnblogs.com/Leo_wl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息查看更多关于Visual Studio进行Web性能测试的详细内容...
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://haodehen.cn/did48159