友好连接

2008年11月17日星期一

Loadrunner 参数 使用小结

在做负载或者压力测试时,很多人选择使用了Loadrunner测试工具。该工具的基本流程是先将用户的实际操作录制成脚本,然后产生数千个虚拟用户运行脚本(虚拟用户可以分布在局域网中不同的PC机上),最后生成相关的报告以及分析图。但是在录制脚本的过程中会遇到很多实际的问题,比如不同的用户有不同的使用数据,这就牵涉到参数的设置问题。本文就Loadrunner中参数的设置进行说明,希望对大家有所帮助。
录制程序运行的过程中,VuGen(脚本生成器) 自动生成了包含录制过程中实际用到的数值的脚本。如果你企图在录制的脚本中使用不同的数值执行脚本的活动(如查询、提交等等),那么你必须用参数值取代录制的数值。这个过程称为参数化脚本。
本文主要包括如下内容:理解参数的局限性、建立参数、定义参数的属性、理解参数的类型、为局部数据类型设置参数的属性、为数据文件设置参数的属性、从已经存在的数据库中引入数据。
除了GUI,以下的内容适合于各种类型的用户脚本。
一、关于参数的定义
在你录制程序运行的过程中,脚本生成器自动生成由函数组成的用户脚本。函数中参数的值就是在录制过程中输入的实际值。
例如,你录制了一个Web应用程序的脚本。脚本生成器生成了一个声明,该声明搜索名称为“UNIX”的图书的数据库。
当你用多个虚拟用户和迭代回放脚本时,也许你不想重复使用相同的值“UNIX”。那么,你就可以用参数来取代这个常量。
结果就是你可以用指定的数据源的数值来取代参数值。数据源可以是一个文件,也可以是内部产生的变量。
用参数表示用户的脚本有两个优点:
① 可以使脚本的长度变短。
② 可以使用不同的数值来测试你的脚本。例如,如果你企图搜索不同名称的图书,你仅仅需要写提交函数一次。在回放的过程中,你可以使用不同的参数值,而不只搜索一个特定名称的值。
参数化包含以下两项任务:
① 在脚本中用参数取代常量值。
② 设置参数的属性以及数据源。
参数化仅可以用于一个函数中的参量。你不能用参数表示非函数参数的字符串。
另外,不是所有的函数都可以参数化的。
二、参数的创建
可以指定名称和类型来创建参数。不存在对脚本中参数个数的限制。
在Web程序的用户脚本中,你可以使用如下过程在基于文本的脚本视图中创建参数。或者,也可以在基于图标的树形视图中创建参数。
要创建一个参数:
1、 将光标定位在要参数化的字符上,点击右键。打开弹出菜单。
2、 在弹出菜单中,选择“Replace with a Parameter”。选择或者创建参数的对话框弹出。
3、 在“Parameter name”中输入参数的名称,或者选择一个在参数列表中已经存在的参数。
4、 在“Parameter type”下拉列表中选择参数类型。
5、 点击“OK”,关闭该对话框。脚本生成器便会用参数中的值来取代脚本中被参数化的字符,参数用一对“{}”括住。
注意:在参数化CORBA或者General-Java 用户脚本的时候,必须参数化整个字符串,而不是其中的部分。
另外注意:除了Web或者WAP,缺省的参数括号对于任何脚本都是 “{}”。你可以在“General Options”对话框中的“Parameterization”标签(Tools>General Options)中定义参数括号种类。
6、 用同样的参数替换字符的其余情况,选中参数,点击右键,弹出菜单。从弹出的菜单中,选择“Replace More Occurrences”。搜索和替换对话框弹出。
“Find What”中显示了你企图替换的值。“Replace With”中显示了括号中参数的名称。
选择适当的检验框来匹配整个字符或者大小写。如果要搜索规则的表达式(.,!,?等等),选中“Regular Expression”检验框,然后点击“Replace”或者“Replace All”。
注意:小心使用“Replace All”,尤其替换数字字符串的时候。脚本生成器将会替换字符出现的所有情况。
7、 如果想用以前定义过的参数来替换常量字符串的话,选中该字符串,点击右键,然后选择“Use Existing Parameter”,子菜单“Use Existing Parameters”弹出。
从子菜单“Use Existing Parameters”选择参数,或者用“Select from Parameter List”来打开参数列表对话框。
注意:如果用以前定义过的参数来替换常量字符串的话,那么,使用“Parameter List”非常方便。同时,还可以查看和修改该参数的属性。
8、 对于已经用参数替换过的地方,如果想取回原来的值,那么,就在参数上点击右键,然后选择“Restore Original Value”。
在Web用户脚本的树形视图中创建参数
在Web用户脚本的树形视图中创建一个参数的步骤
1、将光标定位在企图参数化的地方,点击右键,从弹出的菜单中选择“Properties”。则相关的属性对话框打开。
2、点击在要参数化的参量的旁边的“ABC”形状的图标。“Select or Create Parameter”对话框打开。
3、在“Parameter name”中输入参数的名称,或者从列表中选择一个已经存在的参数。
4、在“Parameter type”中输入参数的类型。
5、点击“OK”关闭该对话框。用户脚本生成器会用参数来替换最初的字符串常量,并用一个表格形状的图标替换“ABC”形状的图标。
6、要恢复参数化以前的值,点击图标,然后从弹出的菜单中选择“Undo Parameter”,则以前的值便会重现。
三、定义参数的属性
创建参数完成后,就可以定义其属性了。参数的属性定义就是定义在脚本执行过程中,参数使用的数据源。
在Web用户脚本中,你既可以在基于文本的脚本视图中定义参数属性,也可以在基于图标的树形视图中定义参数属性。下面的过程将教你如何在基于本文的脚本视图中定义参数属性。
定义参数属性步骤:
1、 在参数上点击右键,有菜单弹出。
2、 在弹出的菜单中,选择“Parameter Properties”。参数属性对话框打开,显示和当前参数类型相关的属性。
3、 输入参数的属性值。
4、 点击“Close”关闭参数属性对话框。
在Web用户脚本的树形视图中定义参数的属性
1、 将关标定位在参数上,然后点击右键,选择“Properties”。属性对话框打开。
2、 点击要定义属性的参数旁边的表格形状按钮,点击右键,选择“Parameter Properties”。参数属性对话框打开,和参数类型相关的属性显示出来。
3、 输入参数的属性。
4、 点击“Close”关闭参数属性对话框。
使用参数列表
使用参数列表可以在任意时刻查看所有的参数,创建新的参数、删除参数,或者修改已经存在参数的属性。
要使用参数列表:
1、 点击参数列表按钮或者用“Vuser>Parameter List”。参数列表对话框打开。
2、 要创建新的参数,点击“New”按钮。新的参数则被添加在参数树中,该参数有一个临时的名字,你可以给它重新命名,然后回车。
注意:不要将一个参数命名为“unique”,因为这个名称是用户脚本生成器本身的。
设置参数的类型和属性,点击“OK”,关闭参数列表对话框。
注意:用户脚本生成器创建新的参数,但是不会自动用该参数在脚本中替换任意选中的字符串。
3、 要删除已有的参数,那么,要先从参数树中选择该参数,点击“Delete”,然后确认你的行为即可。
4、 要修改已有参数,那么,要先从参数树中选择该参数,然后编辑参数的类型和属性。
四、理解参数的类型
在你定义参数属性的时候,要指定参数值的数据源。你可以指定下列数据源类型的任何一种:
Internal Data 虚拟用户内部产生的数据。
Data Files 存在于文件中的数据。可能是已存在的文件或者是用脚本生成器新创建的。
User-Defined Functions 调用外部DLL函数生成的数据
Internal Data包括以下几种:
1. Date/Time
Date/Time用当前的日期/时间替换参数。要指定一个Date/Time格式,你可以从菜单列表中选择格式,或者指定你自己的格式。这个格式应该和你脚本中录制的Date/Time格式保持一致。
2. Group Name
Group Name 用虚拟用户组名称替换参数。在创建scenario的时候,你可以指定虚拟用户组的名称。当从用户脚本生成器运行脚本的时候,虚拟用户组名称总是None。
3. Load Generator Name
Load Generator Name用脚本负载生成器的名称替换参数。负载生成器是虚拟用户在运行的计算机。
4. Iteration Number
Iteration Number用当前的迭代数目替换参数。
5. Random Number
Random Number用一个随机数替换参数。通过指定最大值和最小值来设置随机数的范围。
6. Unique Number
Unique Number用一个唯一的数字来替换参数。你可以指定一个起始数字和一个块的大小。
7. Vuser ID
Vuser ID用分配给虚拟用户的ID替换参数,ID是由Loadrunner的控制器在scenario运行时生成的。如果你从脚本生成器运行脚本的话,虚拟用户的ID总是-1。
五、数据文件
数据文件包含着脚本执行过程中虚拟用户访问的数据。局部和全局文件中都可以存储数据。可以指定现有的ASCII文件、用脚本生成器创建一个新的文件或者引入一个数据库。在参数有很多已知值的时候数据文件非常有用。
数据文件中的数据是以表的形式存储的。一个文件中可以包含很多参数值。每一列包含一个参数的数据。列之间用分隔符隔开,比如说,用逗号。
对数据文件设置参数属性
如果使用文件作为参数的数据源,必须指定以下内容:
1. 文件的名称和位置
2. 包含数据的列
3. 文件格式,包括列的分隔符
4. 更新方法
如果参数的类型是“File”,打开参数属性(Parameter Properties)对话框,设置文件属性如下:
1. 在“File path”中输入文件的位置,或者点击“Browse”指定一个已有文件的位置。缺省情况下,所有新的数据文件名都是“parameter_name.dat”,注意,已有的数据文件的后缀必须是.dat。
2. 点击“Edit”。记事本打开,里面第一行是参数的名称,第二行是参数的初始值。使用诸如逗号之类的分隔符将列隔开。对于每一新的表行开始一行新的数据。
注意:在没有启动记事本的情况下如果想添加列,就在参数属性对话框中点击“Add Col”,那么“Add new column”对话框就会弹出。输入新列的名称,点击“OK”。脚本生成器就会添加该列到表中,并显示该列的初始值。
3. 在“Select Column”部分,指明包含当前参数数据的列。你可以指定列名或者列号。列号是包含你所需要数据的列的索引。列名显示在每列的第一行(row 0)。
4. 在“Column delimiter”中输入列分隔符,你可以指定逗号、空格符等等。
5. 在“First data line”中,在脚本执行的时候选择第一行数据使用。列标题是第0行。若从列标题后面的第一行开始的话,那就在“First data line”中输入1。如果没有列标题,就输入0。
6. 在“Select next row”中输入更新方法,以说明虚拟用户在脚本执行的过程中如何选择表中的数据。方法可以是:连续的、随机的、唯一的、或者与其它参数表的相同行。
7. 选中“Advance row each iteration”表示虚拟用户在每次迭代都使用新的一行数据而不是所有的迭代都使用相同的数据。
从文件中更新参数值
若使用文件中的数值,脚本生成器会要求你指定给参数分配数值给的方法。可用的方法有:
1. 顺序(Sequential):该方法顺序地给虚拟用户分配参数值。如果正在运行的虚拟用户访问数据表的时候,它会取到下一行中可用的数据。
2. 随机(Random):该方法在每次迭代的时候会从数据表中取随机数
3. 使用种子取随机顺序(Use Random Sequence with Seed):如果从Loadrunner的控制器来运行scenario,你可以指定一个种子数值用于随机顺序。每一个种子数值在测试执行的时候代表了一个随机数的顺序。无论你何时使用这个种子数值,在scenario中同样的数据顺序就被分配给虚拟用户。如果在测试执行的时候发现了一个问题并且企图使用同样的随机数序列来重复测试,那么,你就可以启动这个功能(可选项)。
4. 唯一(Unique):Unique方法分配一个唯一的有顺序的值给每个虚拟用户的参数。
5. 与以前定义的参数取同一行(Same Line As ):该方法从和以前定义过的参数中的同样的一行分配数据。你必须指定包含有该数据的列。在下拉列表中会出现定义过的所有参数列表。注意:至少其中的一个参数必须是Sequential、Random或者Unique。
如果数据表中有三列,三个参数定义在列表中:id1,name1和title1,如下:。
ID Name Title
132 Kim Manager
187 Cassie Engineer
189 Jane VP
对于参数id1,你可以指示虚拟用户使用Random方法,而为参数name1和title1就可以指定方法“Same Line as id1”。所以,一旦ID“132”被使用,那么,姓名(Name)“Kim”和职位(Title)“Manager”同时被使用。
六、从已存在的数据库中导入数据
Loadrunner允许你利用参数化从已经存在的数据库中导入数据。可以使用下列两种方式之一:
1. 使用Microsoft Query(要求在系统上先安装MS Query)。
2. 指定数据库连接字符串和SQL语句。
用户脚本生成器在从数据库中导入数据的过程中提供了一个向导。在向导中,你指明如何导入数据-通过MS Query创建查询语句或者直接书写SQL语句。在导入数据以后,以.dat为后缀并作为正规的参数文件保存。
要开始导入数据库中数据的过程,在参数属性对话框中点击“Data Wizard”,则,数据库查询向导弹出。
要创建新的查询
1. 选择“Create new query”。如果需要MS Query的帮助,选择“Show me how to use Microsoft Query”,然后点击“Finish”。
如果你还没有安装Microsoft Query,Loadrunner会提示你这个功能不可用。在进行之前,从Microsoft Office中安装MS Query。
2. 在Microsoft Query中遵循以下步骤,导入期望的表和列。
3. 在完成数据的导入后,选择“Exit and return to Virtual User Generator”,然后点击“Finish”。在参数属性对话框中数据库记录以data文件的形式显示出来。
要在MS Query中编辑并查看数据,选择“View data or edit in Microsoft Query”。若要结束,则选择“File>Exit and return to Virtual User Generator”返回到脚本生成器。
4. 在“Select Column”部分,指定包含当前参数数据的列可以指定列号或者列名。注意:列标题默认为第0行(row 0)。
5. 从“Select next row”列表中选择一个更新方法来告诉虚拟用户在脚本指定的过程中如何选择表中的数据。可选项是:Sequential、Random、Unique或者Same Line As。其中每一项的含义文章前面已经讲述,就不再赘述。
6. 如果选择“Advance row each iteration”,虚拟用户在每次迭代的时候会使用新的一行的数据而不是重复同样的数据。
要指定数据库连接或者SQL语句
1. 选择“Specify SQL Statement”,然后点击“Next”。
2. 点击“Create”指定一个新的连接字符串。选择数据源的窗口弹出。
3. 选择已有的数据源,或者点击“New”创建一个新的数据源。向导将提示你穿过创建ODBC数据源的过程。在完成后,连接字符串就会在连接字符串框中显示出来。
4. 在SQL框中,输入或者粘贴SQL语句。
5. 点击“Finish”继续SQL语句并导入数据。数据库记录将以data文件的形式显示在参数属性框中。
6. 在“Select Column”部分中,指定包含当前参数数据的列。你可以指定列号或者列名。
7. 从“Select next row”列表中选择一个更新方法来告诉虚拟用户在脚本指定的过程中如何选择表中的数据。可选项是:Sequential、Random、Unique或者Same Line As。
8. 如果选择“Advance row each iteration”,虚拟用户在每次迭代的时候会使用新的一行的数据而不是重复同样的数据。
转自:http://www.cnblogs.com/junzhongxu/

Code Snippets for LoadRunner

1. How to choose the option randomly?
Description:

If one option needs to be chosen randomly in below figure, what can we do in LR?
图略


Solution:

1. Use web_reg_save_param with proper LB, RB and Ord=All to get all options’ value into an array.

2. Get a random value from array.

3. In next web_sumbit_form or web_url use the value.

Code:

Action()

{

//declare variables

int flightCount;

char Flight[100];

//replace with your web_reg_save_param

web_reg_save_param("flightList",

"LB=outboundFlight value=",

"RB=>",

"Ord=All", //Make sure Ord's value is All.

LAST);

//replace with your web submit or web url

web_submit_form("reservations.pl",

"Snapshot=t4.inf",ITEMDATA,

"Name=depart", "Value=Shanghai", ENDITEM,

"Name=arrive", "Value=Beijing", ENDITEM,

LAST);

//get the count of flightList array.

flightCount=atoi( lr_eval_string("{flightList_count}") );

/*save random flight to Flight string.

1 + rand() % flightCount: Generate a Random Number

{flightList_1}: get the first value in flightList

*/

sprintf (Flight,"{flightList_%d}",1 + rand() % flightCount );

//save Flight to String RandFlight

lr_save_string( lr_eval_string (Flight),"RandFlight" );

lr_message( lr_eval_string("{RandFlight}") );

//Use RandFlight in next step

web_submit_form("reservations.pl_2",

"Snapshot=t5.inf",ITEMDATA,

"Name=outboundFlight", "Value={RandFlight}", ENDITEM,

LAST);

return 0;

}

2. How to generate a unique input?
Description:

In the below figure we need to input unique values for the Username. How can we make sure that every username is unique during thousand iterations run?

Solution:

Controller will assign a unique VuserId to every Vuser when we start to run a Vuser. The following is two solutions we can use.

1. VuserId + iteration No

2. VuserId + Current Time (If name will be created twice in one iteration)

Code:

Action()

{

//declare variables

char testname[100];

char *VuserId;

//create a VuserId type parameter named RunningVuserId in Parameter list

VuserId=lr_eval_string("{RunningVuserId}");

//The value saved in ParamTimeStamp is the number of milliseconds since midnight January // 1st, 1970.

web_save_timestamp_param("ParamTimeStamp", LAST);

//Create testname as format: VuserId_ ParamTimeStamp.

strcpy(testname,VuserId);

strcat(testname,"_");

strcat(testname,lr_eval_string("{ParamTimeStamp}"));



lr_save_string(testname,"UniqueTestname");

lr_output_message("the value is %s", lr_eval_string("{UniqueTestname}"));

return 0;

}

3. How to check for download function?
Description:

Sometimes we do stress test that download a file from server. When we record this step, our script will generate web_url when we click download link or button. But when you replay it, this web_url always will pass and no file will actually be downloaded in the controller’s location. We can use web_reg_find to check whether we load page properly. How can we check here?

Solution:

The file won't be downloaded (Physically) to the folder but you can determine whether the request was successful or not by determining the size returned by the request. You can use the function "web_get_int_property" and "HTTP_INFO_DOWNLOAD_SIZE” option in that function to determine the size.

Code:

int flen;

//your web url that download file

// get the download file's size.

flen = web_get_int_property(HTTP_INFO_DOWNLOAD_SIZE);

if(flen > 0)

{

lr_end_transaction("S1_D_download", LR_AUTO);

}

else

{

lr_end_transaction("S1_D_download", LR_FAIL);

}



4. How to save file when you download in LR?
Description:

In case 3, if you also want to save the file to a location, what can be done?

Solution:

We can use web_reg_save_param to save all bytes downloaded from server and then these bytes could be written to a location.

Code:

int flen;

long filedes;

int i;



web_reg_save_param("FILED","LB=","RB=","Search=Body",LAST);

//your web url that download file



// get the download file's size.

flen = web_get_int_property(HTTP_INFO_DOWNLOAD_SIZE);

if(flen > 0)

{

//create a new file. If you run the script in controller, you can use unique //name in Case 2 to generate a unique file.

if((filedes = fopen("c:\\test.xls", "wb")) == NULL)

{

lr_output_message("Open File Failed!");

lr_end_transaction("file_download", LR_FAIL);

}

//write the data which are got from server to the file created in your

// location.

i = fwrite(lr_eval_string("{FILED}"), flen, 1, filedes);

lr_output_message("Successfully wrote %d", i );

lr_end_transaction("file_download", LR_AUTO);

fclose(filedes);

}

else

{

lr_end_transaction("S1_D_download", LR_FAIL);

}

5. How to get a substring in LR?
Description:

If the requirement demands us to parse a string, we can use LR_SAVE_VAR.

Solution: See code

Code:

Action()

{

char *mystr = "I come from Shanghai";

lr_save_var(mystr + 12, 8, 0, "Mycity");

lr_output_message("My city is %s",lr_eval_string("{Mycity}"));

return 0;

}



6. How to reformat date?
Description:

When we get some date, but the format is not our expectation, what can we do?

Solution: See code

Code:



char *ReqDate;

lr_save_string("10/11/2006","MyDate");

lr_save_var(lr_eval_string("{MyDate}"),2,0,"Date");

lr_save_var(lr_eval_string("{MyDate}")+3,2,0,"Month");

lr_save_var(lr_eval_string("{MyDate}")+6,4,0,"Year");

ReqDate = lr_eval_string("{Month}/{Date}/{Year}");

lr_output_message("date is %s",ReqDate);
转自:http://www.cnblogs.com/junzhongxu/

你必须学会的几个常用网络测试命令

如果你是一个网络维护人员,那么肯定要经常处理网络故障,了解和掌握下面几个命令将会有助于您更快地检测到网络故障所在,从而节省时间,提高效率。

  Ping

  Ping是测试网络联接状况以及信息包发送和接收状况非常有用的工具,是网络测试最

  常用的命令。Ping向目标主机(地址)发送一个回送请求数据包,要求目标主机收到请求后给予答复,从而判断网络的响应时间和本机是否与目标主机(地址)联通。

  如果执行Ping不成功,则可以预测故障出现在以下几个方面:网线故障,网络适配器配置不正确,IP地址不正确。如果执行Ping成功而网络仍无法使用,那么问题很可能出在网络系统的软件配置方面,Ping成功只能保证本机与目标主机间存在一条连通的物理路径。

  命令格式:

  ping IP地址或主机名 [-t] [-a] [-n count] [-l size]

  参数含义:

  -t不停地向目标主机发送数据;

  -a 以IP地址格式来显示目标主机的网络地址 ;

  -n count 指定要Ping多少次,具体次数由count来指定 ;

  -l size 指定发送到目标主机的数据包的大小。

  例如当您的机器不能访问Internet,首先您想确认是否是本地局域网的故障。假定局域网的代理服务器IP地址为202.168.0.1,您可以使用Ping避免202.168.0.1命令查看本机是否和代理服务器联通。又如,测试本机的网卡是否正确安装的常用命令是ping 127.0.0.1。

  Tracert

  Tracert命令用来显示数据包到达目标主机所经过的路径,并显示到达每个节点的时间。命令功能同Ping类似,但它所获得的信息要比Ping命令详细得多,它把数据包所走的全部路径、节点的IP以及花费的时间都显示出来。该命令比较适用于大型网络。

  命令格式:

  tracert IP地址或主机名 [-d][-h maximumhops][-j host_list] [-w timeout]

  参数含义:

  -d 不解析目标主机的名字;

  -h maximum_hops 指定搜索到目标地址的最大跳跃数;

  -j host_list 按照主机列表中的地址释放源路由;

  -w timeout 指定超时时间间隔,程序默认的时间单位是毫秒。

  例如大家想要了解自己的计算机与目标主机www.cce.com.cn之间详细的传输路径信息,可以在MS-DOS方式输入tracertwww.cce.com.cn。

  如果我们在Tracert命令后面加上一些参数,还可以检测到其他更详细的信息,例如使用参数-d,可以指定程序在跟踪主机的路径信息时,同时也解析目标主机的域名。

  Netstat

  Netstat命令可以帮助网络管理员了解网络的整体使用情况。它可以显示当前正在活动的网络连接的详细信息,例如显示网络连接、路由表和网络接口信息,可以统计目前总共有哪些网络连接正在运行。

  利用命令参数,命令可以显示所有协议的使用状态,这些协议包括TCP协议、UDP协议以及IP协议等,另外还可以选择特定的协议并查看其具体信息,还能显示所有主机的端口号以及当前主机的详细路由信息。

  命令格式:

  netstat [-r] [-s] [-n] [-a]

  参数含义:

  -r 显示本机路由表的内容;

  -s 显示每个协议的使用状态(包括TCP协议、UDP协议、IP协议);

  -n 以数字表格形式显示地址和端口;

  -a 显示所有主机的端口号。

  ipconfig

  ipconfig命令以窗口的形式显示IP协议的具体配置信息,命令可以显示网络适配器的物理地址、主机的IP地址、子网掩码以及默认网关等,还可以查看主机名、DNS服务器、节点类型等相关信息。其中网络适配器的物理地址在检测网络错误时非常有用。

  命令格式:

  ipconfig[/?] [/all]

  参数含义:

  /all 显示所有的有关IP地址的配置信息;

  /batch [file] 将命令结果写入指定文件;

  /renew_ all 重试所有网络适配器;

  /release_all 释放所有网络适配器;

  /renew N 复位网络适配器 N;

  /release N 释放网络适配器 N。
转自:http://www.cnblogs.com/junzhongxu/

2008年11月13日星期四

手机的各项性能测试

表面装饰测试:

1.磨擦测试(Abrasion Test - RCA)

测试环境:室温。

试验方法:将手机外壳固定在RCA试验机上,用175g力摩擦300cycles。

检验标准:耐磨点涂层不能脱落,不可露出底材质地。

2.附着力测试(Coating Adhesion Test)

测试环境:室温

试验方法:使用百格刀刻出100个1平方毫米的方格,划格的深度以露出底材为止,再用3M610号胶带纸用力粘贴在方格面,1分钟后迅速以90度的角度撕脱,检查方格面油漆。

检验标准:方格面油漆脱落应小于3%。

测试环境:60 oC,90%RH

试验方法:把滤纸放于酸性或碱性溶液充分浸透,用胶带将浸有酸性或碱性溶液的滤纸粘在手机外壳喷漆表面,并且确保试纸与手机外壳喷漆表面充分接触,然后放在测试环境中,48小时后,将手机外壳从测试环境中取出,并且放置2小时后,检查手机外壳表面。

检验标准:喷漆表面无变色、起皮、脱落、褪色等异常。

3.硬度测试(Hardness Test)

测试环境:室温

试验方法:用2H铅笔,在45度角下,以1Kg的力度在机壳及镜盖表面划出3~5cm长的线条。

检验标准:用橡皮擦去铅笔痕迹后,应不留下划痕。

4.镜盖摩擦测试(Lens Scratch Test)

测试环境:室温

试验方法:以1Kg的力用棉布作用于手机外屏镜盖表面,接触面为10mm直径的圆,往复摩擦20,000次,行程20mm,速度30次/分钟。

检验标准:镜盖表面没有明显划痕,透明度没有变化。

5.紫外线照射测试(UV illuminant Test)

测试环境:60° C

试验方法:在温度为60° C,紫外线为340W/mm2的光线下直射油漆表面48小时。试验结束后将手机外壳取出,在常温下冷却2小时后检查喷漆表面。

检验标准:油漆表面应无褪色及色变现象。手机结构测试标准

  1.全参数测试

Full Parametric Test 25℃±5℃, 60%±15%RH (room ambient),功能、外观及参数测试全通过。

  2.高温操作测试

High Temperature Operation +55℃,2h,开机状态。

  3.低温操作测试

Low Temperature Operation -25℃,2h,开机状态。

  4.热冲击测试

  Thermal Shock Test 冷热冲击是在15秒内,实现?40℃ 和+85℃的瞬间转换。且在每个温度停留30分钟,重复转换30次。

  5 温度循环测试

  Temperature Cycle Test 25℃±5℃, 60%±15%RH,1h→ +70℃,25%RH,1h →+40℃,90%RH,1h → -30℃, 1h→ 25℃±5℃, 60%±15%RH; 27 循环,关机状态。

  6.静电放电测试

ESD Test 直接放电电压(±4V),空气放电电压 ( ±8KV)。

  7.高温高湿存贮测试

High Temp.& Humid. Storage 裸机,关机,65℃,90%RH,持续48小时。

  8.低温存贮测试

Low Temp. Storage 裸机,关机,-30℃,持续48小时。

  9.卡通箱振动测试

  Carton-packed Vibration Test 类型/ Type:正弦振动/ Sinusoidal Sweep;

  方向/ Direction:三个轴向/ Three orthogonal axes;

  加速度/ Acceleration:1m/s2 (5~200 Hz ), 0.3m/s2 (200~500 Hz );

  持续时间/ Duration:2小时/2h/axis。
转自:http://www.cnblogs.com/junzhongxu/

为何要在性能测试中设置考虑时间

考虑时间Thinking Time指的是在性能测试脚本中,事务与事务之间,会有一些短暂的停顿,就好像真实用户在操作时,两次操作之间需要考虑一下。比如用户注册的时候,在打开注册页面到提交注册页面之间,是有一段考虑时间的(用户在填写个人信息)。
下面就讨论一下在性能测试实战中,为什么要设置考虑时间。

先说一个概念:吞吐量,这指的是服务器系统(包括软件和硬件)单位时间内处理业务的数量。我们现在做一个小试验,写一个小程序,执行一个简单的业务,并且在程序中进行计时,计算每分钟能执行多少次。然后当我们运行1路这个程序的时候,每分钟能完成约6万次。好,现在问一个问题,如果我们起2路,是不是每一路都能达到 6万/分钟 的吞吐量?

试验发现,当运行2路的时候,两个程序的数值都降了下来,但是它们的总和仍然是6万次。而且不管我们起多少路,这些程序的性能总和都接近于6万。

这就好像一个人1分钟最快能吃1个馒头,你让他一个一个吃,他两分钟能吃2个,如果你让他一手拿一个,同时吃,他两分钟吃不了4个,还是只能吃两个。

我们不是在说“考虑时间”么,哈哈,别急,因为上面的问题必须要先说清楚。

如果我们需要进行性能测试的业务是一个单纯的业务,就好像上面举的那个例子一样,那么测试脚本中就不需要设置“考虑时间”,因为不管你用什么方法测试,一个服务系统处理单一业务的吞吐量总是一个定值。

但是在实际环境里面,往往一个系统都是要处理多种业务,并且这些业务之间是有逻辑关系的。举例说明,比如一个论坛系统,每天最常处理的业务有两个:A打开帖子、B回复帖子。那么每天系统处理AB业务的总数是不是一样的呢,答案很明显,看帖子多,回复的少一些。假设A:B=2:1。

好,如果我们不设置考虑时间,起2路A的脚本,1路B的脚本进行性能测试,我们会得到什么结果呢?我们会得到这两个业务的吞吐量,并且能算出每个小时系统完成A、B业务的总数,吞吐量 × 时间 = 总数。

这时我们发现,同样时间,AB业务的处理总数却不是2:1的关系,这是为什么呢?原因是这样的,我们在跑AB脚本的时候,这两组脚本都在尽全力争夺服务器的资源,他们的并发路数虽然是2:1,但是给服务器的压力却不一定是2:1,可能会出现偏差,测试结果就是最好的证据。A查看帖子由于响应时间短,因此跑的次数更多,最后的比例可能是4:1。

那么这样的结果有什么问题呢。总结为一句话:测试环境的业务和真实环境不符,这样测出的数据没有价值。即使测试通过,也不能证明真实环境是ok的;或者即使测试不通过,也不能说明真实环境不ok,呵呵。

比如上面的例子,如果我们测出的结果是B回复帖子的吞吐量不够,响应时间太长,那可能是因为A业务抢走了过多的,本不属于A的资源,而引起了B的性能降低。

说到这里,大家应该明白了,我们设置考虑时间,是为了保证测试复合业务的时候,各个业务之间的比例关系符合我们的真实生产环境。