13

我需要使用 100 位用户测试网站的各种链接(无需登录),并使用 JMeter 将其循环若干次。我想将这些链接放在“CSV 文件”中,以便从文件中读取所有要测试的链接。

我如何完成这项任务?

4

2 回答 2

22

使用您的测试参数列表准备一种 csv 文件,并使用它来参数化您的测试采样器,至少使用以下内容:

  1. CSV 数据集配置

    查看以下链接了解详细信息:

    如何让 Jmeter 将 CSV 数据用于 GET 参数?
    使用 jmeter 测试多个网站
    在 jmeter httprequest 路径中使用 csv 参数
    使用 CSV 数据集配置时强制线程使用相同的输入行

  2. Jmeter功能:

  3. 来自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 上回收列表。

于 2013-01-23T10:24:48.327 回答
0

在其中一条评论中提到,您不能在每个循环中多次读取 CSV。您可以拥有多个线程,每个线程读取一次 CSV 文件,但随后该文件已关闭,并且不会在下一个循环中读取。此外,如果您将 CSV 设置为回收,则 CSV 文件会被无限期地反复读取。所以问题变成了如何循环一个 CSV 文件一定次数而不是无限期地循环?

我在另一篇文章(https://stackoverflow.com/a/64086009/4832515)中发布了我的答案,但我会复制并粘贴它,以防该链接将来无法正常工作。


我找不到一个简单的解决方案。我最终使用了 beanshell 脚本,它允许您使用与 java 非常相似的代码来做一些自定义的事情。我制作了一个示例 JMeter 项目来演示如何做到这一点(是的,它非常复杂,考虑到我想要做的就是重复 CSV 读取):


  1. 文件:

我的文件结构:

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 个请求。

  1. 线程组

在此处输入图像描述


  1. 用户定义的变量

这是一种可选的,但文件路径可能会发生变化,而且我不喜欢仅仅为了改变配置而改变我的脚本。所以我将 CSV 文件名存储在“用户定义的变量”节点中。

如果您将 CSV 文件存储在与 JMeter 测试相同的目录中,则只需指定文件名即可。

如果您将 CSV 保存在包含 JMeter 文件的目录以外的文件夹中,则需要提供绝对路径,然后稍微修改下面的 beanshell 脚本:您需要注释掉相对加载文件的行, 并在从绝对路径加载的行中添加注释。

在此处输入图像描述


  1. BeanShell Sampler 解析和存储 CSV 行

添加一个 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()));

  1. 回路控制器

添加一个循环控制器,为每条 CSV 行循环一次。${linesCount}是 CSV 行数的计数,由上述 beanShell 脚本计算得出。

在此处输入图像描述


  1. 从当前 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]);

  1. Http请求采样器

这是使用提取的数据的 HTTP 请求。

在此处输入图像描述


  1. 结果

运行时,根据需要,我最终将 6 个 http 请求发送到我定义的端点。

在此处输入图像描述

于 2020-09-27T16:51:01.120 回答