JMeter工具:常用协议脚本开发(BeanShell Sampler, Debug Sampler, FTP/Java/JDBC请求, JUnit request, SOAP/XML-RPC)

目录

1. BeanShell Sampler

1.1 BeanShell Timer

1.2 BeanShell PreProcessor

1.3 BeanShell Sampler

2. Debug Sampler

3. FTP 请求

4. Java 请求

4.1 自带的两个Java请求类

4.2 实例:模仿JavaTest, SleepTest,扩展Java请求元件

5. JDBC 请求

5.1 JDBC 连接池设置

5.2 添加 JDBC Request

6. JUnit Request

6.1 JUnit 简介

6.2 JUnit 参数

6.3 JMeter JUnit Request

7. SOAP/XML-RPC Request

7.1 WebServices目前主流的实现方式有三种

7.2 SOAP/XML-RPC Request


1. BeanShell Sampler

1.1 BeanShell Timer

Script脚本区域:可以在该区域写BeanShell脚本,在脚本中可以调用JMeter的运行属性。

(1)Log:直接可以调用log类来写日志。比如log.error()。

(2)Ctx:可以通过获取JmeterContent实例来获取运行时信息(线程数,线程状态等),比如ctx.getThreadNum()。

(3)Vars:能够访问变量获取对应的值,也可以设置变量。比如vars.put("name", "Sheryl"), vars.get("name")。

(4)Props:可以直接访问JMeter的属性,也可以设置属性值。JMeter的属性在jmeter.properties中。比如: props.put("log_level.jmeter","ERROR"), props.get("log_level.jmeter")。即在运行过程中,我们可以用BeanShell来修改JMeter属性。

(5)Prev:可以访问前面Sampler的结果。BeanShell支持调用Java方法的脚本语言。

BeanShell脚本语言语法: http://www.beanshell.org/ 

 小结:

我们可以用云BeanShell来访问及设置属性,访问及设置变量,记录日志。

在定时器,前置处理器,后置处理器,Sampler,断言,监听器中,都可以用到BeanShell。

在JMeter中只要涉及到BeanShell的,脚本编写方式都一样,访问的资源也都一样。

JmeterContent(ctx)类的常用方法如下:

 

1.2 BeanShell PreProcessor

1.3 BeanShell Sampler

(1)BeanShell Sampler跟BeanShell定时器,BeanShell前置处理器等有共性。脚本一样,仅配置项有变化。

(2)BeanShell Sampler作为Sampler, 即用来模拟向被测系统发起请求,JMeter会记录取样结果(TPS,响应时间等性能指标)。

(3)BeanShell支持Java对象的调用,可直接通过BeanShell来调用Java程序(类似接口测试)。

(4)实例:BeanShell调用Java接口的例子

步骤:

1)编写Java程序

2)将Java程序打成jar包

3)把jar包加入JMeter脚本的类路径

4)在BeanShell取样器中编写BeanShell脚本

package com.seling.test;

public interface BeanUtil {
    public String getUserName();
    public String getAddress();
    public int mul(int i);
}
package com.seling.test;

public class BeanShellEg implements BeanUtil{
    private String userName;
    private String address;

    public BeanShellEg(String name){
        this.userName = name;
    }
    public BeanShellEg(String name, String address){
        this.userName = name;
        this.address = address;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public int mul(int i) {
        return i*i;
    }
}
package com.seling.test;

public class BeanShellTest {
    public static void main(String[] args) {
        BeanShellEg bs = new BeanShellEg("Sheryl", "China");
        System.out.println(bs.getUserName() + " is in " + bs.getAddress());
    }
}

 

(5)如何将被引用的类加入到类加载路径

 如果不加载被引用的类,则BeanShell找不到相应的类,运行报错。

解决办法有两个:

1)在测试计划中导入被引用的程序的jar包形式。

2)将引用包和依赖包放到JMeter默认的包加载路径:%JMETER_HOME%\lib。

引用包:是BeanShell程序调用的Java类所在的包。比如BeanShellTest1211.jar

依赖包:如果引用包中的类又依赖于其他包中的类,这个包就是引用包的依赖包,也需要发布到类加载路径。即:直接引用或间接引用的包都需要发布到类加载路径。建议用该方法。

(6)BeanShell支持访问哪些属性和变量

上文BeanShell Timer能访问的属性和变量,BeanShell Sampler也匹配这些功能。

此外,作为Sampler, 它还多出4个项目:

1)SampleResult:可以访问Sampler对应的结果对象,即能够让你查询与编辑其中的属性。

2)ResponseCode:可以引用此属性自行设置Samler的返回码,一般http请求成功设置为200。

3)ResponseCode:可以引用此属性自行设置响应消息内容,默认为OK。

4)IsSuccess:可以引用它来决定Sampler产生的事务是否成功。

 

2. Debug Sampler

Debug Sampler和察看结果树结合使用,可以满足下方的需求:

(1)参数化的变量取值是否正确

(2)正则表达式提取的值是否正确

(3)JMeter属性

(4)调试时服务器返回些什么内容

3. FTP 请求

(1)FTP(文件传输协议)用于Internet上文件的双向传输。作为一个应用程序不同的操作系统系统也有不同的实现,为了保证可以跨平台,FTP程序都要遵循相同的协议,FTP有上传和下载两种功能。

(2)JMeter提供对FTP上传和下载的测试支持。FTP请求和FTP请求默认值设置基本一样,只是多了用户名和密码。

(3)实例演示:

 

 

 

4. Java 请求

4.1 自带的两个Java请求类

JMeter的Java取样器上自带两个Java请求类:JavaTest, SleepTest。

通常这两个类对我们测试没有实际作用,但可以模仿它们来扩展Java请求元件,用来做接口测试。

4.2 实例:模仿JavaTest, SleepTest,扩展Java请求元件

分析:

(1)JavaTest类继承了AbstractJavaSamplerClient类,那么我们编写的类也要继承该类。此时,需要实现类里的runTest方法,在这个方法中,可以放入我们需要测试的接口。

(2)只有继承AbstractJavaSamplerClient类,在Java Sampler请求中才可以看到我们模仿的Java请求。

(3)执行过程中,可以将部分工作提取出来,放在setupTest,tearDownTest方法中。需要参数化的,可以暴露出参数表供用户进行参数化,这部分内容放在getDefaultParameters方法中。

示例工程:

(1)编写代码:

package com.seling.test;

public interface BeanUtil {
    public String getUserName();
    public String getAddress();
    public int mul(int i);
}
package com.seling.test;

public class BeanShellEg implements BeanUtil{
    private String userName;
    private String address;

    public BeanShellEg(String name){
        this.userName = name;
    }
    public BeanShellEg(String name, String address){
        this.userName = name;
        this.address = address;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public int mul(int i) {
        return i*i;
    }
}
package com.seling.test;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;

import java.io.Serializable;

public class BeanUtilTest extends AbstractJavaSamplerClient implements Serializable {


    private static final long serialVersionUID = 5002930172848461734L;
    private static final Log log = LogFactory.getLog(BeanUtilTest.class);
    private BeanUtil bu;

    //Java Sampler界面中展示用来指导用户输入变量
    public Arguments getDefaultParameters(){
        Arguments args = new Arguments();
        args.addArgument("i", "i.value");
        return args;
    }

    //执行runTest方法之前会调用此方法
    public void setupTest(JavaSamplerContext context){
        bu = new BeanShellEg("Lili", "Germany");
    }

    //此方法中调用需要测试的接口
    //@param context JavaSampler 上下文
    //@return SamplerResult 返回对象用来记录取样器结果
    @Override
    public SampleResult runTest(JavaSamplerContext context) {
        //获取用户输入的变量值
        int i = Integer.valueOf(context.getParameter("i"));

        //实例化SamplerResult, 用来记录运行结果
        SampleResult sr = new SampleResult();

        //定义事务的开始
        sr.sampleStart();
        int mul = bu.mul(i);
        //设置事务结束
        sr.sampleEnd();
        //设置事务成功
        sr.setSuccessful(true);
        //设置Java Sampler标题
        sr.setSampleLabel("mul");
        //设置响应成功
        sr.setResponseCodeOK();
        //设置响应内容
        sr.setResponseData("mul result: " + String.valueOf(mul));

        return sr;
    }

    //执行runTest方法后会调用此方法
    public void tearDownTest(JavaSamplerContext context){
    }

}

(2)打包我们编写的BeanUtilTest类。

打包好BeanUtilTest后,放到%JMETER_HOME%\lib\ext目录下。如果程序依赖于另一个BeanShell.jar包,所以BeanShell.jar包需要放入%JMETER_HOME%\lib目录。

注意:

这两个目录不同。BeanUtilTest.jar是JMeter启动时会加载到Java Sampler元件中的,属于扩展包,比如放在%JMETER_HOME%\lib\ext目录下而BeanShell.jar是被依赖的包,放在%JMETER_HOME%\lib目录下(也可以在测试计划中加入)。

(3)重启JMeter, 此时在Java请求元件页面的类名称下拉表中,就能看到我们扩展的BeanUtilTest类。

(4)调试脚本,增加断言元件等等

遇到的问题:

在实际操作时,在IDEA中编写了上述三个类,然后打包成jar包。这三个类没有main方法,貌似是因为这个原因,导致打包过程出了问题,虽然可以打包成一个jar包,也放到了%JMETER_HOME%\lib\ext目录下了,但是此时想要启动JMeter,报错,启动失败。当在项目的out目录下删除了这个jar包后,JMeter才能启动成功。

具体原因还未知,可能是我对过程中某个内容的理解还不到位,进而导致错误,后续会再排查,然后重新操作一遍。到时更新。

5. JDBC 请求

当需要对数据库进行测试,比如想测试一个SQL性能如何,测试一个存储过程性能如何。JMeter提供了程序,帮我们建立了连接池,连接池的配置由我们自行配置,然后又提供程序来执行我们的SQL语句,提供参数化的功能。

局限:一个JDBC request只能执行一条语句。

5.1 JDBC 连接池设置

补充知识点:

(1)数据库事务的ACID和隔离级别

1)ACID

A原子性:atomicity,事务是数据库的逻辑公祖哦单位,对于其数据修改,要么全部执行,要么全部不执行。

C一致性:consistency,事务在完成时,必须是所有的数据都保持一致状态。在相关数据库中,所有规则都必须应用于事务的修改,以保持所有数据的完整性。

I隔离性:isolation,一个事务的执行不能被其他事务所影响。

D持久性:duration,一个事物一旦提交,事务的操作边永久性的保存在数据库中。即使此时再执行回滚操作也不能撤销所做的更改。

2)锁机制,用来隔离事务。

3)隔离级别

TRANSACTION_NONE:不支持事务,=0

TRANSACTION_READ_UNCOMMITTED:允许脏读,不可重复读和幻读,=1

TRANSACTION_READ_COMMITED:禁止脏读,但允许不可重复读和幻读,=2

TRANSACTION_REPEATABLE_READ:禁止脏读和不可重复读,允许幻读,=4

TRANSACTION_SERIALIZABLE:禁止脏读,不可重复读和幻读,=8

default:JMeter加上去的,其实是TRACNSACTION_READ_COMMITED。

4)脏读,不可重复读,幻读

脏读:一个事务读取了另一个事务未提交的数据

不可重复读:一个事务再次读取之前的数据时,这个数据已经被另外一个事务修改

幻读:一个事务重新执行一个查询,返回的记录包含了其他事务提交的新纪录

(2)JDBC连接字符是固定的,不同的数据,这个链接字符有差别,常见的连接字符如下:

1)MySQL

Driver="com.mysql.jdbc.Driver";

URL="jdbc:mysql://localhost:{端口}/{数据库名}";

2)Oracle

Driver="oracle.jdbc.driver.OracleDriver";

URL="jdbc:oracle:thin:@localhost:{端口}:{SID}";

3)Microsoft SQL Server

Driver="com.microsoft.sqlserver.jdbc.SQLServerDriver";

URL="jdbc:microsofr:sqlserver://localhost::{端口}: DatabaseName={数据库名}";

4)Sysbase

Driver="com.sybase.jdbc.SybDriver";

URL="jdbc:Sysbase://localhost:{端口}/{数据库名}";

5)PostgreSQL

Driver="org.postgresql.Driver";

URL="jdbc:postgresql://localhost/db_name";

6)DB2

Driver="com.ibm.db2.jdbc.app.DB2.Driver";//装有DB2客户端

Driver="com.ibm.db2.jdbc.net.DB2.Driver"; //未装DB2客户端

URL="jdbc:db2://localhost:{端口}/{数据库名}";

7)JDBC-ODBC

Driver="sun.jdbc.odbc.JdbcOdbcDriver";

URL="jdbc:odbc:{数据源名}";

注意:需要把用到的驱动包放到%JMETER_HOME%\lib目录下。比如用MySQL的话,需要把MySQL JDBC驱动包 mysql-connector-java-5.0.7-bin.jar放到目录%JMETER_HOME%\lib下。

 

附:C3p0连接池配置官网地址如下,用于C3p0连接池的配置调优。

c3p0-v0.9.5.5 - JDBC3 Connection and Statement Pooling - Documentation (mchange.com)

 

5.2 添加 JDBC Request

 

(1)Query Type说明:

Select Statement:在需要执行查询语句的时候用到

Update Statement:执行更新操作的时候用到,包括插入和修改

Callable Statement:读音JDBC规范中的CallableStatement对象,为所有的DBMS提供了一种以标准形式调用存储过程的方法。即可以调用存储过程,可以入参,有占位符。

Prepared Select Statement:预编译查询语句。在Oracle中为了减少护具库在SQL上的硬编译资源消耗,提倡大家用绑定变量,这样相同的SQL只会被编译一次。

Perpared Update Statement:这个只是把上面的Select换成update,意义一样。

Commit:当前连接状态中的内容提交

Rollback:当前连接状态中的内容回滚

AutoCommite(false) :指明不需要自动提交

(2)JDBC Request的实例演示

(稍后补)

6. JUnit Request

经常用JUnit来完成单元测试。

JMeter提供了对JUit程序的支持。重点在JUnit4。

6.1 JUnit 简介

JUnit是一个单元测试框架。多数Java集成开发环境都已经集成了JUnit作为单元测试工具。

JUnit能够测试程序,可以利用它作为性能测试脚本进行性能测试。

常见注解:

@Before

@After

@BeforeClass

@AfterClass

@Test(timeout=xxx)

@Test(expected=Exception.class)

@Ignore

示例:略

注意:在使用Junit时,需要加上hamcrest-core-XX.jar包。建议组合:hamc-core-1.3.jar和junit-4.11.jar

6.2 JUnit 参数

测试是可能会需要用多组参数来测试程序是否正确,这就需要JUnit能够支持参数化功能。

示例稍后补。

说明:

(1)在JUnit测试类中定义了一个静态的方法initData(),来组装参数值,返回Collection对象。

(2)定义了两个成员变量name和address,然后用构造方法来对这两个成员变量赋值。

(3)在执行时即可正常读取到参数。

使用到的注解:

(1)@RunWith:指定用RunWith运行器,JUnit有多个运行期,RunWith支持读取参数,表名此测试类哟读取参数。

(2)@Parameters:定义此方法进行参数组装,注意此方法是Static的,并且返回的是集合,可以用来循环遍历。而且这个集合至少要是一个二维数组。如果只需要一个参数,则不给数组的第二个维度赋值即可。

6.3 JMeter JUnit Request

 开始JMeter JUnit Request的开发:

(1)编写JUnit程序,将其打包成jar包,放到%JMETER_HOME%\lib\junit目录下。

(2)启动JMeter,添加JUnit Request, 选择Search for JUnit4 annotations

(3)运行,观察结果(察看结果树,控制台)

(具体演示,稍后补)

7. SOAP/XML-RPC Request

7.1 WebServices目前主流的实现方式有三种

(1)REST

(2)SOAP

(3)XML-RPC

7.2 SOAP/XML-RPC Request

猜你喜欢

转载自blog.csdn.net/sulia1234567890/article/details/121859229