Jmeter JSON Config Element开发
作者:互联网
Jmeter 插件开发之Config Element篇
JSON Config Element(TestBean)插件开发
背景:在项目中有个场景需要从json文件中读取数据来并且进行引用,想法是做成和CSV Data Set Config类似,可以从json文件(json数组)中循环读取数据,并且通过JsonPath(使用fastjson的JSONPath类来提取数据)来提取与之匹配的值,提取之后可以在当前线程或者其他线程进行引用。界面如下:
简单介绍一下:
文件名:即读取的json文件路径,json数组
文件编码:即文件读取时的编码
JSON Path 表达式:用来提取JSON数据文件中的
Variable Names:在Jmeter上下文引用的变量
主要步骤如下
1、选择一个包并制作三个文件:
[组件名称].java (jmeter.config.JSONDataSet.java)
[组件名称]BeanInfo.java (jmeter.config.JSONDataSetBeanInfo.java)
[组件名称]Resources.properties (org.apache.jmeter.config.JSONDataSetResources.properties)
如下图:
其中[组件名称]BeanInfo.java 表示Config Element的界面,如本例中的JSONDataSet BeanInfo;[组件名称].java 表示插件的处理逻辑,如本例中的JSONDataSet.java;[组件名称]Resources.properties表示界面显示的文字,同如本例相关文件。
JSONDataSet.java必须实现TestBean接口。此外,它将扩展 ConfigTestElement,并实现LoopIterationListener。(不需要迭代的不用实现)TestBean是一个标记接口,因此没有要实现的方法。扩展ConfigTestElement将使我们的组件成为测试计划中的Config元素。
3、JSONDataSetBeanInfo.java应该扩展org.apache.jmeter.testbeans.BeanInfoSupport
创建一个零参数构造函数,我们在其中调用super(CSVDataSet.class);
4、实现逻辑。
该JSONDataSet将读取一个json数组文件,并会保存它发现到JMeter的运行范围内使用JSONPath匹配的值。为每个要引用的值定义变量名称。实现TestBean 时,请注意属性。这些属性将成为用户配置JSONDataSet元素的 GUI 表单的基础。
测试开始时,JMeter 将克隆您的元素。每个线程都会得到它自己的实例。但是,如果需要,您将有机会控制克隆的完成方式。
variableNames是一个字符串,它允许用户输入我们将为其赋值的变量的名称。为什么是字符串?为什么不是一个集合?用户肯定需要输入多个(和未知数量的)变量名称吗?是的,但是如果我们使用 List 或 Collection,我们就必须编写一个 GUI 组件来处理集合,而我只想快速完成。相反,我们将让用户输入以逗号分隔的变量名称列表。
然后我实现了LoopIterationListener接口的IterationStart方法。这个“事件”的重点是当测试进入它的父控制器时通知你的组件。出于我们的目的,每次输入JSONDataSet的父控制器时,我们都会读取数据文件的新对象并设置变量。因此,对于常规控制器,每次测试循环都会导致读取一组新值。对于循环控制器,每次迭代都会这样做。每个测试线程也会得到不同的值。
具体逻辑实现如下:
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package jmeter.config;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONPath;
import org.apache.commons.lang3.StringUtils;
import org.apache.jmeter.config.ConfigTestElement;
import org.apache.jmeter.engine.event.LoopIterationEvent;
import org.apache.jmeter.engine.event.LoopIterationListener;
import org.apache.jmeter.testbeans.TestBean;
import org.apache.jmeter.testbeans.gui.GenericTestBeanCustomizer;
import org.apache.jmeter.testelement.property.JMeterProperty;
import org.apache.jmeter.testelement.property.StringProperty;
import org.apache.jmeter.threads.JMeterContext;
import org.apache.jmeter.threads.JMeterVariables;
import org.apache.jmeter.util.JMeterUtils;
import org.apache.jorphan.util.JMeterStopThreadException;
import org.apache.jorphan.util.JOrphanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.io.*;
import java.util.*;
/**
* Read lines from a file and split int variables.
* <p>
* The iterationStart() method is used to set up each set of values.
* <p>
* By default, the same file is shared between all threads
* (and other thread groups, if they use the same file name).
* <p>
* The shareMode can be set to:
* <ul>
* <li>All threads - default, as described above</li>
* <li>Current thread group</li>
* <li>Current thread</li>
* <li>Identifier - all threads sharing the same identifier</li>
* </ul>
* <p>
* The class uses the FileServer alias mechanism to provide the different share modes.
* For all threads, the file alias is set to the file name.
* Otherwise, a suffix is appended to the filename to make it unique within the required context.
* For current thread group, the thread group identityHashcode is used;
* for individual threads, the thread hashcode is used as the suffix.
* Or the user can provide their own suffix, in which case the file is shared between all
* threads with the same suffix.
*/
public class JSONDataSet extends ConfigTestElement
implements TestBean, LoopIterationListener {
private static final Logger log = LoggerFactory.getLogger(JSONDataSet.class);
private static final long serialVersionUID = 233L;
private static final String EOFVALUE = // value to return at EOF
JMeterUtils.getPropDefault("jsondataset.eofstring", "<EOF>"); //$NON-NLS-1$ //$NON-NLS-2$
private transient String filename;
private transient String fileEncoding;
private transient String variableNames;
private transient String jsonpathExpression;
private transient boolean recycle = true;
private transient boolean stopThread;
private transient String[] vars;
private transient String[] jsonPathVars;
// private transient String alias;
private transient String shareMode;
/**
* @return Returns the filename.
*/
public String getFilename() {
return filename;
}
/**
* @param filename The filename to set.
*/
public void setFilename(String filename) {
this.filename = filename;
}
/**
* @return Returns the file encoding.
*/
public String getFileEncoding() {
return fileEncoding;
}
/**
* @param fileEncoding The fileEncoding to set.
*/
public void setFileEncoding(String fileEncoding) {
this.fileEncoding = fileEncoding;
}
/**
* @return Returns the variableNames.
*/
public String getVariableNames() {
return variableNames;
}
/**
* @param variableNames The variableNames to set.
*/
public void setVariableNames(String variableNames) {
this.variableNames = variableNames;
}
public String getJsonpathExpression() {
return jsonpathExpression;
}
public void setJsonpathExpression(String jsonpathExpression) {
this.jsonpathExpression = jsonpathExpression;
}
public boolean getRecycle() {
return recycle;
}
public void setRecycle(boolean recycle) {
this.recycle = recycle;
}
public boolean getStopThread() {
return stopThread;
}
public void setStopThread(boolean value) {
this.stopThread = value;
}
public String getShareMode() {
return shareMode;
}
public void setShareMode(String value) {
this.shareMode = value;
}
private Object readResolve() {
recycle = true;
return this;
}
/**
* Override the setProperty method in order to convert
* the original String shareMode property.
* This used the locale-dependent display value, so caused
* problems when the language was changed.
* If the "shareMode" value matches a resource value then it is converted
* into the resource key.
* To reduce the need to look up resources, we only attempt to
* convert values with spaces in them, as these are almost certainly
* not variables (and they are definitely not resource keys).
*/
@Override
public void setProperty(JMeterProperty property) {
if (property instanceof StringProperty) {
final String propName = property.getName();
if ("shareMode".equals(propName)) { // The original name of the property
final String propValue = property.getStringValue();
if (propValue.contains(" ")) { // variables are unlikely to contain spaces, so most likely a translation
try {
final BeanInfo beanInfo = Introspector.getBeanInfo(this.getClass());
final ResourceBundle rb = (ResourceBundle) beanInfo.getBeanDescriptor().getValue(GenericTestBeanCustomizer.RESOURCE_BUNDLE);
for (String resKey : JSONDataSetBeanInfo.getShareTags()) {
if (propValue.equals(rb.getString(resKey))) {
if (log.isDebugEnabled()) {
log.debug("Converted {}={} to {} using Locale: {}", propName, propValue, resKey, rb.getLocale());
}
((StringProperty) property).setValue(resKey); // reset the value
super.setProperty(property);
return;
}
}
// This could perhaps be a variable name
log.warn("Could not translate {}={} using Locale: {}", propName, propValue, rb.getLocale());
} catch (IntrospectionException e) {
log.error("Could not find BeanInfo; cannot translate shareMode entries", e);
}
}
}
}
super.setProperty(property);
}
@Override
public void iterationStart(LoopIterationEvent iterEvent) {
// FileServer server = FileServer.getFileServer();
final JMeterContext context = getThreadContext();//Jmeter 上下文
int index = 0;
if (vars == null) {
String fileName = getFilename().trim();
// fileName="D:/ASCS-sit/app/sit/sortplan/755WF/LF/S{白班(新一体机04P和记、莞陆混版)集初分,6,XC,JCG,755WF}_C{1}_V{755WF[JSH]-1.0.0(1.2)-20210715182052}.json";
String mode = getShareMode();
int modeInt = JSONDataSetBeanInfo.getShareModeAsInt(mode);
// switch (modeInt) {
// case JSONDataSetBeanInfo.SHARE_ALL:
// alias = fileName;
// break;
// case JSONDataSetBeanInfo.SHARE_GROUP:
// alias = fileName + "@" + System.identityHashCode(context.getThreadGroup());
// break;
// case JSONDataSetBeanInfo.SHARE_THREAD:
// alias = fileName + "@" + System.identityHashCode(context.getThread());
// break;
// default:
// alias = fileName + "@" + mode; // user-specified key
// break;
// }
//获取引用的变量
final String names = getVariableNames();//引用变量
final String jsonNames = getJsonpathExpression();
if (!StringUtils.isEmpty(names)) {
// server.reserveFile(fileName, getFileEncoding(), alias);
// 提取引用变量到数组
vars = JOrphanUtils.split(names, ",");
log.info("===============================================" + vars.toString());
//提取JsonPath变量并存到数组
jsonPathVars = JOrphanUtils.split(jsonNames, ",");
log.info("jsonPathVars数组长度为:" + jsonPathVars.length);
} else {
throw new IllegalArgumentException("Could not split JSON Path Expression line from file:" + fileName);
}
trimVarNames(vars);
//获取数据
// TODO: fetch this once as per vars above?
JMeterVariables threadVars = context.getVariables();
String[] jsonLineValues = {};//存取使用JsonPath提取后的值
//分割JsonPath表达式提取的值并存到数组
jsonLineValues = JOrphanUtils.split(jsonNames, ",", false);
log.info("===============================================" + fileName);
String jsonFile = readJsonFile(fileName);
//从json输入文件中,读取一个Json对象
JSONArray jsonArray = JSON.parseArray(jsonFile);
log.info("***************************index: " + "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" + iterEvent.getIteration());
System.out.println("============================********************" + threadVars.getIteration());
String num=threadVars.getThreadName().split("-")[1];
index=Integer.parseInt(num);
JSONObject jsonObject = jsonArray.getJSONObject(index);
String line = jsonObject.toJSONString();
log.info("===" + line);
String jsonValue;
for (int i = 0; i < jsonPathVars.length; i++) {
log.info("i " + i + "==========================");
log.info("i: " + jsonPathVars[i]);
jsonValue = JSONPath.read(line, jsonPathVars[i]).toString();
jsonLineValues[i] = jsonValue;
}
//提取Json Path匹配的值,经过jsonpath转换的值
// lineValues = JOrphanUtils.split(line, ",", false);
for (int a = 0; a < vars.length && a < jsonLineValues.length; a++) {
threadVars.put(vars[a], jsonLineValues[a]);
}
if (jsonLineValues.length == 0) {// i.e. EOF
if (getStopThread()) {
throw new JMeterStopThreadException("End of file:" + getFilename() + " detected for JSON DataSet:"
+ getName() + " configured with stopThread:" + getStopThread() + ", recycle:" + getRecycle());
}
for (String var : vars) {
threadVars.put(var, EOFVALUE);
}
}
threadVars.incIteration();
}
}
/**
* trim content of array varNames
*
* @param varsNames
*/
private void trimVarNames(String[] varsNames) {
for (int i = 0; i < varsNames.length; i++) {
varsNames[i] = varsNames[i].trim();
}
}
//读取json文件
public static String readJsonFile(String fileName) {
String jsonStr = "";
try {
File jsonFile = new File(fileName);
FileReader fileReader = new FileReader(jsonFile);
Reader reader = new InputStreamReader(new FileInputStream(jsonFile), "utf-8");
int ch = 0;
StringBuffer sb = new StringBuffer();
while ((ch = reader.read()) != -1) {
sb.append((char) ch);
}
fileReader.close();
reader.close();
jsonStr = sb.toString();
return jsonStr;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
在JSONDataSetBeanInfo 中设置 GUI 元素:
我们可以为组件的属性创建分组。创建的每个分组都需要一个标签和要包含在该分组中的属性名称列表。IE:
createPropertyGroup("json_data", //$NON-NLS-1$
new String[]{FILENAME, FILE_ENCODING, JSONPATH_EXP,VARIABLE_NAMES,
RECYCLE, STOPTHREAD, SHAREMODE});
创建分组称为json_data,其中将包括在GUI上的输入元件 的文件名和variableNames的性质JSONDataSet。然后,我们需要定义我们希望这些属性的类型:
PropertyDescriptor p = property(FILENAME);
p.setValue(NOT_UNDEFINED, Boolean.TRUE);
p.setValue(DEFAULT, ""); //$NON-NLS-1$
p.setValue(NOT_EXPRESSION, Boolean.TRUE);
p.setPropertyEditorClass(FileEditor.class);
p = property(FILE_ENCODING, TypeEditor.ComboStringEditor);
p.setValue(NOT_UNDEFINED, Boolean.TRUE);
p.setValue(DEFAULT, ""); //$NON-NLS-1$
p.setValue(TAGS, getListFileEncoding());
//jsonpath表达式用","分隔
p = property(JSONPATH_EXP);
p.setValue(NOT_UNDEFINED, Boolean.TRUE);
p.setValue(DEFAULT, ""); //$NON-NLS-1$
p.setValue(NOT_EXPRESSION, Boolean.TRUE);
p = property(VARIABLE_NAMES);
p.setValue(NOT_UNDEFINED, Boolean.TRUE);
p.setValue(DEFAULT, ""); //$NON-NLS-1$
p.setValue(NOT_EXPRESSION, Boolean.TRUE);
p = property(RECYCLE);
p.setValue(NOT_UNDEFINED, Boolean.TRUE);
p.setValue(DEFAULT, Boolean.TRUE);
p = property(STOPTHREAD);
p.setValue(NOT_UNDEFINED, Boolean.TRUE);
p.setValue(DEFAULT, Boolean.FALSE);
p = property(SHAREMODE, TypeEditor.ComboStringEditor);
p.setValue(RESOURCE_BUNDLE, getBeanDescriptor().getValue(RESOURCE_BUNDLE));
p.setValue(NOT_UNDEFINED, Boolean.TRUE);
p.setValue(DEFAULT, SHARE_TAGS[SHARE_ALL]);
p.setValue(NOT_OTHER, Boolean.FALSE);
p.setValue(NOT_EXPRESSION, Boolean.FALSE);
p.setValue(TAGS, SHARE_TAGS);
这实质上创建了7个属性,其值不允许为null,其默认值为""。可以为每个属性设置几个这样的属性。这是一个纲要:
NOT_UNDEFINED
该属性不会保留为null。
DEFAULT
如果NOT_UNDEFINED为true ,则必须给出默认值。
NOT_EXPRESSION
如果为true ,则不会为函数解析该值。
NOT_OTHER
这不是一个自由形式的输入字段——必须提供一个值列表。
TAGS
使用String[]作为值,这将设置可接受值的预定义列表,JMeter 将创建一个下拉选择。
此外,可以为属性指定自定义属性编辑器:
p.setPropertyEditorClass(FileEditor.class);
这将创建一个文本输入和浏览按钮,该按钮打开一个用于查找文件的对话框。
详细的GUI文件定义如下:
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package jmeter.config;
import org.apache.jmeter.testbeans.BeanInfoSupport;
import org.apache.jmeter.testbeans.gui.FileEditor;
import org.apache.jmeter.testbeans.gui.TypeEditor;
import org.apache.jmeter.util.JMeterUtils;
import org.apache.jorphan.util.JOrphanUtils;
import java.beans.PropertyDescriptor;
public class JSONDataSetBeanInfo extends BeanInfoSupport {
static final int SHARE_ALL = 0;
static final int SHARE_GROUP = 1;
static final int SHARE_THREAD = 2;
// These names must agree case-wise with the variable and property names
private static final String FILENAME = "filename"; //$NON-NLS-1$
private static final String FILE_ENCODING = "fileEncoding"; //$NON-NLS-1$
private static final String VARIABLE_NAMES = "variableNames"; //$NON-NLS-1$
private static final String JSONPATH_EXP = "jsonpathExpression";
private static final String RECYCLE = "recycle"; //$NON-NLS-1$
private static final String STOPTHREAD = "stopThread"; //$NON-NLS-1$
private static final String SHAREMODE = "shareMode"; //$NON-NLS-1$
// Access needed from CSVDataSet
private static final String[] SHARE_TAGS = new String[3];
// Store the resource keys
static {
SHARE_TAGS[SHARE_ALL] = "shareMode.all"; //$NON-NLS-1$
SHARE_TAGS[SHARE_GROUP] = "shareMode.group"; //$NON-NLS-1$
SHARE_TAGS[SHARE_THREAD] = "shareMode.thread"; //$NON-NLS-1$
}
public JSONDataSetBeanInfo() {
super(JSONDataSet.class);
createPropertyGroup("json_data", //$NON-NLS-1$
new String[]{FILENAME, FILE_ENCODING, JSONPATH_EXP,VARIABLE_NAMES,
RECYCLE, STOPTHREAD, SHAREMODE});
PropertyDescriptor p = property(FILENAME);
p.setValue(NOT_UNDEFINED, Boolean.TRUE);
p.setValue(DEFAULT, ""); //$NON-NLS-1$
p.setValue(NOT_EXPRESSION, Boolean.TRUE);
p.setPropertyEditorClass(FileEditor.class);
p = property(FILE_ENCODING, TypeEditor.ComboStringEditor);
p.setValue(NOT_UNDEFINED, Boolean.TRUE);
p.setValue(DEFAULT, ""); //$NON-NLS-1$
p.setValue(TAGS, getListFileEncoding());
//jsonpath表达式用","分隔
p = property(JSONPATH_EXP);
p.setValue(NOT_UNDEFINED, Boolean.TRUE);
p.setValue(DEFAULT, ""); //$NON-NLS-1$
p.setValue(NOT_EXPRESSION, Boolean.TRUE);
p = property(VARIABLE_NAMES);
p.setValue(NOT_UNDEFINED, Boolean.TRUE);
p.setValue(DEFAULT, ""); //$NON-NLS-1$
p.setValue(NOT_EXPRESSION, Boolean.TRUE);
p = property(RECYCLE);
p.setValue(NOT_UNDEFINED, Boolean.TRUE);
p.setValue(DEFAULT, Boolean.TRUE);
p = property(STOPTHREAD);
p.setValue(NOT_UNDEFINED, Boolean.TRUE);
p.setValue(DEFAULT, Boolean.FALSE);
p = property(SHAREMODE, TypeEditor.ComboStringEditor);
p.setValue(RESOURCE_BUNDLE, getBeanDescriptor().getValue(RESOURCE_BUNDLE));
p.setValue(NOT_UNDEFINED, Boolean.TRUE);
p.setValue(DEFAULT, SHARE_TAGS[SHARE_ALL]);
p.setValue(NOT_OTHER, Boolean.FALSE);
p.setValue(NOT_EXPRESSION, Boolean.FALSE);
p.setValue(TAGS, SHARE_TAGS);
}
public static int getShareModeAsInt(String mode) {
if (mode == null || mode.length() == 0) {
return SHARE_ALL; // default (e.g. if test plan does not have definition)
}
for (int i = 0; i < SHARE_TAGS.length; i++) {
if (SHARE_TAGS[i].equals(mode)) {
return i;
}
}
return -1;
}
/**
* @return array of String for possible sharing modes
*/
public static String[] getShareTags() {
String[] copy = new String[SHARE_TAGS.length];
System.arraycopy(SHARE_TAGS, 0, copy, 0, SHARE_TAGS.length);
return copy;
}
/**
* Get the mains file encoding
* list from https://docs.oracle.com/javase/8/docs/technotes/guides/intl/encoding.doc.html
*
* @return a String[] with the list of file encoding
*/
private String[] getListFileEncoding() {
return JOrphanUtils.split(JMeterUtils.getPropDefault("csvdataset.file.encoding_list", ""), "|"); //$NON-NLS-1$
}
}
- 定义资源字符串。
在JSONDataSetResources.properties 中,我们必须定义所有字符串资源。为了提供翻译,可以创建其他文件,例如 JSONDataSetResources_ja.properties和JSONDataSetResources_de.properties。对于我们的组件,我们必须定义以下资源:
displayName
这将为将出现在菜单中的元素提供一个名称。
json_data.displayName
我们创建了一个名为csv_data的属性分组,因此我们必须为分组提供一个标签
filename.displayName
文件名输入元素的标签。
filename.shortDescription(当鼠标定位到GUI输入框名称提示性文字)
类似工具提示的帮助文本简介。
variableNames.displayName
变量名称输入元素的标签。
variableNames.shortDescription
variableNames输入元素的工具提示。
详细的资源定义如下:
displayName=JSON Data Set Config
#控制面板名称
json_data.displayName=Config the JSON Data Source
filename.displayName=FileName
filename.shortDescription=Name of the file that holds the json data (relative or absolute filename)
fileEncoding.displayName=File encoding
fileEncoding.shortDescription=The character set encoding used in the file
jsonpathExpression.displayName=JSON Path Expression(comma-delimited)
jsonpathExpression.shortDescription=JSON Path Expressions in order to match the order of data in your json data
variableNames.displayName=Variable Names (comma-delimited)
variableNames.shortDescription=List your variable names in order to match the order of columns in your json data. Keep it empty to use the first line of the file for variable names.
recycle.displayName=Recycle on EOF ?
recycle.shortDescription=Should the file be re-read from the start on reaching EOF ?
stopThread.displayName=Stop thread on EOF ?
stopThread.shortDescription=Should the thread be stopped on reaching EOF (if Recycle is false) ?
shareMode.displayName=Sharing mode
shareMode.shortDescription=Select which threads share the same file pointer
shareMode.all=All threads
shareMode.group=Current thread group
shareMode.thread=Current thread
Pom文件如下:
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
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.test.jmeter</groupId>
<artifactId>JmeterFunctions</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>JmeterFunctions</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<repositories>
</repositories>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>compile</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.73</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.zxing/zxing-parent -->
<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_core</artifactId>
<version>5.2.1</version>
<exclusions>
<exclusion>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_java</artifactId>
<version>5.2.1</version>
<exclusions>
<exclusion>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.jmeter</groupId>
<artifactId>ApacheJMeter_core</artifactId>
<version>5.2.1</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.test.util.GenerateSortCode</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
调试组件。
逻辑实现完后使用maven打包然后放到Jmeter\lib\ext目录下后重启Jmeter即可在Config Element中找到我们开发的JSON DataSet Config,然后可以使用json数组文件试一下,运行结果如下图:
标签:setValue,String,JSON,Boolean,import,apache,org,Jmeter,Config 来源: https://blog.csdn.net/TalorSwfit20111208/article/details/120371672