JMeter: Reading CSV with BeanShell

JMeter: CSV Reading with the Help of BeanShell

When it comes to reading data from a CSV file in order to use it in load tests on JMeter, the first recommendation is to use CSV Data Set Config. It is enough for most of scenarios, it works as expected and without errors. However, its behavior turned out to be unpredictable in some particular cases, which cost me a few hours of troubleshooting.

Debug Sampler is an indispensable tool for debugging JMeter scenarios. It helped me to reveal the following problem: during the successive reading of several files with names like <filename>_N.csv (where N changes from 1 to 5, for example) CSV Data Set Config worked unpredictably. To be more precise, while CSV Data Set Config was working, the name of the next file in nested Loop/While Controller was formed incorrectly and there were issues with defining the moment when reading of the current file was finished. A search in Google didn't help - all the examples were with simpler scenarios. As a result, I had to write my own implementation of reading the data from CSV in BeanShell.

Given:

Let's say that there is a web application - "Questionnaire". Every user has to answer 5 sets of questions with X questions in each set (X is different for every set). After answering all questions of one set, you have to go to the next one. To perform load testing, CSV files with answers of the following kind were prepared:

answer1,0
answer2,1
answer3,2
...
answerX,X-1

where the first column contains answers, and the second one - the numbers of questions in a set (answerNum).

The general testing scenario:

  1. Start answering the set of questions nr. i.
  2. Read the data from the file with answers nr. i (line by line).
  3. Unless it is the last line, answer the question nr. j.
  4. If it is the last line, then i++ and move to the next set of questions (point 1).

The implementation of CSV reading:

This implementation describes how to use BeanShell to read CSV file. BeanShell is a JMeter's built-in scripting language. To get it, you have to use BeanShell Sampler component. The code can be downloaded from this link Reading CSV with BeanShell in JMeter manually or see it below:

import java.text.*;
import java.io.*;
import java.util.*;

String filename = "oprosnik_" + vars.get("fileNum") + ".csv";

ArrayList strList = new ArrayList();     

try {
    File file = new File(filename);

    if (!file.exists()) {
        throw new Exception ("ERROR: file " + filename + " not found");
    }

    BufferedReader bufRdr = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF8"));
    String line = null;
    Integer i = 0;

    while((line = bufRdr.readLine()) != null) {
        strList.add(line);
        i++;
    }

    bufRdr.close();            
    counter = Integer.parseInt(vars.get("counter"));
    if (counter != i) {
	    String[] variables = strList.get(counter).split(",");
	    vars.put("answer",variables[0]);
	    vars.put("answerNum",variables[1]);
	    counter++;
	    vars.put("counter",Integer.toString(counter));
    }
    else {
    	    vars.put("answer","<EOF>");
    	    vars.put("eol","<EOF>");
    	    vars.put("counter","0");
    }
}
catch (Exception ex) {
    IsSuccess = false; 
    log.error(ex.getMessage());
    System.err.println(ex.getMessage());
}
catch (Throwable thex) {
    System.err.println(thex.getMessage());
}

You can also download test plan. It is not fully operational because it contains dummy HTTP requests but it gives a rough idea of the general test structure.

I would like to thank Ilya Ponomarenko for his help in investigating this issue.