使用 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 采样器,它基本上采用路径,并将每一行解析并存储为变量。第一行将存储为名为@9​​87654338@ 的变量,第二行将存储为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文件读取大量测试数据

使用jmeter测试的时候,需要读取csv文件的第三列,csv文件名为test.csv,如何使用函数读取?

如何批量读取csv格式的文件名及文件内容到新的Excel中?

使用PostMan自动从文件中读取参数发送测试请求

无法读取炮兵脚本文件中的 CSV 文件

gh读取csv文件