我需要使用 100 位用户测试网站的各种链接(无需登录),并使用 JMeter 将其循环若干次。我想将这些链接放在“CSV 文件”中,以便从文件中读取所有要测试的链接。
我如何完成这项任务?
我需要使用 100 位用户测试网站的各种链接(无需登录),并使用 JMeter 将其循环若干次。我想将这些链接放在“CSV 文件”中,以便从文件中读取所有要测试的链接。
我如何完成这项任务?
使用您的测试参数列表准备一种 csv 文件,并使用它来参数化您的测试采样器,至少使用以下内容:
查看以下链接了解详细信息:
如何让 Jmeter 将 CSV 数据用于 GET 参数?
使用 jmeter 测试多个网站
在 jmeter httprequest 路径中使用 csv 参数
使用 CSV 数据集配置时强制线程使用相同的输入行
Jmeter功能:
来自jmeter-plugins 的CSV采样器的变量。
1.在 csv 文件中准备您的测试 URL,例如,采用以下格式:
url1
url2
...
urlN
确保测试 URL 不包含http://
前缀(根据HTTP 请求参数-> 服务器)。
2.为您的脚本使用架构,如下所示:
CSV Data Set Config:
Filename: [path to your csv-file with test-urls]
Variable Names: testURL
Recycle on EOF?: True
Stop thread on EOF?: False
Sharing mode: Current thread
Thread Group:
Number of Threads: N
Loop Count: M
HTTP Request // your http call
Server Name or IP: ${testURL} // use variable with extracted URL
这将启动 N 个用户,每个用户将从 test-urls 列表中读取 M 个条目。如果 M > test-urls 列表中的条目数,则用户将在 EOF 上回收列表。
在其中一条评论中提到,您不能在每个循环中多次读取 CSV。您可以拥有多个线程,每个线程读取一次 CSV 文件,但随后该文件已关闭,并且不会在下一个循环中读取。此外,如果您将 CSV 设置为回收,则 CSV 文件会被无限期地反复读取。所以问题变成了如何循环一个 CSV 文件一定次数而不是无限期地循环?
我在另一篇文章(https://stackoverflow.com/a/64086009/4832515)中发布了我的答案,但我会复制并粘贴它,以防该链接将来无法正常工作。
我找不到一个简单的解决方案。我最终使用了 beanshell 脚本,它允许您使用与 java 非常相似的代码来做一些自定义的事情。我制作了一个示例 JMeter 项目来演示如何做到这一点(是的,它非常复杂,考虑到我想要做的就是重复 CSV 读取):
我的文件结构:
JMeterExample
|
⊢--JMeterTests.jmx // the JMeter file
⊢--example.csv // the CSV file
我的 CSV 内容:
guest-id-1,"123 fake street",
guest-id-2,"456 fake street",
guest-id-3,"789 fake street",
所以在这个线程组中,我将只有 1 个用户,我会循环 2 次。我打算每 CSV 行发送 1 个请求。所以应该总共发送 6 个请求。
这是一种可选的,但文件路径可能会发生变化,而且我不喜欢仅仅为了改变配置而改变我的脚本。所以我将 CSV 文件名存储在“用户定义的变量”节点中。
如果您将 CSV 文件存储在与 JMeter 测试相同的目录中,则只需指定文件名即可。
如果您将 CSV 保存在包含 JMeter 文件的目录以外的文件夹中,则需要提供绝对路径,然后稍微修改下面的 beanshell 脚本:您需要注释掉相对加载文件的行, 并在从绝对路径加载的行中添加注释。
添加一个 Beanshell 采样器,它基本上采用路径,并将每一行解析并存储为变量。第一行将存储为一个名为 的变量csv_line_0
,第二行将是csv_line_1
等等。我知道这不是一个干净的解决方案,但是......我找不到任何干净简单的方法来完成这个干净简单的任务。我在下面复制并粘贴了我的代码。
import org.apache.jmeter.services.FileServer;
import java.text.*;
import java.io.*;
import java.util.*;
String temp = null;
ArrayList lines = new ArrayList();
BufferedReader bufRdr;
ArrayList strList = new ArrayList();
// get the file
try {
// you can use this line below if your csvFilePath is an absolute path
// File file = new File(${csvFilePath});
// you can use this line below if your csvFilepath is a relative path, relative to where you saved this JMeter file
File file = new File(org.apache.jmeter.services.FileServer.getFileServer().getBaseDir() + "/" + ${csvFilePath});
if (!file.exists()) {
throw new Exception ("ERROR: file " + filename + " not found");
}
bufRdr = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF8"));
} catch(Exception e){
log.error("failed to load file");
log.error(e.getMessage());
return;
}
// For each CSV line, save it to a variable
int counter = 0;
while(true){
try{
temp = bufRdr.readLine();
if(temp == null || temp.equals("<EOF>")){
break;
}
lines.add(temp);
vars.put("csv_line_" + String.valueOf(counter), temp);
counter++;
} catch(Exception e){
log.error("failed to get next line");
log.error(e.getMessage());
break;
}
}
// store the number of CSV lines there are for the loop counter
vars.put("linesCount", String.valueOf(lines.size()));
添加一个循环控制器,为每条 CSV 行循环一次。${linesCount}
是 CSV 行数的计数,由上述 beanShell 脚本计算得出。
此脚本将在每个 CSV 行运行一次。它会去抓取当前行,并解析出上面的任何数据。您必须修改此脚本以获取所需的数据。在我的示例中,我只有 2 列,其中第 1 列是“guestId”,第 2 列是“地址”。
__jm__loopController__idx
是 JMeter 为你定义的变量,是循环控制器的索引。变量名是__jm__{loop controller name}__idx
。
String index = vars.get("__jm__loopController__idx");
String line = vars.get("csv_line_" + index);
String [] tokens = line.split(",");
vars.put("guestId", tokens[0]);
vars.put("address", tokens[1]);
这是使用提取的数据的 HTTP 请求。
运行时,根据需要,我最终将 6 个 http 请求发送到我定义的端点。