第16节 最好的实践
16.6 用户变量
一些测试计划需要为不同的用户线程使用不同的值。例如,您可能想要测试一个序列,该序列需要为每个用户进行唯一的登录。通过JMeter提供的工程,这很容易实现。
例如:
- 创建一个文本文件,其中包含用户名和密码,以逗号分隔。将其放到与测试计划相同的目录中。
- 向测试计划中添加CSV数据文件配置,将变量命名为USER和PASS
- 在取样器合适的地方,用
U
S
E
R
替
换
登
录
名
,
用
{USER}替换登录名,用
USER替换登录名,用{PASS}替换密码
CSV数据文件将为每个线程读取一个新行。
16.7减少资源请求
关于减少资源使用的一些建议:
- 使用无界面模式:jmeter -n -t test.jmx -l test.jtl
- 使用尽可能少的监听器;如果使用了-l的参数,则可以删除或禁用他们
- 在负载测试时,不要使用“查看结果树”或“用表格查看结果”的监听器,仅在脚本编写阶段使用它们来调试脚本
- 与其使用大量类似的采样器,不如在循环中使用相同的采样器,并使用变量(CSV数据集)来改变样本【Include Controller在这里没有帮助,因为它将文件中的所有测试元素添加到测试计划中】
- 不要使用功能模式
- 使用CSV输出而不是XML
- 只保存你需要的数据
- 尽可能少使用断言
- 使用性能最佳的脚本语言(参见JSR223部分)
如果你的测试需要大量的数据,尤其是需要随机化的数据,请在可以使用CSV数据集读取的文件中创建测试数据。这样可以避免在运行中浪费资源。
16.8 BeanShell server
BeanShell解释器有一个非常有用的特性——它可以充当服务器,可以通过telnet或http访问。
这是不安全的,任何可以连接到该端口的人都可以发出任何BeanShell命令。它们可以不受限制地访问JMeter应用程序和主机。除非端口受到访问保护,否则不要启用服务器,如启动防火墙。
如果您确实希望使用服务器,请在jmeter.properties中定义以下内容:
beanshell.server.port=9000
beanshell.server.file=../extras/startup.bsh
在上面的示例中,服务器将启动,并将监听端口9000和9001。9000端口将用于http访问,9001端口将用于telnet访问。startup.bsh文件将由服务器处理,可用于定义各种函数和设置变量。启动文件定义了设置和打印JMeter和系统属性的方法。这是你在JMeter控制台看到的东西:
Startup script running
Startup script completed
Httpd started on port: 9000
Session started on port: 9001
你可以使用示例脚本(extras / remote.bsh)来测试服务器【看看它是如何工作的】,在JMeter bin目录中启动它时(如果从其他地方运行,则根据需要调整路径),输出应该如下所示:
$ java -jar ../lib/bshclient.jar localhost 9000 ../extras/remote.bsh
Connecting to BSH server on localhost:9000
Reading responses from server …
BeanShell 2.0b5 - by Pat Niemeyer (pat@pat.net)
bsh % remote.bsh starting
user.home = C:\Documents and Settings\User
user.dir = D:\eclipseworkspaces\main\JMeter_trunk\bin
Setting property 'EXAMPLE' to '0'.
Setting property 'EXAMPLE' to '1'.
Setting property 'EXAMPLE' to '2'.
Setting property 'EXAMPLE' to '3'.
Setting property 'EXAMPLE' to '4'.
Setting property 'EXAMPLE' to '5'.
Setting property 'EXAMPLE' to '6'.
Setting property 'EXAMPLE' to '7'.
Setting property 'EXAMPLE' to '8'.
Setting property 'EXAMPLE' to '9'.
EXAMPLE = 9
remote.bsh ended
bsh % … disconnected from server.
作为一个实例示例,假设你在非GUI模式下,运行了长时间的JMeter测试,并且希望在测试期间的不同时间段更改吞吐量。测试计划包括一个常量吞吐量计时器,他是根据属性定义的,例如:${__P(throughput)},可以使用以下BeanShell命令来更改测试:
printprop("throughput");
curr = Integer.decode(args[0]); // Start value
inc = Integer.decode(args[1]); // Increment
end = Integer.decode(args[2]); // Final value
secs = Integer.decode(args[3]); // Wait between changes
while(curr <= end) {
setprop("throughput",curr.toString()); // Needs to be a string here
Thread.sleep(secs*1000);
curr += inc;
}
printprop("throughput");
该脚本可以存储在一个文件中(例如,throughput.bsh),并使用bshclient.jar发送到服务器,例如:
java -jar ../lib/bshclient.jar localhost 9000 throughput.bsh 70 5 100 60
16.9 BeanShell 脚本
从JMeter 3.1开始,我们建议从BeanShell切换到JSR223测试元素(参见下面的JSR223小节了解更多细节),并从BeanShell函数切换到groovy函数。
16.9.1 概述
每个BeanShell测试元素都有自己的解释器副本(对于每个线程)。如果重复调用测试元素,例如在循环内,除非选择“在每次调用之前重置bsh.Interpreter”选项,否则解释器将保留在调用之间。
一些长期运行的测试可能会导致解释器使用大量内存;如果是这种情况,请尝试使用reset选项。
您可以使用命令行解释器在JMeter之外测试BeanShell脚本:
$ java -cp bsh-xxx.jar[;other jars as needed] bsh.Interpreter file.bsh [parameters]
或
$ java -cp bsh-xxx.jar bsh.Interpreter
bsh% source("file.bsh");
bsh% exit(); // or use EOF key (e.g. ^Z or ^D)
16.9.2 共享变量
变量可以在启动(初始化)脚本中定义。除非使用reset选项,否则这些值将在测试元素的调用期间保留。
脚本还可以使用vars变量的get()和put()方法访问JMeter变量,例如:
vars.get("HOST");
vars.put("MSG","Successful");
get()和put()方法只支持具有String的变量,但是也有getObject()和putObject()方法可以用于任意对象,JMeter变量是线程的本地变量,但是可以被所有测试元素(不仅仅是Beanshell)使用。如果需要在线程之间共享变量,那么可以使用JMeter属性:
import org.apache.jmeter.util.JMeterUtils;
String value = JMeterUtils.getPropDefault("name","");
JMeterUtils.setProperty("name", "value");
示例.bshrc文件包含getprop()和setprop()方法的示例定义。共享变量的另一种可能方法是使用“bsh.shared”共享命名空间。
例如:
if (bsh.shared.myObj == void){
// not yet defined, so create it:
myObj = new AnyObject();
}
bsh.shared.myObj.process();
与其在测试元素中创建对象,不如在JMeter属性bean .init.file定义的启动文件中创建对象。这只处理一次。