【发布时间】:2013-01-23 09:37:06
【问题描述】:
我需要用 100 位用户测试网站的各种链接(无需登录),并使用 JMeter 将其循环若干次。我想把这些链接放在一个“CSV文件”中,以便从文件中读取所有要测试的链接。
我该如何完成这项任务?
【问题讨论】:
-
为什么不先尝试在jmeter标签中搜索呢?在这里问了很多次。
标签: csv jmeter load-testing jmeter-plugins
我需要用 100 位用户测试网站的各种链接(无需登录),并使用 JMeter 将其循环若干次。我想把这些链接放在一个“CSV文件”中,以便从文件中读取所有要测试的链接。
我该如何完成这项任务?
【问题讨论】:
标签: csv jmeter load-testing jmeter-plugins
使用您的测试参数列表准备一种 csv 文件,并使用它来参数化您的测试采样器,至少使用以下内容:
查看以下链接了解详情:
How to get Jmeter to use CSV data for GET parameters?
Use jmeter to test multiple Websites
use csv parameters in jmeter httprequest path
Force a thread to use same input line when using CSV Data Set Config
Jmeter 功能:
1. 在 csv 文件中准备您的测试网址,例如格式如下:
url1
url2
...
urlN
确保测试 URL 不包含 http:// 前缀(根据 HTTP Request params -> 服务器)。
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 上回收列表。
【讨论】:
在其中一个 cmets 中提到,您不能在每个循环中多次读取 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 采样器,它基本上采用路径,并将每一行解析并存储为变量。第一行将存储为名为@987654338@ 的变量,第二行将存储为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 请求。
【讨论】: