LR 脚本---.net协议(收集)
源于网上收集。
1、http://blog.csdn.net/mh370/article/details/30036985
北京XX项目的时候,有个对文件系统的性能需求如下:
业务场景:在一台服务器上单独部署一个文件系统,用于管理系统操作中产生的图片文件,客户端会对该文件系统产生上传文件和下载文件的操作,由于在一段时间内操作的用户会很多,会产生并发操作的情况,需要对上传和下载进行压力测试;
文件系统使用c#编写,在服务器上以服务器形式运行;客户端也是C#编写的winform应用程序,首先想到的是使用microsoft .Net协议开发脚本,录制的效果不好,选择直接C#编写脚本;
说明:
- microsoft .net协议的脚本录制起来的脚本比较难看,比较冗长;建议还是新建microsoft .net协议的脚本后自己根据需要编写;
- 下面的脚本不是自己随意编写,实现操作功能即可的;而是和开发人员沟通,得知客户端是怎么对文件系统进行操作后,完全模拟客户端中的代码模式编写;或者可以认为是copy开发人员的代码后简单修改的;
- loadrunner是支持直接VS2005调试的,不知道现在有没有出现支持VS更高版本的
//--------------------------------------------- //Script Title : //Script Description : // // //Recorder Version : 593 //--------------------------------------------- namespace Script { using FJ.RP.Entity; using LoadRunner; using Mercury.LoadRunner.DotNetProtocol.Replay; //自己定义的变量 using SocketLibrary; using System; using System.Collections; using System.Data; using System.Data.Common; using System.Data.OracleClient; using System.Xml; using System.IO; public partial class VuserClass { public virtual int Action() { //RemoteFloder_1为服务器上保存批次图像的路径; //LocalFloder_1是本地事先准备好的批次图像,需要运行前准备好; //参数化时直接参数batchArea变量的后三位数字; sharePath="\\\\192.168.3.28\\xxx\\"; batchArea="\\11\\1101\\110101\\110101001\\110101001005\\110101001005" + lr.eval_string("{NewParam1}"); RemoteFloder_1=sharePath+"Scanimage\\短表<a target=_blank href="file://\\put'+batchArea">\\put"+batchArea</a>; LocalFloder_1="D:\\test\\Scanimage\\短表"+batchArea; //192.168.3.28时文件系统服务器的地址 NetFileTransfer_2=((NetFileTransfer)(Activator.GetObject(typeof(SocketLibrary.NetFileTransfer), "tcp://192.168.3.28:8085/FileService"))); //上传本地图像到服务器中; lr.start_transaction("scan_put"); Files = Directory.GetFiles(@LocalFloder_1); foreach(string s in Files) { string name=System.IO.Path.GetFileName(s); RemoteSavefile = RemoteFloder_1+"//"+name; filePath_2=LocalFloder_1+"//"+name; try{ //把本地需要上传的单个文件读取到文件流中; lr.start_transaction("readlocal"); FileStream fs1 = new FileStream(filePath_2,FileMode.Open,FileAccess.Read,FileShare.Read); ByteArray_2 = new byte[fs1.Length]; fs1.Read(ByteArray_2,0,ByteArray_2.Length); fs1.Close(); lr.end_transaction("readlocal", lr.AUTO); //上传文件到服务器指定目录并保存; if(!System.IO.Directory.Exists(@RemoteFloder_1)) { System.IO.Directory.CreateDirectory(@RemoteFloder_1); } if (File.Exists(RemoteSavefile)) File.Delete(RemoteSavefile); NetFileTransfer_2.SendFileBytes(ByteArray_2,RemoteSavefile); }catch(Exception ex) { lr.output_message(ex.ToString()); lr.end_transaction("scan_put", lr.FAIL); } } lr.end_transaction("scan_put", lr.AUTO); NetFileTransfer_2=null; return 0; } } }
2、http://blog.csdn.net/mh370/article/details/30064361
下面列出项目中另外两个关于microsoft .net协议的脚本应用。
1)模拟公司某产品(CS结构,使用C#开发)的一个数据发布场景,其实这个脚本并不是用来做压力测试的,而是针对性模拟其它和该产品有关的应用需要的数据。简单点说,有些测试需要该产品发布的大量数据或者持续发布数据,但是操作产品功能发布数据显然满足不了要求,需要使用脚本来完成,模拟发布场景自动完成。
//--------------------------------------------- //Script Title : //Script Description : // // //Recorder Version : //--------------------------------------------- using LoadRunner; using Mercury.LoadRunner.DotNetProtocol.Replay; using System; using System.Reflection; using System.Collections.Generic; using System.Text; using System.IO; using ICSharpCode.SharpZipLib.Zip; namespace Script { public partial class VuserClass { /*fullPath是保存XML文件和图像路径的地方,压缩的是该目录下的内容;filename是压缩后压缩文件的名称,该变量主要用于来做参数化 releaseName压缩成release格式时的文件名称的全路径;*/ string fullPath="C:\\TempRelease"; string fileName; string sourcePatch="c:\\scanrelease\\"; string zipName; string releaseName; int count; /*countSum为循环次数,也就是模拟发布的批次的数量*/ int countSum=3; public int Action() { count=1; while(count<countSum) { lr.start_transaction("batchRelease"); fileName=lr.eval_string("{NewParam}"); //lr.output_message(fileName); releaseName=sourcePatch+fileName.ToString()+".release"; zipName=sourcePatch+fileName+".zip"; /*调用ZipDirectory方法压缩fullPath路径下的文件称release格式文件*/ ZipDirectory(releaseName,fullPath); /*如果release格式文件存在,则判断zip格式文件是否存在,存在则删除,然后把release文件格式修改成zip格式*/ if (File.Exists(releaseName)) { if (File.Exists(zipName)) { if ((File.GetAttributes(zipName) & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) { File.SetAttributes(zipName, FileAttributes.Normal); } File.Delete(zipName); } File.Move(releaseName, zipName); } lr.output_message("模拟第"+count+"个批次发布完成!"); lr.end_transaction("batchRelease", lr.AUTO); /*增加思考时间,在循环的时候根据设置的思考时间,NewParam(参数类型为Date/time)取得的时间会不同,也就是模拟多长时间发布一个批次,参数单位为 秒,如果不增加该思考时间,不管循环多少次,都只能模拟发布一个批次*/ lr.think_time(5); count++; } return 0; } /*压缩指定路径下文件的压缩方法,需要传入两个参数,一个是压缩后的文件名,一个是压缩的原目录*/ public void ZipDirectory(string zipFileName, string sourceDirectory) { try { FastZip fz = new FastZip(); fz.CreateEmptyDirectories = true; fz.CreateZip(zipFileName, sourceDirectory, true, ""); fz = null; } catch (Exception ex) { lr.output_message(ex.ToString()); } } } }
2)
同样是公司某产品(CS结构,使用C#开发),有个指定类型的性能需求。就是产品中会产生很多的文档,但是这些文档需要手动或者自动的指定一个文档类型,其实就是往数据库中更新数据,会产生很多客户端同时指定文档类型的场景,对数据库操作产生一定压力,需要做并发压力测试;
其实这里就是对数据库产生操作,其实也可以直接使用数据库相关的协议。其实就是一堆与数据库相关的代码,也是根据客户端的操作代码来编写的脚本;这个脚本比较长,且看且不看吧~~
//--------------------------------------------- //Script Title : //Script Description : // // //Recorder Version : 593 //--------------------------------------------- using LoadRunner; using Mercury.LoadRunner.DotNetProtocol.Replay; using System;using System.Data; using System.Data.SqlClient; namespace Script { public partial class VuserClass { int bthClassID; int bthID; int sapID; string sapDescription; int dcmClassID; int filedID; int docID; /*需要再对应的数据库系统中准备30个批次的数据,模拟30个客户端同时操作时,每个客户端操作一个批次,需要对批次的文档ID进行参数化,避免每次迭代操作时都是操作的同一个文档*/ public virtual int Action() { /*文档ID的参数化*/ /*注意:模拟的每个批次包含16个文档,参数化文档ID的时候,选择的参数类型是Uniqe Number,那么每个虚拟用户直接的step就应该是小于16*/ docID=Convert.ToInt32(lr.eval_string("{NewParam_1}")); bthID=Convert.ToInt32(lr.eval_string("{NewParam2}")); lr.start_transaction("指定文档类型"); /*根据批次名称从批次表中查出该批次使用的批次类ID,这里只是模拟客户端根据批次查询出对应的批次类,这段操作不需要做参数化*/ lr.start_transaction("selectBatchClass"); string strConn = "data source=192.168.0.208;initial catalog=capture;user id=sa;password=sa"; SqlConnection conn = new SqlConnection(strConn); SqlCommand cmd = new SqlCommand(); cmd.CommandType = System.Data.CommandType.Text; cmd.CommandText = "select * from TBLBatch where Bth_Name=@Bth_Name"; cmd.Connection = conn; cmd.Connection.Open(); SqlParameter sqlp1 = new SqlParameter(); sqlp1.ParameterName="@Bth_Name"; sqlp1.DbType= DbType.String; sqlp1.Value ="2010-11-30 10:09:23"; sqlp1.Direction = ParameterDirection.Input; sqlp1.IsNullable = false; SqlParameterCollection SqlParameterCollection1 = ((SqlParameterCollection)(cmd.Parameters)); SqlParameterCollection1.Add(((Object)(sqlp1))); SqlDataReader sqlDataReader = cmd.ExecuteReader(); while(sqlDataReader.Read()) { bthClassID = Convert.ToInt32(sqlDataReader["BthClass_ID"]); //bthID = Convert.ToInt32(sqlDataReader["Bth_ID"]); String strbthClassID = Convert.ToString(sqlDataReader["BthClass_ID"]); lr.message(strbthClassID.ToString()); } sqlDataReader.Close(); cmd.Dispose(); lr.end_transaction("selectBatchClass", lr.AUTO); /*根据批次类ID查询出该批次类下面包含多少的文档类,以及所有文档类下面的样本页,获取样本页ID和样本页描述,实际操作中用户会在界面选择一个样本页,这里模拟的是使用最后一个样本页*/ lr.start_transaction("selectSamplePage"); string strConn1 = "data source=192.168.0.208;initial catalog=capture;user id=sa;password=sa"; SqlConnection conn1 = new SqlConnection(strConn1); SqlCommand cmd1 = new SqlCommand(); cmd1.CommandType = System.Data.CommandType.Text; cmd1.CommandText = "SELECT A.Sap_ID,A.Sap_Description,A.DcmClass_ID,A.DeleteDocument,A.De" + "letePage FROM TBLSamplePage AS A,TBLClassRelation AS B WHERE A.DcmCla" + "ss_ID=B.DcmClass_ID AND B.BthClass_ID=@BthClass_ID"; cmd1.Connection = conn1; conn1.Open(); SqlParameter sqlp2 = new SqlParameter(); sqlp2.ParameterName="@BthClass_ID"; sqlp2.DbType= DbType.Int32; sqlp2.Value =bthClassID; sqlp2.Direction = ParameterDirection.Input; sqlp2.IsNullable = false; SqlParameterCollection SqlParameterCollection2 = ((SqlParameterCollection)(cmd1.Parameters)); SqlParameterCollection2.Add(((Object)(sqlp2))); SqlDataReader sqlDataReader1 = cmd1.ExecuteReader(); while(sqlDataReader1.Read()) { //int str =Convert.ToInt32(sqlDataReader[0]); sapID = Convert.ToInt32(sqlDataReader1["Sap_ID"]); sapDescription = Convert.ToString(sqlDataReader1["Sap_Description"]); lr.message(sapDescription.ToString()); } sqlDataReader1.Close(); cmd1.Dispose(); lr.end_transaction("selectSamplePage", lr.AUTO); /*更新文档表中需要更新文档类型的文档的样本页,每个虚拟用户每次迭代只会更新一个文档的文档类型,更新的文档ID需要进行参数化, 参数化统一在最前面进行,这里都使用docID代替*/ //更新动作需要操作多个表 下面是第一个 lr.start_transaction("updateTBLDocument"); string strConn2 = "data source=192.168.0.208;initial catalog=capture;user id=sa;password=sa"; SqlConnection conn2 = new SqlConnection(strConn2); SqlCommand cmd2 = new SqlCommand(); cmd2.CommandType = System.Data.CommandType.Text; cmd2.CommandText ="UPDATE TBLDocument SET Sap_ID=@SamplePageID,Dcm_Name=@DocumentName WH" + "ERE Dcm_ID=@DocumentID"; cmd2.Connection = conn2; conn2.Open(); SqlParameter sqlp3 = new SqlParameter(); sqlp3.ParameterName="@SamplePageID"; sqlp3.DbType= DbType.Int32; sqlp3.Value =sapID; sqlp3.Direction = ParameterDirection.Input; sqlp3.IsNullable = false; SqlParameterCollection SqlParameterCollection3 = ((SqlParameterCollection)(cmd2.Parameters)); SqlParameterCollection3.Add(((Object)(sqlp3))); SqlParameter sqlp4 = new SqlParameter(); sqlp4.ParameterName="@DocumentName"; sqlp4.DbType= DbType.String; sqlp4.Value =sapDescription; sqlp4.Direction = ParameterDirection.Input; sqlp4.IsNullable = false; SqlParameterCollection SqlParameterCollection4 = ((SqlParameterCollection)(cmd2.Parameters)); SqlParameterCollection4.Add(((Object)(sqlp4))); SqlParameter sqlp5 = new SqlParameter(); sqlp5.ParameterName="@DocumentID"; sqlp5.DbType= DbType.Int32; /*指定指定需要更新的文档是哪一个*/ sqlp5.Value =docID; sqlp5.Direction = ParameterDirection.Input; sqlp5.IsNullable = false; SqlParameterCollection SqlParameterCollection5 = ((SqlParameterCollection)(cmd2.Parameters)); SqlParameterCollection5.Add(((Object)(sqlp5))); cmd2.ExecuteNonQuery(); conn2.Dispose(); lr.end_transaction("updateTBLDocument", lr.AUTO); /*删除原来文档类型在属性表中的数据,实际生产中该表还是没有存在数据的,为与客户端的操作同步,模拟该动作*/ //第二个表的更新操作 lr.start_transaction("deleteTBLprority"); string strConn3 = "data source=192.168.0.208;initial catalog=capture;user id=sa;password=sa"; SqlConnection conn3 = new SqlConnection(strConn3); SqlCommand cmd3 = new SqlCommand(); cmd3.CommandType = System.Data.CommandType.Text; cmd3.CommandText ="DELETE FROM TBLProperty WHERE Dcm_ID=@Dcm_ID"; cmd3.Connection = conn3; conn3.Open(); SqlParameter sqlp6 = new SqlParameter(); sqlp6.ParameterName="@Dcm_ID"; sqlp6.DbType= DbType.Int32; /*指定需要更新的文档是哪一个*/ sqlp6.Value =docID; sqlp6.Direction = ParameterDirection.Input; sqlp6.IsNullable = false; SqlParameterCollection SqlParameterCollection6 = ((SqlParameterCollection)(cmd3.Parameters)); SqlParameterCollection6.Add(((Object)(sqlp6))); cmd3.ExecuteNonQuery(); conn3.Dispose(); lr.end_transaction("deleteTBLprority", lr.AUTO); /*根据更新的样本页ID查询该样本页属于哪个文档类,这里主要是模拟客户端中查询出具体的文档类ID用于下面查询文档类的字段*/ lr.start_transaction("selectDocClassID"); string strConn4 = "data source=192.168.0.208;initial catalog=capture;user id=sa;password=sa"; SqlConnection conn4 = new SqlConnection(strConn4); SqlCommand cmd4 = new SqlCommand(); cmd4.CommandType = System.Data.CommandType.Text; cmd4.CommandText ="SELECT * FROM TBLSamplePage WHERE Sap_ID=2"; cmd4.Connection = conn4; conn4.Open(); SqlDataReader sqlDataReader4 = cmd4.ExecuteReader(); while(sqlDataReader4.Read()) { dcmClassID = Convert.ToInt32(sqlDataReader4["DcmClass_ID"]); } sqlDataReader4.Dispose(); lr.end_transaction("selectDocClassID", lr.AUTO); /*从文档类的字段表中查询出该文档类下有哪些字段,然后插入到属性表中,一般文档类下面是存在多个字段的,那么就需要循环把所有字段都插入 到属性表中,供后面的索引阶段使用*/ /*这里插入使用的文档ID需要与上面指定类型的文档ID一致,所以在插入属性表的时候文档ID要使用上面的参数*/ lr.start_transaction("insertTBLprority"); string strConn5 = "data source=192.168.0.208;initial catalog=capture;user id=sa;password=sa"; SqlConnection conn5 = new SqlConnection(strConn5); SqlCommand cmd5 = new SqlCommand(); cmd5.CommandType = System.Data.CommandType.Text; cmd5.CommandText ="SELECT * FROM TBLField WHERE Class_ID=@DcmClass_ID"; cmd5.Connection = conn5; conn5.Open(); SqlParameter sqlp7 = new SqlParameter(); sqlp7.ParameterName="@DcmClass_ID"; sqlp7.DbType= DbType.Int32; sqlp7.Value =dcmClassID; sqlp7.Direction = ParameterDirection.Input; sqlp7.IsNullable = false; SqlParameterCollection SqlParameterCollection7 = ((SqlParameterCollection)(cmd5.Parameters)); SqlParameterCollection7.Add(((Object)(sqlp7))); SqlDataReader sqlDataReader5 = cmd5.ExecuteReader(); while(sqlDataReader5.Read()) { //int str =Convert.ToInt32(sqlDataReader[0]); filedID = Convert.ToInt32(sqlDataReader5["Field_ID"]); SqlConnection conn6 = new SqlConnection(strConn5); SqlCommand cmd6 = new SqlCommand(); cmd6.CommandType = System.Data.CommandType.Text; cmd6.CommandText ="Insert into TBLProperty (Bth_ID,Dcm_ID,Field_ID,Pro_Value) values (@B" + "atchID,@DoctID,@FieldID,'')"; cmd6.Connection = conn6; conn6.Open(); SqlParameter sqlp8 = new SqlParameter(); sqlp8.ParameterName="@BatchID"; sqlp8.DbType= DbType.Int32; sqlp8.Value =bthID+1; sqlp8.Direction = ParameterDirection.Input; sqlp8.IsNullable = false; SqlParameterCollection SqlParameterCollection8 = ((SqlParameterCollection)(cmd6.Parameters)); SqlParameterCollection8.Add(((Object)(sqlp8))); SqlParameter sqlp9 = new SqlParameter(); sqlp9.ParameterName="@DoctID"; sqlp9.DbType= DbType.Int32; /*这里同样需要配合上面对文档ID的参数化*/ sqlp9.Value =docID; sqlp9.Direction = ParameterDirection.Input; sqlp9.IsNullable = false; SqlParameterCollection SqlParameterCollection9 = ((SqlParameterCollection)(cmd6.Parameters)); SqlParameterCollection9.Add(((Object)(sqlp9))); SqlParameter sqlp10 = new SqlParameter(); sqlp10.ParameterName="@FieldID"; sqlp10.DbType= DbType.Int32; sqlp10.Value =filedID; sqlp10.Direction = ParameterDirection.Input; sqlp10.IsNullable = false; SqlParameterCollection SqlParameterCollection10 = ((SqlParameterCollection)(cmd6.Parameters)); SqlParameterCollection10.Add(((Object)(sqlp10))); cmd6.ExecuteNonQuery(); conn6.Dispose(); } sqlDataReader5.Dispose(); lr.end_transaction("insertTBLprority", lr.AUTO); lr.end_transaction("指定文档类型", lr.AUTO); return 0; } } }

浙公网安备 33010602011771号