# jmeter基础测试

# jmeter元件执行顺序

1、配置元件

2、前置处理器

3、定时器

4、sampler

5、后置处理器(关联,正式表达式提取器)

6、断言

7、监听器

Jmeter语言版本中英文切换

1、控制台修改

menu -> options -> choose language

2、配置文件修改

bin目录 -> jmeter.properties

默认 #language=en
改为 language=zh_CN 

# jmeter环境变量配置

注:在安装Jmeter之前,请先检查下电脑有没有装JDK:开始->运行->然后输入cmd->进入命令行界面,输入java -version , 出现以下信息就是此电脑已安装了JDK

如果没有,需要安装JDK,官网上下载即可

Java环境配置

变量名:JAVA_HOME
变量值:C:\Program Files\Java\jdk1.8.0_51 (即jdk安装的位置)
变量名:Path  (这个变量名已在系统变量中存在,现只需在这个值的前面添加以下变量值就可以了)
变量值:%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin
变量名:CLASSPATH
变量值:.;%JAVA_HOME%lib;%JAVA_HOME%lib\tools.jar(记住前面的.)
1
2
3
4
5
6

jmeter环境配置

新建:JMETER_HOME=D:\apache-jmetes\apache-jmeter-4.0(jmeter安装位置)
CLASSPATH=%JMETER_HOME%\lib\ext\ApacheJMeter_core.jar;%JMETER_HOME%\lib\jorphan.jar;  
PATH=%JMETER_HOME%\bin
1
2
3

最后在cmd输入jmeter 直接打开 如图

jmeter响应数据中中文乱码问题

Jmeter安装目录/bin/jmeter.properties中sampleresult.default.encoding默认为ISO-8859-1,将参数修改为

sampleresult.default.encoding=utf-8 即可

同时注意将注释符号#去掉,否则不会生效

# 参数化构造技巧

# 如何构建唯一ID?

使用多个函数组合:{group}+{thread number}+{迭代计数}

group:由于JMeter支持多个Group,所以要考虑多个Group的情况,于是我们把线程组编号也纳入组合中

thread number:线程Number,组中的线程Number是唯一 的,group+thread number能够保证线程号唯一

迭代计数:每个线程都有一个迭代计数量,记录脚本运行了多少次

{group}+{thread number}+{迭代计数} 就可以保证生成一个唯一号,如果觉得不够长可以加上time({time}+{group}+{thread number}+{迭代计数} )

${__BeanShell(((ctx.getThread().getThreadName().toString()).split(" ")[1]).split("-")[0],group)}-》线程组的Id放在group中

其他的thread number,time,迭代计数器通过函数助手获取,如:

合在一起:${__time(hhmmss,)}${group}${__threadNum}${__counter(,)}名称中直接用了BeanShell函数,在此可以触发截取group。

# 构造未来时间和过去时间

函数助手里面的time函数是当前时间,就不适用了,使用BeanShell函数,代码如下:

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

try{
	//获取当期那日期
	Date date = new Date();  
	SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
	String nowDate = sf.format(date);   
	
	Calendar cal = Calendar.getInstance();  
	cal.setTime(sf.parse(nowDate));  
	//当前时间往后面+3天
	cal.add(Calendar.DAY_OF_YEAR, +3);  
	String chanceDate = sf.format(cal.getTime());   
	cal.add(Calendar.DAY_OF_YEAR, +7);
	String planFinishDate = sf.format(cal.getTime());
	vars.put("orderDate",chanceDate);
	vars.put("delivery",planFinishDate);
	}
	catch (Exception e)
	{
	String orderDateate="";
	String planFinishDate="";
	vars.put("orderDate",orderDateate);
	vars.put("delivery",planFinishDate);
		}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# 关联

关联是一种动态行为,用以后续的请求(比如HTTP请求)从之前的请求(比如JDBC Request)的的查看结果器—>响应数据(服务器返回的数据)中直接使用指定的数据。

如:HTTP请求—>HTTP请求。某个用户(调用登陆接口)登录成功后服务器会返回一个登录凭证比如防止csrf攻击而生成的account_token,之后的操作比如修改密码接口、发布信息等都需要带上此凭证。我们怎么获取登录凭证并传递给后续的HTTP接口请求呢,可用的方法就是关联。

登录后获得的account_token

使用正则表达式提取器,提取account_token

使用debug sampler获取关联参数

在接下来的接口信息头管理器中关联此参数

后面的接口请求成功

# 集合点

模拟并发,使虚拟用户在需要压力的地方等一等

添加synchronizing timer

设置筹齐5个点就请求

线程数改成10个

这是全部sampler都会按照集合点要求请求,如果想只是作用于某一个,可以将synchronizing timer放在该sampler下面

# 控制器

1、条件控制器(if)

添加条件判断

2、循环控制器

3、吞吐量控制器

序号 线程数 循环次数 模式 throughput(吞吐量) per user 执行次数
1 2 10 percent 50 Y 10
2 2 10 percent 50 N 10
3 2 10 total 7 Y 14
4 2 10 total 7 N 7
5 2 2 total 7 Y 4
6 2 2 total 7 N 4

如下图:

序号 线程数 循环次数 模式 throughput(吞吐量) per user 执行次数
4 2 10 total 7 N 7

4、for each控制器

# JDBC

数据库驱动类和URL格式:

Datebase Driver class Database URL
MySQL com.mysql.jdbc.Driver jdbc:mysql://host:port/{dbname}
PostgreSQL org.postgresql.Driver jdbc:postgresql:{dbname}
Oracle oracle.jdbc.driver.OracleDriver jdbc:oracle:thin:@//host:port/service OR jdbc:oracle:thin:@(description=(address=(host={mc-name}(protocol=tcp)(port={port-no}))(connect_data=(sid={sid})))

JDBC select

JDBC update:prepared update statement(进行参数化)

JDBC callable(存储过程)

新建存储过程:

# jmeter非GUI操作

jmeter非GUI下命令参数

-h 帮助 -> 打印出有用的信息并退出

-n 非 GUI 模式 -> 在非 GUI 模式下运行 JMeter

-t 测试文件 -> 要运行的 JMeter 测试脚本文件

-J 是设置本地jmeter属性,引用变量参数

-G 是设置server的jmeter属性

-l 日志文件 -> 记录结果的文件

-r 远程执行 -> 在Jmter.properties文件中指定的所有远程服务器

-H 代理主机 -> 设置 JMeter 使用的代理主机

-P 代理端口 -> 设置 JMeter 使用的代理主机的端口号
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

非GUI参数化

场景设计

右键测试计划->添加->Threads(Users)->jp@gc - Stepping Thread Group

First,wait for N seconds - 启动第一个线程之前,需要等待N秒
Then start N threads - 设置最开始时启动N个线程
Next add N1 threads every N2 seconds, using ramp-up N3 seconds - 然后,每隔N2秒,在N3秒内启动N1个线程
Then hold load for N seconds - 单台负载机启动的线程总数达到Max之后,持续运行N秒
Finally,stop N1 threads ervery N2 seconds - 最后,每隔N2秒,停止N1个线程数
1
2
3
4
5