Jmeter有很多的配置元件可以定义变量值在测试过程中使用
比如最常见的两个:
配置元件主要是用于测试前配置,将配置转换为变量设置到Jmeter context中。
而Jmeter默认并没有配置文件(.properties)读取器,但由于Jmeter是开源的,我们自己可以自定义一个配置元件来读取配置文件。
启动Jmeter后,我们可以从配置元件中看到Property File Reader
,即我们自定义扩展的配置文件。
在测试计划中添加它后,输入配置文件路径:
${__P(Propertyname)}
来获取属性值Jmeter启动扫描扩展下的所有实现了JmterGUIComponent和TestBean接口的类,然后进行初始化。
ClassFinder.findClassesThatExtend( JMeterUtils.getSearchPaths(), new Class[] {JMeterGUIComponent.class, TestBean.class }
ClassFinder.findClassesThatExtend( JMeterUtils.getSearchPaths(), new Class[] {JMeterGUIComponent.class, TestBean.class }
所以只要确保插件的jar包在扩展路径下,默认路径是: JMETER_HOME/lib/ext
由于Jmeter是一个基于Swing的GUI工具,所以对它的GUI框架也需要有一定了解。JMeter内部有两种GUI框架
1.直接继承 JMeterGUIComponent接口的抽象实现类:
org.apache.jmeter.config.gui.AbstractConfigGui org.apache.jmeter.assertions.gui.AbstractAssertionGui org.apache.jmeter.control.gui.AbstractControllerGui org.apache.jmeter.timers.gui.AbstractTimerGui org.apache.jmeter.visualizers.gui.AbstractVisualizer org.apache.jmeter.samplers.gui.AbstractSamplerGui
org.apache.jmeter.config.gui.AbstractConfigGui org.apache.jmeter.assertions.gui.AbstractAssertionGui org.apache.jmeter.control.gui.AbstractControllerGui org.apache.jmeter.timers.gui.AbstractTimerGui org.apache.jmeter.visualizers.gui.AbstractVisualizer org.apache.jmeter.samplers.gui.AbstractSamplerGui
2.通过Swing的Bean绑定机制
前者的好处是自由度高,可定制性强,但需要开发者关心GUI控件布局,以及从控件到Model的转换。 后者基本不需要开发者接触到GUI层的东西,定义好Bean以及BeanInfo即可。但SampleListener不支持BeanInfo方式定义。
首先我们需要新建一个 Maven项目,并导入相关依赖包
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.techstar.plugins.configelement</groupId> <artifactId>PropertyReader</artifactId> <version>1.0-SNAPSHOT</version> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>7</source> <target>7</target> </configuration> </plugin> </plugins> <resources> <!-- 编译之后包含xml和properties --> <resource> <directory>${basedir}/src/main/resources</directory> <includes> <include>**/*</include> </includes> <filtering>true</filtering> </resource> <!--解决构建项目时,target/classes目录下不存在资源文件--> <resource> <directory>${basedir}/src/main/java</directory> <includes> <include>**/*</include> </includes> </resource> </resources> </build> <dependencies> <dependency> <groupId>org.apache.jmeter</groupId> <artifactId>ApacheJMeter_core</artifactId> <version>4.0</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.25</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.11.1</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.11.1</version> </dependency> <dependency> <groupId>org.mongodb</groupId> <artifactId>mongo-java-driver</artifactId> <version>2.9.3</version> </dependency> </dependencies> </project>
Test Bean GUI
TestStateListener
接口来读取配置文件public class PropertyReader extends ConfigTestElement implements TestBean, TestStateListener { //定义根日志器 private static final Logger logger = LogManager.getLogger(PropertyReader.class); //配置文件路径 private String propFilePath; public PropertyReader(){ super(); } /** * 在主线程测试开始之前被调用 * 我们需要在测试前加载配置 */ public void testStarted() { //判断字段是否为空 if (StringUtils.isNotEmpty(getPropFilePath())){ try { //使用传入的字符串返回一个Path对象 Path path = Paths.get(getPropFilePath()); //判断是否为为绝对路径 if (!path.isAbsolute()) { //得到文件路径 path = Paths.get(FileServer.getFileServer().getBaseDir(), path.toString()); } //加载配置文件 JMeterUtils.getJMeterProperties().load(new FileInputStream(path.toString())); logger.info("loading Property:"+path); } catch (FileNotFoundException e) { logger.error(e.getMessage()); } catch (IOException e){ logger.error(e.getMessage()); } } } /** * 在主线程测试开始之前被调用 * @param s */ public void testStarted(String s) { testStarted(); } /** * 测试结束后,所有线程都调用一次 */ public void testEnded() { } /** * 测试结束后,所有线程都调用一次 * @param s */ public void testEnded(String s) { } /** * 返回配置文件路径 * @return */ public String getPropFilePath(){ return this.propFilePath; } /** * 读取配置文件路径 * @param propFilePath */ public void setPropFilePath(String propFilePath){ this.propFilePath = propFilePath; } }
public class PropertyReader extends ConfigTestElement implements TestBean, TestStateListener { //定义根日志器 private static final Logger logger = LogManager.getLogger(PropertyReader.class); //配置文件路径 private String propFilePath; public PropertyReader(){ super(); } /** * 在主线程测试开始之前被调用 * 我们需要在测试前加载配置 */ public void testStarted() { //判断字段是否为空 if (StringUtils.isNotEmpty(getPropFilePath())){ try { //使用传入的字符串返回一个Path对象 Path path = Paths.get(getPropFilePath()); //判断是否为为绝对路径 if (!path.isAbsolute()) { //得到文件路径 path = Paths.get(FileServer.getFileServer().getBaseDir(), path.toString()); } //加载配置文件 JMeterUtils.getJMeterProperties().load(new FileInputStream(path.toString())); logger.info("loading Property:"+path); } catch (FileNotFoundException e) { logger.error(e.getMessage()); } catch (IOException e){ logger.error(e.getMessage()); } } } /** * 在主线程测试开始之前被调用 * @param s */ public void testStarted(String s) { testStarted(); } /** * 测试结束后,所有线程都调用一次 */ public void testEnded() { } /** * 测试结束后,所有线程都调用一次 * @param s */ public void testEnded(String s) { } /** * 返回配置文件路径 * @return */ public String getPropFilePath(){ return this.propFilePath; } /** * 读取配置文件路径 * @param propFilePath */ public void setPropFilePath(String propFilePath){ this.propFilePath = propFilePath; } }
[ComponentName]Beaninfo
,且在同一个包中public class PropertyReaderBeanInfo extends BeanInfoSupport { //创建一个文件路径常量 private static final String FIELD_PROPERTY_FILE_PATH = "propFilePath"; /** * 创建一个无参构造函数 */ public PropertyReaderBeanInfo() { //调用配置文件读取类 super(PropertyReader.class); //在Jmeter GUI中添加字段及设置 //添加"FIELD_PROPERTY_FILE_PATH"字段 PropertyDescriptor p = property(FIELD_PROPERTY_FILE_PATH); //设置该字段必填项 p.setValue(NOT_UNDEFINED,Boolean.FALSE); //设置该字段默认值 p.setValue(DEFAULT,""); } }
public class PropertyReaderBeanInfo extends BeanInfoSupport { //创建一个文件路径常量 private static final String FIELD_PROPERTY_FILE_PATH = "propFilePath"; /** * 创建一个无参构造函数 */ public PropertyReaderBeanInfo() { //调用配置文件读取类 super(PropertyReader.class); //在Jmeter GUI中添加字段及设置 //添加"FIELD_PROPERTY_FILE_PATH"字段 PropertyDescriptor p = property(FIELD_PROPERTY_FILE_PATH); //设置该字段必填项 p.setValue(NOT_UNDEFINED,Boolean.FALSE); //设置该字段默认值 p.setValue(DEFAULT,""); } }
[ComponentName]Resources.properties
#配置元件 displayName=Property File Reader #元素的显示名称 propFilePath.displayName=File Path #元素的简短描述 propFilePath.shortDescription=Absolute Path of the Property file
mvn clean package
命令打包JMETER_HOME/lib/ext
下增加一个BeanShell Sampler去打印配置文件的值
运行测试,检查Jmeter log
插件测试成功~
本文源码:
https://github.com/zuozewei/Jmeter-Porperty-File-Reader-Plugin