BeanShell 是一门完全兼容 Java 语法的脚本语言,在 JMeter 中可用来编写自定义脚本,具备极高的灵活性。例如,以下代码能够生成一个随机数,并将其存储到 JMeter 变量中:
import java.util.Random;
Random rand = new Random();
int num = rand.nextInt(100);
vars.put("randomNumber", String.valueOf(num));
在 JMeter 中,BeanShell 几乎无处不在:采样器(BeanShell Sampler)、前置处理器(BeanShell PreProcessor)、后置处理器(BeanShell PostProcessor)、断言(BeanShell Assertion)、定时器(BeanShell Timer)、监听器(BeanShell Listener)——这些组件都能嵌入一段 BeanShell 脚本。借助它,可以轻松拓展 JMeter 的能力,例如:
- 在测试计划中嵌入复杂的逻辑控制;
- 动态生成 HTTP 请求参数;
- 在测试过程中灵活处理响应数据;
- 自定义结果分析逻辑。
BeanShell 的常用内置对象
log
用于记录日志。JMeter 底层采用 log4j,日志会输出到 bin/jmeter.log 文件。常用的两个 API 是 log.info() 和 log.error(),分别用于记录普通信息和错误信息。
vars
操作 JMeter 变量的入口。JMeter 变量可在 HTTP 请求等地方直接引用。需要注意:JMeter 变量在线程启动时拷贝到当前线程,类似于线程局部变量——也就是说,一个线程修改变量的值,不会影响其他线程。
获取变量:
vars.get("name")
设置变量(如果变量不存在则自动创建):
vars.put("key", "value")
props
用于操作 JMeter 的配置文件 jmeter.properties。
获取配置项的值:
props.get("key")
设置配置项的值:
props.put("key", value)
data
当前请求的响应数据,类型为 byte[](字节数组)。可以通过 String str = new String(data, "utf-8") 将其转为字符串并打印出来。
示例
下面几个例子展示了 BeanShell 的常见用法,涵盖变量计算、参数构造、请求执行等场景。
计算两个变量的和
int num1 = Integer.parseInt(vars.get("num1"));
int num2 = Integer.parseInt(vars.get("num2"));
int sum = num1 + num2;
vars.put("sum", String.valueOf(sum));
构造 HTTP 请求参数
String param1 = URLEncoder.encode(vars.get("param1"), "UTF-8");
String param2 = URLEncoder.encode(vars.get("param2"), "UTF-8");
String params = "param1=" + param1 + "¶m2=" + param2;
vars.put("params", params);
获取 HTTP 响应头中的某个值
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
String url = vars.get("url");
DefaultHttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(url);
HttpResponse response = client.execute(request);
Header header = response.getFirstHeader("Content-Type");
String contentType = header.getValue();
vars.put("contentType", contentType);
执行 HTTP 请求并解析响应数据
import org.apache.commons.io.IOUtils;
import java.net.URL;
import java.nio.charset.StandardCharsets;
String url = vars.get("url");
String response = IOUtils.toString(new URL(url), StandardCharsets.UTF_8);
// 解析响应的逻辑写在这里
vars.put("response", response);
发送电子邮件
import javax.mail.*;
import javax.mail.internet.*;
import java.util.Properties;
String host = vars.get("host");
String port = vars.get("port");
String username = vars.get("username");
String password = vars.get("password");
String from = vars.get("from");
String to = vars.get("to");
String subject = vars.get("subject");
String body = vars.get("body");
Properties props = new Properties();
props.put("mail.smtp.host", host);
props.put("mail.smtp.port", port);
props.put("mail.smtp.auth", "true");
Session session = Session.getInstance(props, new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
message.setSubject(subject);
message.setText(body);
Transport.send(message);
BeanShell 的优点
- 扩展性:BeanShell 脚本能够轻松扩展 JMeter 的功能,满足更高级的性能测试需求。
- 灵活性:可与 JMeter 中的其他组件无缝集成,适用各种复杂的测试场景。
- 易用性:采用 Java 语法编写,对于 Java 开发者来说几乎零学习成本。
- 可读性:脚本结构清晰,便于调试和后续维护修改。
BeanShell 的缺点
- 性能:BeanShell 脚本的执行效率不如原生 Java 代码,可能对测试结果产生一定影响。
- 学习成本:对非 Java 开发者而言,需要额外花费时间掌握 Java 语法和脚本逻辑。
- 维护成本:随着测试用例复杂度的提升,脚本的维护和更新需要持续投入精力。
总结
JMeter BeanShell 的使用确实需要一定的编程基础,但它能显著提升 JMeter 的灵活性和可扩展性。如果您的测试场景超出了常规组件的支持范围,BeanShell 是一个值得掌握的利器,能够帮助您更高效地完成性能测试任务。
