Using CSV file to read test data from

后端 未结 2 2038
既然无缘
既然无缘 2020-12-30 06:42

I need to test a various links of a site (no need to login) with 100\'s of users and loop it for some number of times using JMeter. I want to put those links in a \"CSV file

2条回答
  •  隐瞒了意图╮
    2020-12-30 06:52

    In one of the comments, it's mentioned that you can't read the CSV more than once per loop. You can go and have multiple threads, each reading the CSV file once, but then the file is close and won't be read on the next loop. Also, if you set the CSV to recycle, then CSV file is read over and over again indefinitely. So the question becomes how do you loop a CSV file a certain number of times as opposed to indefinitely?

    I posted my answer to that in another post (https://stackoverflow.com/a/64086009/4832515), but I'll copy & paste it incase that link doesn't work in the future.


    I couldn't find a simple solution to this. I ended up using beanshell scripts, which let you use code very similar to java to do some custom stuff. I made an example JMeter project to demonstrate how to do this (yes it's ridiculously complicated, considering all I want to do is repeat the CSV read):


    1. Files:

    my file structure:

    JMeterExample
    |
    ⊢--JMeterTests.jmx             // the JMeter file
    ⊢--example.csv                 // the CSV file
    

    contents of my CSV:

    guest-id-1,"123 fake street",
    guest-id-2,"456 fake street",
    guest-id-3,"789 fake street",
    

    so in this thread group, I'm going to just have 1 user, and I'll loop 2 times. I intend to send 1 request per CSV line. So there should be 6 requests sent total.

    1. Thread Group


    1. User Defined Variables

    This is kind of optional, but the filepath is subject to change, and I don't like changing my scripts just for a change in configuration. So I store the CSV filename in a "User Defined Variables" node.

    If you are storing the CSV file in the same directory as your JMeter test, you can just specify the filename only.

    If you are saving the CSV in a folder other than the directory containing your JMeter file, you will need to supply an absolute path, and then slightly modify the beanshell script below: you'll need to comment out the line that loads the file relatively, and comment in the line that loads from an absolute path.


    1. BeanShell Sampler to parse and store CSV lines

    Add a Beanshell Sampler which will basically take in a path, and parse & store each line as a variable. The first line will be stored as a variable called csv_line_0, the 2nd line will be csv_line_1 and so on. I know it's not a clean solution but... I can't find any clean simple way of doing this clean simple task. I copied and pasted my code below.

    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("")){
                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. Loop Controller

    Add a Loop Controller that loops once for each CSV line. ${linesCount} is a count of the number of CSV lines and is calculated from the above beanShell script.


    1. Beanshell script to extract data from current CSV Line

    This script will run once per CSV line. It will go and grab the current line, and parse out whatever data is on it. You'll have to modify this script to get the data you want. In my example, I only had 2 columns, where column 1 is a "guestId", and column 2 is an "address".

    __jm__loopController__idx is a variable JMeter defines for you, and is the index of the loop controller. The variable name is __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 request sampler

    Here's the HTTP request that's using the data extracted.


    1. result

    When running this, as desired, I end up sending 6 http requests over to the endpoint I defined.

提交回复
热议问题