beanshell取样器作用,beanshell取样器参数
Jmeter和Postman做接口测试的区别
不同的目录结构与组织方式代表不同工具的测试思想,学习一个测试工具应该首先了解其组织方式。
Jmeter的组织方式相对比较扁平,它首先没有WorkSpace(工作空间)的概念,直接是TestPlan(测试计划),TestPlan(测试计划)下创建的Threads Group(线程组)就相当于TestCase(测试用例),并没有TestSuite(测试模块)的层级。TheadsGroup(线程组)中的Sampler(取样器)、管理器代表一个Step(测试步骤)
Postman功能上更简单,组织方式也更轻量级,它主要针对的就是单个的HTTP请求。Collection就相当于是Project(项目),而Collection中可以创建不定层级的Folders(文件夹),可以自己组织TestSuite(测试模块)。每个Request(请求)可以当做是一个TestCase(测试用例)或者Step(测试步骤)
Jmeter的功能更强大,可以测试各种类型的接口,不支持的也可以通过网上或自己编写的插件进行扩展
Postman更轻量级,定位也不同,可用来测试Rest接口
Jmeter可以在线程组里添加HTTP、TCP或WebSocket的Sampler
Postman仅支持Rest接口
除以下表格中所列的变量之外,两个工具也都有系统变量,没有列出。
Jmeter:由Switch控制器、If控制器、随机控制器等一系列控制器实现流程控制,以及Beanshell脚本
Postman:通过JavaScript脚本控制
Jmeter:TestPlan、Threads Group、Sampler均可添加断言
Postman:请求的Tests中可添加断言
Jmeter:Bean shell(Java)
Postman:JavaScript
Jmeter:一个TestPlan也是一个jmx(xml)文件,无法分割,但Jmeter有一个合并的功能,允许将多个文件合并在一起。只能每个团队成员自己建立一个TestPlan,分功能块进行测试。最后整理合并。
Postman:有团队协作的功能,需要付费。
jmeter实现登录并设置token为全局变量
1.在测试计划下面添加http请求默认值,我们可以把域名添加好,每个请求只输入URL即可
2.登录请求:在消息体数据中输入json数据格式的参数
3.添加正则表达式提取器获取token
(1)引用名称?token
(2)正则表达式??"token":"(.+?)"
(3)模板?用$$引用起来,如果在正则表达式中有多个正则表达式,则可以是$2$$3$等等,表示解析到的第几个值给title。如:$1$表示解析到的第1个值
(4)匹配数字?0代表随机取值,1代表全部取值,通常情况下填0
(5)缺省值?如果参数没有取得到值,那默认给一个值让它取
4.添加BeanShell 取样器将token值设为全局变量,${__setProperty(newtoken,${token},)}
?5.添加请求头部管理器作为全局使用,将变量token使用如下。${__property(newtoken)}? ??
如果没有Content-Type? 则手动增加:application/json;charset=UTF-8
这是为了自己方便记录与查看,所以记录在上,原文地址:
beanshell和shell的区别
BeanShell是一种完全符合Java语法规范的脚本语言,并且又拥有自己的一些语法和方法;
BeanShell是一种松散类型的脚本语言(这点和JS类似)
BeanShell是用Java写成的,一个小型的、免费的、可以下载的、嵌入式的Java源代码解释器,
具有对象脚本语言特性,非常精简的解释器jar文件大小为175k。
BeanShell执行标准Java语句和表达式,另外包括一些脚本命令和语法。
官网:
BeanShell 将成为Java平台上的第三种编程语言,前两种分别为java和Groovy(也是一种脚本语言)
下载与安装:
jar:
src:
或使用SVN:
svn co
doc:
设置环境:
(1) 把bsh-xx.jar放到$JAVA_HOME/jre/lib/ext文件夹下(不推荐);
(2) UNIX: export CLASSPATH=$CLASSPATH:bsh-xx.jar(推荐)
(3) WINDOWS: set classpath %classpath%;bsh-xx.jar(推荐)
运行方式:
(1) 界面UI方式 : java bsh.Console
(2) 命令行方式 : java bsh.Interpreter
(3) 运行脚本文件: java bsh.Interpreter filename [args]
简单举例(windows):
设置好环境变量classpath, 打开dos或CMD窗口, 键入命令:
java bsh.Console
出现BeanShell的"Bsh Workspace"界面,表示设置成功,BeanShell开始运行;
在使用上面命令出现的控制台界面中进行下面的测试:
bsh % foo="Foo"; //定义变量foo
bsh % four=(2+2)*2/2; //定义变量four并初始化为(2+2)*2/2
bsh % print(foo+"="+four); //输出 Foo=4
Foo=4 //输出结果
bsh % for(i=0;i5;i++)print(i); //循环打印0~4
1
2
3
4
bsh % button = new JButton("MyButton"); //实例化一个Button对象
bsh % frame = new JFrame("MyFrame"); //实例化一个Frame对象
bsh % frame.getContentPane().add(button,"Center"); //将Button对象加入Frame对象的面板中;
bsh % frame.pack(); //打包
bsh % frame.setVisible(true); //设置Frame对象的可见性;回车后会弹出一个GUI界面;
bsh %
完整代码:
foo = "Foo";
four = (2 + 2)*2/2;
print( foo + " = " + four );
for (i=0; i5; i++)
print(i);
button = new JButton( "My Button" );
frame = new JFrame( "My Frame" );
frame.getContentPane().add( button, "Center" );
frame.pack();
frame.setVisible(true);
在窗口中输入上面的代码, 敲回车执行,弹出一个有Button的GUI界面.
说明:
因为BeanShell是松散类型的脚本语言因此可以直接写:
foo = "Foo";
four = (2 + 2)*2/2;
也就是foo与four均不需要变量类型的声明,给赋什么类型的值,就是什么类型的变量;
print()是BeanShell提供一种简单的打印命令,相当于java中的System.out.println();
脚本中所写的方法范例:
int addTwoNumbers( int a, int b ) {
return a + b;
}
sum = addTwoNumbers( 5, 7 ); // 12
也可以使用动态的变量类型(无状态)方法
add(a, b){
return a + b;
}
foo = add(1, 2); // 3
foo = add(1, "2"); //"12"
特别注意:
只要有一个为字符串全部按照字符串处理,
系统不会根据1是数字在前把"2"转换成数字处理;
foo = add("Oh", " baby"); // "Oh baby"
脚本中实现接口:
实现任何接口需要JDK1.3或者更高,可以使用缺省的java匿名类的语法实现一个接口类,例如:
ActionListener scriptedListener = new ActionListener() {
actionPerformed( event ) { ... }
}
不需要实现接口的所有的方法,只需要实现你使用的方法即可, 如果使用你没有实现的方法,
BeanShell将抛出一个错误,如:
ml = new MouseListener() {
mousePressed( event ) { print("test"); }
// handle the rest
invoke( name, args ) {
print("Method: "+name+" invoked!");
}
}
脚本中定义对象:
例一:
使用特殊的关键字this可以创建一个对象(根JS类似)
foo() {
print("foo");
x=5;
bar() {
print("bar");
}
return this;
}
myfoo = foo(); // prints "foo"
print( myfoo.x ); // prints "5"
myfoo.bar(); // prints "bar"
例二:
在java标准语言中可以使用this返回一个类的一个实例
// MyClass.java
MyClass {
Object getObject() {
return this; // return a reference to our object
}
}
在这个例子中getObject() 方法是返回MyClass类的一个实例
在BeanShell中对象中的变量只是局部的变量在对象内可以使用,
在对象外是不可以使用的(不同于前面for-loop,if-else中的使用);
// Define the foo() method:
foo() {
bar = 42;
print( bar );
}
// Invoke the foo() method:
foo(); // prints 42
print(bar); // Error, bar is undefined here
这里的print(bar);会抛出异常:
// Error: EvalError: Undefined argument: bar : at Line: 1 : in file: unknown file : ( bar )
但可以使用this返回对象,使用对象加上"."运算符引用属性(类似JS)
foo() {
bar = 42;
return this;
}
fooObj = foo();
print( fooObj.bar ); // prints 42
同样对象中也可以定义一些方法,例如:
foo() {
int a = 42;
bar() {
print("The bar is open!");
}
//bar();
return this;
}
// Construct the foo object
fooObj = foo(); // prints "the bar is open!"
// Print a variable of the foo object
print ( fooObj.a ) // 42
// Invoke a method on the foo object
fooObj.bar(); // prints "the bar is open!"
也可以定义bar()和foo()也带参数:
foo() {
bar(int a) {
print("The bar is open!" + a);
}
return this;
}
foo().bar(1);
也可以把bar()方法定义到对象外面
foo() {
return this;
}
bar(int a) {
print("The bar is open!" + a);
}
foo().bar(1); //其实就是bar(1);
BeanShell一种松散的脚本语言, 有很多中声明的方法可以使用:
This super global
This 是引用当前对象
Super 是引用父亲对象
Global 是引用最上层对象
super.super.super...foo = 42; // Chain super. to reach the top
global.foo = 42;
BeanShell(Bsh)调用外部Java类的两种方式:
(1) 方法一(直接调用.java源文件)
sourceRelative("xxx.java");
利用sourceRelative()方法把java的源代码引入bsh环境中,然后进行调用。
这种方法不需要编译引用的java源文件,缺点也很明显"无法利用javac来检查java代码"。
(2) 方法二(通过引用.class二进制文件)
import xxx;
利用传统的java import机制来获取java类,然后在bsh环境中进行调用。
需要编译.java文件;
方便调用第三方的Java API(因为通常情况下无法得到API的源码,即使得到了文件会远大于jar包的大小)。
BeanShell介绍:
我们知道,现在有很多脚本语言,大家平时使用的比较多的包括Perl,Python,Ruby,JavaScript,Groovy,
在这里我要介绍的是另外一个对象脚本语言BeanShell()。
BeanShell的解释器是用Java写的,开源并且免费的,
引用open-open上面的话来说明它的运作方式:
它将脚本化对象看作简单闭包方法(simple method closure)来支持,
就如同在Perl和JavaScript中的一样。它具有以下的一些特点:
* 使用Java反射API以提供Java语句和表达式的实时解释执行;
* 可以透明地访问任何Java对象和API;
* 可以在命令行模式、控制台模式、小程序模式和远程线程服务器模式等四种模式下面运行;
* 与在应用程序中一样,可以在小程序中(Applet)正常运行(无需编译器或者类装载器);
* 非常精简的解释器, jar文件中的Intepreter.class大小为150+k"。
每一种脚本语言都有它的使用场景,而正是因为其在某些场景的使用而使语言本身得到了发扬光大,
比如Ruby正是因为Ruby On Rails这个Web框架的流行而得到开发者的关注,Groovy也一样;
BeanShell可不能再有Web框架,Java世界的Web框架已经太多了,够让人头痛的了;
BeanShell是Java语法,所以对Java开发者来说,很快就可以上手,
BeanShell不能像Ruby,Perl,Ruby一样可以占据一个系统的主体,
而只能在一些小的地方发挥"螺丝钉"的作用。
笔者与BeanShell结缘是通过一个开源工作流引擎-OBE(这个鸟东西现在好像没什么声音了),
BeanShell被用作流程跳转的Parser,举个例子,比如一个流程A节点的下一个节点是B或者C,
如何决定A-B还是A-C呢,我们可以写一段Java脚本放在流程定义里面,
一旦A运行完毕,流程会使用BeanShell来Parse这段Java脚本,
根据脚本的返回值决定流程下一步的运行方向,
脚本在这里虽然用得不多,但是却是非常的重要,
我们知道,简单的表达式是远远满足不了流程跳转的判断的,
有了脚本就可以满足任何不规则的业务逻辑。
继以上说到的,使用BeanShell可以处理现实中不规则的业务,举个很典型的例子,
我们知道,一个保险公司有很多险种,每个险种的投入和收益的算法是很复杂的,
无法用规则的关系数据库模型来描述,所以很多保险系统在处理险种的算法都是硬编码,
如果要在系统中新加一个险种,是非常麻烦的,重新修改代码,重新发布,
这对开发\维护人员和客户都是很痛苦的,有了BeanShell,我们可以从这种痛苦中解脱出来,
对每个险种使用不同的脚本,新加的险种我们新配一个脚本,这样既可以满足业务多变的要求,
又可以减少工作量,节约成本。
BeanShell的一个特点是动态执行Java代码,脚本文件改变不会影响当前脚本的调用,
新脚本将在脚本的下一次调用生效,这不同于配置文件,配置文件改变一般都需要应用重启。
下面举个例子来说明BeanShell的使用(JDK1.5,BeanShell2.04),
主类:
package com.test.BeanShell;
import bsh.Interpreter;
public class TestShell {
public static void main(String[] args) throws Exception {
Interpreter interpreter = new Interpreter();
interpreter.set("inValue", new Integer(1));
interpreter.source("/D://BeanShell_test/test.bsh");
System.out.println(((Integer) interpreter.get("outValue")).intValue());
}
}
脚本文件(D:/BeanShell_test/test.bsh)中的内容为::
System.out.println("hello,in value is "+inValue);
outValue = inValue+1;
结果:
hello,in value is 1
2
再来一个简单例子:
(1) 下载BeanShell的jar,加到 classpath 里
(2) 写一个脚本文件 myscript.txt ,内容如下:
a = 2;
b = 3;
c = a + b;
print(c);
(3) 运行该脚本
d:\BeanShelljava bsh.Interpreter myscript.txt
如果没有将BeanShell的JAR加到classpath路径里,运行下面的命令:
java -classpath %CLASSPATH%;bsh-2.0b4.jar bsh.Interpreter myscript.txt
OK,输出结果5
写一个bat文件 bsh.bat放到系统目录下,如:winnt 文件内容如下:
java bsh.Interpreter %1
就可以使用如下方法运行脚本文件了
c:\BeanShellbsh myscript.txt
osworkflow用的就是他了
和Eclipse的集成:
eclipse update url:
有用的BeanShell命令:
在刚才那个例子中我们用了一个内建在BeanShell中的一个方便的命令print(),来显示变量的值。
print()跟Java的System.out.println()非常的相像,除非它能保证输出总是命令行。
print()也可以显示一些对象的类型(如数组),但比Java的更详细。
另一个相关的命令是show(),用来开启与关闭显示你输入的每一行的结果。
Jmeter之BeanShell的使用
背景:在一次接口压测过程中,接口的参数值是通过java类中的方法获取的,此方法没有封装成接口,又因参数值存在有效期(15min),所以导致在执行压测的过程中需考虑在执行的时长内参数值是否失效的问题。
在未使用beanshell的时候(当时不知道如何使用,且时间紧,没时间研究),就先在IntelliJ Idea运行Java程序获取参数值,然后将参数值复制出来粘贴到jmeter中,然后再执行脚本进行压测。暂时不影响测试,但是操作起来有点麻烦。
趁着测试工作结束,正好有时间研究下jmeter中beanshell的使用,总结如下:
1、先将java程序打成jar包;
打jar包参考:
2、将1中jar包复制到jmeter安装路径D:\Program Files\apache-jmeter-5.3\lib\ext\下,如果jave程序中有引用到其它jar包(import导入的),也一并复制到该目录下;
3、启动jmeter,在测试计划右侧页面下方,添加2中复制的jar包:
4、然后在测试计划下,创建线程组,添加BeanShell取样器,在取样器右侧页面脚本处,编写java脚本:
注:脚本可接收传参,参数传入方式:${参数名1} ${参数名2} ...,参数之间用空格隔开,在脚本中可使用bsh.args[i]获取参数值,i表示参数在数组中的索引。参数的定义,放在用户定义的变量中,在线程组下添加用户定义的变量:
5、在线程组下添加HTTP请求,在消息体数据中传递请求参数(json):
6、在线程组下添加查看结果数,执行HTTP请求,查看结果树中请求body中的参数(成功获取):
至此,使用BeanShell的方式成功传参,解决了手动获取参数的麻烦。
jmeter(六)-定时器
1,固定定时器
定义:让需要每个线程在请求之前按相同的指定时间停顿
注意:1),固定定时器的响应时间不会记入每个取样器的响应时间
2),固定定时器的响应时间会被记录事务控制器的时间
2,高斯随机定时器
定义:让需要每个线程在请求前按随机时间停顿,上面是随机在100到400秒之间
计算公式:Math.abs((this.random.nextGaussian() * 300) + 100)
3,统一随机定时器
定义:和高斯随机定时器的作用差异不大,区别在于延时时间在指定范围内且每个时间的取值概率相同,每个时间间隔都有相同的概率发生,总的延迟时间就是随机值和偏移值之和
(1)Random Delay Maximum(in milliseconds):随机延迟时间的最大毫秒数
(2)Constant Delay Offset(in milliseconds):暂停的毫秒数减去随机延迟的毫秒数
4,固定吞吐量定时器
定义:JMeter以指定数字的吞吐量(即指定TPS,只是这里要求指定每分钟的执行数,而不是每秒)执行
5,同步定时器
定义:类似loadrunner当中的集合点,作用阻塞进程,直到指定线程数量到达后一起爆发
1),模拟用户的数量:即指定同时释放的线程数数量
2),超时时间,超时多少毫秒后同时释放指定的线程数
6,Beanshell定时器
定义:万能定时器(待补充)