一、脚本调试

1、回放调试脚本慢,可进行如下设置:

dnf脚本怎么写 java dnf脚本思路_sql

2、bbs回帖脚本调试心得:

思路
①练习先进行tid的关联。回帖需要关联用户id,模块id(fid),帖子(tid)id,但是就登录回帖这个需求,可以在同一个帖子下进行回帖,而不会影响压测的结果,所以,fid和tid都无需进行关联,写死即可;
②在关联上tid后,访问回帖请求,报登录连接不上,先将问题放置。
③对回帖请求中的参数formhash进行关联。在tree视图中,查找产生formhash的请求,进行关联。注意在进行右键关联时,找左右边界相同多的那个值进行关联,这样比较容易命中,而且要注意有特殊需要转义的字符,需要进行转义,也可以用其它的值来进行关联,从而避开转义。
④调试过程中,在找关联关系时,在tree视图中的录制请求视图(display recorded snapshot)查看,回放错误时,结合tress视图中的回放请求视图(show replay snapshot)查看,此处可以查看发送请求的状态是否成功。
⑤脚本回放报错后,除了查看报错信息之外,关注报错信息附近的warning信息或许会对调试有帮助。
⑥脚本调试是个循序渐进的过程,一定不能急躁,相信自己,关联的调试,无外乎就是左右边界值的调整和请求响应值的对应关系,其它业务流程的依赖关系则要具体情况具体分析。

3、一些名词:

①事务:是自己定义的,其设置尽可能的精确,测什么就放什么(OA工作流之类的例外);

②思考时间:

加在事务的外边

为什么要加思考时间 → 实质是缓解服务器压力,减少单位时间段内向发送到服务器请求数

一般压力测试不加思考时间,有的时候为了测试报告好看,不加思考时间,并发量达不到,因单位时间内的请求量过大,服务器处理不过来,这时候,会产生阻塞和错误。虽然还是100个并发,但是加了思考时间,服务器的压力就会减小了。并发量达不到要求,又要上线的时候,加上(哈哈,没节操!)

加了思考时间,tps会降低,前提是服务器的tps没有达到极限,如果服务器的tps达到了极限,加思考时间和不加思考时间没有区别(木桶原理)

设置思考时间是否生效:

dnf脚本怎么写 java dnf脚本思路_dnf脚本怎么写 java_02

什么影响服务器的处理能力呢?cup,一个cpu单核的,一次只能处理一件事(线程)

dnf脚本怎么写 java dnf脚本思路_java_03

pacing也是思考时间,作用于迭代和迭代之间,相对来说think_time比较灵活

③检查点:从请求的返回结果集中取值

检查点是否一定要加:

理论上来说,检查点函数是一定要加的(性能测试的前提条件是请求成功,符合业务规则)

 

加检查点会影响性能:

A、对于写操作来说不加检查点,只需要在场景运行结束后,比对数据库中的数据和通过的事务数(通过的事务数可以在在controller中通过的事务数选项查看)

B、对于查操作来说需要加检查点

dnf脚本怎么写 java dnf脚本思路_dnf脚本怎么写 java_04

④集合点:

dnf脚本怎么写 java dnf脚本思路_dnf脚本怎么写 java_05

集合点策略百分比,模拟瞬时并发

什么时候用:秒杀项目、抢购项目(有些抢购就是一个静态页面,汗颜!!!)

目的:更加真实的模拟用户的瞬时并发概率

dnf脚本怎么写 java dnf脚本思路_java_06

4、关于脚本精简

①性能测试的服务对象是开发,在脚本开发中,可以不考虑图片、css、js等样式;

②搞清楚关联和依赖关系,哪些是必须的,哪些是依赖的,必须+依赖的请求,其他的请求都可以精简掉;

③实际测试中,建议一个action里只放一个事务,即只放一个请求。

 

二、脚本开发

1、http脚本的开发

APP本身就相当于web的前端,都有一个服务器,一般是做http协议通信

接口说明文档

①http接口测试一般用postman;

②所有走https的协议在lr上,都可以用火狐进行录制;

③api脚本回放报错时,如果报安全协议(SSL)错误,在请求前加上:
 web_set_sockets_option("SSL_VERSION","TLS"); //走https协议

④接口测试(http请求、手机接口测试)手写,用如下两个函数:

 web_custom_request
 web_submit_data

手写豆瓣api请求:

dnf脚本怎么写 java dnf脚本思路_dnf脚本怎么写 java_07

A、使用web_custom_request函数

dnf脚本怎么写 java dnf脚本思路_dnf脚本怎么写 java_08

dnf脚本怎么写 java dnf脚本思路_测试_09

dnf脚本怎么写 java dnf脚本思路_dnf脚本怎么写 java_10

B、使用web_submit_data函数

dnf脚本怎么写 java dnf脚本思路_测试_11

如下图这么写时,报错:

dnf脚本怎么写 java dnf脚本思路_sql_12

dnf脚本怎么写 java dnf脚本思路_测试_13

故上述脚本修改如下:

dnf脚本怎么写 java dnf脚本思路_java_14

将下图打开可以查看返回结果:

dnf脚本怎么写 java dnf脚本思路_测试_15

2、webservice脚本的开发

dnf脚本怎么写 java dnf脚本思路_数据库_16

dnf脚本怎么写 java dnf脚本思路_sql_17

dnf脚本怎么写 java dnf脚本思路_dnf脚本怎么写 java_18

dnf脚本怎么写 java dnf脚本思路_sql_19

dnf脚本怎么写 java dnf脚本思路_dnf脚本怎么写 java_20

dnf脚本怎么写 java dnf脚本思路_数据库_21

dnf脚本怎么写 java dnf脚本思路_测试_22

dnf脚本怎么写 java dnf脚本思路_java_23

回放脚本:

dnf脚本怎么写 java dnf脚本思路_java_24

添加新的函数:

dnf脚本怎么写 java dnf脚本思路_测试_25

dnf脚本怎么写 java dnf脚本思路_数据库_26

3、接口功能测试webserver工具:
soatest\soupui(既能做功能又能测性能)

4、实现mysql的增删改查脚本:

方式一、



1 javauser:
 2 /*
 3  * LoadRunner Java script. (Build: _build_number_)
 4  * 
 5  * Script Description: 
 6  *                     
 7  */
 8 import java.sql.Connection;
 9 import java.sql.DriverManager;
10 import java.sql.ResultSet;
11 import java.sql.SQLException;
12 import java.sql.Statement;
13 import com.sun.org.apache.xpath.internal.operations.String;
14 import lrapi.lr;
15 
16 
17 public class Actions
18 {
19 
20 public int init() throws Throwable {
21 
22     Class.forName("com.mysql.jdbc.Driver");// 加载驱动程序
23 
24     String url = "jdbc:mysql://10.10.10.10:36001/message";// URL指向要访问的数据库名message_old
25 
26     String user = "root";// MySQL配置时的用户名
27  
28     String password = "############";// MySQL配置时的密码
29 
30     Connection connection = DriverManager.getConnection(url, user,password);// 连续数据库
31 
32    if (!connection.isClosed()){
33 
34             System.out.println("Succeeded connecting to the Database!");
35    }
36 
37    Statement statement = connection.createStatement();// statement用来执行SQL语句
38 
39    System.out.println("initial_id" + "\t" + "user_id1"+ "\t" + "user_id2");
40 
41    return 0;
42 }//end of init
43 
44 public int action() throws Throwable {
45 
46    String sql ="SELECT * from user WHERE user_id1=238 group by user_id1";
47    ResultSet rs = statement.executeQuery(sql);// 执行SQL语句并返回结果集
48  
49             while (rs.next()) {
50 
51                 System.out.println(rs.getString("initi_id") + "\t"+ rs.getString("user_id1")+"\t"+rs.getString("user_id2"));
52 
53     }
54     
55         return 0;
56 }
57 
58 
59 public int end() throws Throwable {
60 
61     rs.close();//关闭果集
62        connection.close();//数据库连接
63 
64         return 0;
65 }//end of end
66 
67 }



方式二、

init中的代码:



1 #include "Ptt_MySql.h"
 2 vuser_init()
 3 {
 4 
 5     lr_load_dll("libmysql.dll");
 6 
 7     #define MYSQLSERVER   "192.168.2.104"
 8     #define MYSQLUSERNAME  "root"
 9     #define MYSQLPASSWORD   "123456"
10     #define  MYSQLDB     "mysqlwork1"
11     #define  MYSQLPORT    "3306"
12     return 0;
13 }



action中的代码:



1 char  sqlQuery[512];
 2 MYSQL *Mconnection ;
 3 int  MyRc ;
 4 
 5 char *tempname ;
 6 
 7 char tempname2[100];
 8 
 9 Action()
10 {
11 
12 
13      Mconnection  =  lr_mysql_connect(MYSQLSERVER , MYSQLUSERNAME  ,  MYSQLPASSWORD , MYSQLDB , atoi(MYSQLPORT));
14 
15 
16      sprintf(sqlQuery, "insert  into  Student ( name, sex  , birth  , department , address) values ( '张三' , '男' , 1987 , '计算机' , '北京' )");
17 
18      lr_mysql_query(Mconnection, sqlQuery);
19 
20 
21      sprintf(sqlQuery , "update  Student  set  name='王五'   where name='张三' ");
22 
23      lr_mysql_query(Mconnection, sqlQuery);
24 
25 
26 
27       sprintf(sqlQuery, "select id, name, sex  , birth  , department , address  from  Student  where  name = '王五' ");
28 
29       lr_mysql_query(Mconnection, sqlQuery);
30 
31   
32     //row[x][y].cell   x表示列(第一列是0),y表示行(第一行是0)。
33     lr_save_string(row[0][0].cell, "id");
34 
35    /*
36    lr_convert_string_encoding(row[1][0].cell ,"utf-8" ,NULL,"tempname");
37    strcpy(tempname2,lr_eval_string("{tempname}")),
38    lr_save_string(tempname2,"sname");
39    lr_output_message(lr_eval_string("name: {sname}"));
40    */
41 
42     lr_save_string(row[1][0].cell, "sname");
43 
44     lr_save_string(row[2][0].cell, "sex");
45 
46     lr_save_string(row[3][0].cell, "birth");
47 
48     lr_save_string(row[4][0].cell, "department");
49 
50 
51     lr_save_string(row[5][0].cell, "address");
52 
53     
54     lr_output_message(lr_eval_string("id: {id}"));
55 
56     lr_output_message(lr_eval_string("name: {sname}"));
57 
58     lr_output_message(lr_eval_string("sex: {sex}"));
59 
60     lr_output_message(lr_eval_string("birth: {birth}"));
61 
62     lr_output_message(lr_eval_string("department: {department}"));
63 
64     lr_output_message(lr_eval_string("address: {address}"));
65 
66         
67 
68     
69 
70      sprintf(sqlQuery  , "delete  from  Student  where  name='王五' ");
71 
72       lr_mysql_query(Mconnection, sqlQuery);
73 
74     //Disconnect from MySQL #断开数据库连接
75     lr_mysql_disconnect(Mconnection);
76 
77     return 0;
78 }



连接jdbc增删改查用jemter实现的效果比较好,因不需要频繁的连接关闭数据库。 

------------------------------------------------------------------------