使用 CSV 文件读取测试数据
Posted
技术标签:
【中文标题】使用 CSV 文件读取测试数据【英文标题】:Using CSV file to read test data from 【发布时间】:2013-01-23 09:37:06 【问题描述】:我需要用 100 位用户测试网站的各种链接(无需登录),并使用 JMeter 将其循环若干次。我想把这些链接放在一个“CSV文件”中,以便从文件中读取所有要测试的链接。
我该如何完成这项任务?
【问题讨论】:
为什么不先尝试在jmeter标签中搜索呢?在这里问了很多次。 相关:sqa.stackexchange.com/q/5577/11978 【参考方案1】:使用您的测试参数列表准备一种 csv 文件,并使用它来参数化您的测试采样器,至少使用以下内容:
CSV Data Set Config
查看以下链接了解详情:
How to get Jmeter to use CSV data for GET parameters?Use jmeter to test multiple Websitesuse csv parameters in jmeter httprequest pathForce a thread to use same input line when using CSV Data Set Config
Jmeter 功能:
__CSVRead, __StringFromFile.Variables From CSV 采样器来自jmeter-plugins。
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 上回收列表。
【讨论】:
谢谢,但我一直面临的问题是,测试在读取 csv 文件中的所有请求后结束。我无法为多个线程运行它,甚至无法在循环中运行它。你能帮忙吗? 好吧,设置“在 EOF 上回收?”和“在 EOF 上停止线程?”以及相应的 CSV Data Set Config 的“共享模式”选项。如果您想从 csv 文件中读取用户凭据和测试链接,您必须设置 2 个 CSV 数据集配置实例:一个用于读取用户凭据并将其分配给线程,另一个 - 读取与每个线程一起使用的测试链接。 好吧,先更新你的答案,更清楚地说明你的问题,提供你的测试脚本架构。 我只是从 CSV 文件中读取测试链接。所有,我想做的是用多个线程/用户测试 CSV 文件中的链接(通过提及线程组中的线程数并提及循环数)我已经尝试过完成这个测试,但主要问题是 CSV 数据集配置中“EOF”的设置。如果“在 EOF 上循环”设置为 False,则测试将在单个线程上停止。并且,如果“在 EOF 上循环?:设置为 True”,则测试将运行无限次。那么,你能告诉我如何处理这个问题吗? 好吧,我特别在上面发布了 2 个指向工作解决方案(this 和 this)的链接,这些链接几乎是您想要的,但似乎您甚至没有尝试过研究。【参考方案2】:在其中一个 cmets 中提到,您不能在每个循环中多次读取 CSV。您可以拥有多个线程,每个线程读取一次 CSV 文件,但随后该文件已关闭且不会在下一个循环中读取。此外,如果您将 CSV 设置为回收,则 CSV 文件会被无限期地反复读取。那么问题就变成了如何循环一个 CSV 文件一定次数而不是无限次?
我在另一篇帖子 (https://***.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 行
添加一个 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 行中提取数据的 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 请求采样器
这是使用提取数据的 HTTP 请求。
-
结果
根据需要运行此程序时,我最终会向我定义的端点发送 6 个 http 请求。
【讨论】:
以上是关于使用 CSV 文件读取测试数据的主要内容,如果未能解决你的问题,请参考以下文章
使用jmeter测试的时候,需要读取csv文件的第三列,csv文件名为test.csv,如何使用函数读取?