JMeter - Read Files from Directory - jmeter

Using Apache JMeter
First question: I was able to read one single file (containing all the data) from a directory and use its data.
However now the requirement is to have a separate file for each data point, that means I will have to put many data files in a directory and then read the files off that directory. I have a set of data files, but I do not know how to read each of the files in a loop and send it to JMeter.
Second Question: the data we are talking about here is a JSON msg, and it's indented and multi-line, how to read a multi-line file into a single input variable? Again, I had no problem when the JSON msg is a single line.

Use Beanshell Sampler to convert files list into a JMeter Variable:
Add a Beanshell Sampler to your test plan
Put the following code into the Sampler's "Script" area:
File folder = new File("/path/to/your/folder");
File[] files = folder.listFiles();
int counter = 1;
for (File file : files) {
vars.put("file_" + counter, file.getAbsolutePath());
counter++;
}
It will result into variables set like:
file_1=/path/to/your/folder/file1.txt
file_2=/path/to/your/folder/file2.txt
etc.
Add ForEach Controller after Beanshell Sampler and configure it as follows:
Input variable prefix: file
Start index for loop: 0
End index for loop: leave blank
Output variable name: anything meaningful, i.e. current_file
Check Add "_" before number
Put your main sampler as a child of the ForEach Controller. Where required address each file contents using __FileToString() function as ${__FileToString(${current_file},,)}

If using the directory listing data source, in order to loop through you should use the where you would use $current_file. __FileToString() function as ${__FileToString(${current_file},,)} mentioned above by Dmitri T and alexandrul.
Very simple to over look.

you can use below code to read file data
FileWriter fWriter = new FileWriter("D:\\report\\Results.csv",true);
BufferedWriter buff = new BufferedWriter(fWriter);
buff.write("file created \n");
buff.close();
fWriter.close();

Related

In Jmeter how I generate hundreds of xml payload files and use them for the test

Here is what I am trying to do using Jmeter
Firstly,I would like create hundreds of xml payload files with different values and save them in to a folder at some location-How can I achieve that?
Secondly,I would like to use and run the test the generated xml payload files from the folder of above-How can I achieve that?
Much appreciated the thoughts!
Thanks, Raj
For creating XML you can use a suitable JSR223 Test Element, i.e. JSR223 Sampler and generate XML files using Groovy code like:
import groovy.xml.MarkupBuilder
import org.apache.commons.lang3.RandomStringUtils
import org.apache.commons.lang3.RandomUtils
1.upto(2, {
def writer = new StringWriter()
def xml = new MarkupBuilder(writer)
xml.records() {
foo(name: RandomStringUtils.randomAlphabetic(5), make: RandomStringUtils.randomAlphabetic(7), year: RandomUtils.nextInt(1000, 9999)) {
country(RandomStringUtils.randomAlphabetic(10))
record(type: RandomStringUtils.randomAlphabetic(15), RandomStringUtils.randomAlphabetic(10))
}
}
new File("test" + "$it" + ".xml") << writer
})
it will create files like test1.xml and test2.xml with random content in "bin" folder of your JMeter installation
The easiest way of using the generated files is Directory Listing Config element, it reads files from the specified folder into a JMeter Variable which will hold the path to the specified file. The file in its turn can be "read" using __FileToString() function

Read multiple CSV files automatically from a directory inside a ForEach Controller with JMeter

Im trying to read multiple CSV files from a special directory inside a While Controller to convert the data in the files to a specific JMeter property/variable. But I always get an error:
ERROR - jmeter.threads.JMeterThread: Test failed! java.lang.IllegalArgumentException: File ${CURRENTACTIONATTRIBUTEFILE} must exist and be readable
Is it possible that the variable isn't evaluated at this moment? (__V doesn't change anything).I really have no idea why this isn't working.
When I place a Debug Sampler between the ForEach and the While Controller it shows me the JMeterVariable CURRENTACTIONATTRIBUTEFILE has the correct path and file name (when I paste this string hardcoded in the CSV data set config filename it works):
CURRENTACTIONATTRIBUTEFILE=C:/#JMeter/Plans/PRODUCT/61_RISK2VALUE/61_RISK2VALUE - Resources/ModelingData/ActionAttributes/ActionAttributes_AM2.csv
This is what my Testplan Setup looks like:
CREATE file variables: groovy sampler, which checks a special directory and creates numbered vars with the file path + name + extension and a var with the count of the files found in the directory
ForEach Controller
While Controller
CSV Data Set Config (Filename: ${CURRENTACTIONATTRIBUTEFILE)
CREATE variables: groovy sampler, which creates properties/vars to a special convention I need
"CREATE file variables" - sampler code:
String actionAttributeFilePath = "${PATHPLAN}${PATHMODELINGDATA}ActionAttributes/";
File modelingDataDirectory = new File(actionAttributeFilePath);
File[] files = modelingDataDirectory.listFiles();
int fileCounter = 1;
for (File file : files) {
if(file)
{
String actionAttributeFile = actionAttributeFilePath + file.getName();
vars.put("ACTIONATTRIBUTEFILE_" + fileCounter, actionAttributeFile);
fileCounter++;
}
}
vars.put("ACTIONATTRIBUTEFILE_COUNT", Integer.toString(fileCounter-1))
"CREATE variables" - sampler code (not relevant for my problem):
All variables names used below, come from the CSV data set config.
if ("${ATTRIBUTEDEFINITIONID}" != "<EOF>")
{
def variableName = sprintf('ATTRIBUTE%2$sDEFINITIONID_%1$s',["${ATTRIBUTEFORMULANAME}", "${ATTRIBUTETYPE}"])
props.put(variableName,"${ATTRIBUTEDEFINITIONID}");
}
You won't be able to use a JMeter Variable as a CSV Data Set Config filename as CSV Data Set Config is being initialized before any variables.
The only way to make this dynamic is using JMeter Property instead of JMeter Variable
Substitute your ${CURRENTACTIONATTRIBUTEFILE} variable reference with JMeter Property using __P() function as ${__P(CURRENTACTIONATTRIBUTEFILE,)}
Provide the property value via -J command line argument like:
jmeter -JCURRENTACTIONATTRIBUTEFILE="C:/#JMeter/Plans/PRODUCT/61_RISK2VALUE/61_RISK2VALUE - Resources/ModelingData/ActionAttributes/ActionAttributes_AM2.csv"
Another way of setting the property is defining it in user.properties file like:
CURRENTACTIONATTRIBUTEFILE="C:/#JMeter/Plans/PRODUCT/61_RISK2VALUE/61_RISK2VALUE - Resources/ModelingData/ActionAttributes/ActionAttributes_AM2.csv"
References:
Configuring JMeter
Apache JMeter Properties Customization Guide
The CSV Data Set Config element has a field called Filename where you need to specify the file name of your CSV along with its' path.
By default JMeter starts to look for data files in the JMeter root/home folder (\apache-jmeter-x. xx\bin) or the same folder where the JMeter script (.jmx file) resides.
So you can have your CSV files together in the same directory than the .jmx.

Jmeter Script to upload all files in a folder?

I am trying to test an API using Jmeter.
http://localhost:8080/fileupload
This API take a single file as as a parameter and uploads it to my App
Now I have a folder which contains 1000's of such files.
How do I write a script in Jmeter that picks up 1 file from the folder and then sends a request (i.e. 1 request for each file) and this continues for all the files in the folder?
I would suggest using Beanshell Sampler and ForEach Controller combination like:
Add Beanshell Sampler to your Test Plan
Put the following code into "Script" area:
File folder = new File("c:\\somefolder");
File[] files = folder.listFiles(new FileFilter() {
public boolean accept(File file) {
return file.isFile();
}
});
for (int i=0; i < files.length; i++) {
vars.put("file_" + i, files[i].getAbsolutePath());
}
The above code will generate JMeter Variables like:
file_1=C:\somefolder\somefile.txt
file_2=C:\somefolder\someotherfile.jpg
Add ForEach Controller after the Beanshell Sampler and configure it as follows:
Input variable prefix: file
Output variable name: anything meaningful, i.e. currentFile
Check `Add "_" before number
Put the HTTP Request sampler which performs file upload under the ForEach Controller
Put ${currentFile} to "File Path" input
See How to Use BeanShell: JMeter's Favorite Built-in Component guide for comprehensive information on enhancing your JMeter tests with Beanshell
To make JMeter upload all files:
First create a CSV file that contains the file names
Then use a CSV Data Set with 2 columns:
- 1 that will contain the path to files, let's say you name it pathToFile
- 1 that will contain the mime type of the file, let's say you name it mimeType
Then in your HTTP Request , select "Files Upload" Tab and use the variables:
Note you must change:
paramName in the table to match what you have in your form.
path to match your URL suffix
host
port if different from 80 for HTTP and 443 for HTTPS
I think this can be solved by using the solution provided here :
http://artoftesting.com/performanceTesting/fileUploadInJMeter.html
and keeping the file name like:
abc-${counter}.png
where the counter is a counter variable which increments with each request.
Also, files in the folders too are like abc-1.png abc-2.png etc.

How to read the archived JSON file & pass a parameter to the next job?

I could able to fetch an archived file by copy articrafts from another project.
This archived file is in JSON. I need to extract a value from this JSON file and pass this parameter to the next build. I've used python script to do that (Execute Shell), but scope of that variable is not visible outside Execute Shell. Is there any other way, how can i do that ?
One way you could pass the parameter off to the next build is by using the Jenkins API in a Groovy postbuild step.
For example, here is a quick script that will:
Read in an archived json file called "myJsonFile.json" (assuming it lies in the root of the workspace)
Kick off a job called "myDownstreamJob" passing in the value of "myJsonParameter" (found within that "myJsonFile.json" file) for the build parameter named "Param1" in the downstream job.
// Parse the json file
def json = new groovy.json.JsonSlurper().parse(new File(manager.build.artifactsDir.path + "\\myJsonFile.json"))
// Get the target json value
def myValue = json.myJsonParameter
// Kick off downstream job passing in json value as Param1
manager.hudson.getItem("myDownstreamJob").scheduleBuild(5, new hudson.model.Cause.UpstreamCause(manager.build), new hudson.model.ParametersAction([ new hudson.model.StringParameterValue( "Param1", myValue ) ]));

how to write data to csv in jmeter using beanshell scripting

I am new to jmeter,and in my company we are doing webservices testing using jmeter.My requirement is i am using csv data config file for web services testing and here i want to update each row of csv file with test results and i am using beanshell postprocessor,please help
Ex:
csv contains:
Test Case,Dates,Numbers,Results
Total test cases are 16 and i want to update as below for each test case
TC_001,9-03-2016,001,PASS
TC_002,9-03-2016,0002,FAIL
and so one...
Result = "FAIL";
Response = prev.Get....();
If(Response.Contains("Valid"));
Results="PASS";
f = new FileOutputStream("/tmp/oders.csv", true);
p = new PrintStream(f);
this.interpreter.setOut(p);
print(Results + "," + Result);
f.close();
P.Close();
import java.io.File;
import org.apache.jmeter.services.FileServer; //jmeter spelling corrected
import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.Arrays;
import java.io.Writer;
File file = new File("csvFilePath");
FileWriter fstream = new FileWriter(file, true);
// true, will append the file if already exist
BufferedWriter out = new BufferedWriter(fstream);
out.write("Save your data which you want to save");
out.write("Save your data which you want to save");
out.close();
fstream.close();
It might not be the best idea as:
You may have problems with re-using this file
You may run into a situation when 2 or more threads will be concurrently writing to the file and it will result in data loss, file corruption or IO Exception
I would recommend adding your "Test Case", "Dates" and "Numbers" variables to JMeter's .jtl results file instead using Sample Variables property like:
Given you have 3 variables: TestCase, Date and Number
Add the following line to user.properties file (it is located under /bin folder of your JMeter installation)
sample_variables=TestCase,Date,Number
On next JMeter restart you will see "TestCase", "Date" and "Number" variable values appended to .jtl results file.
It is also possible to pass the setting as a command-line parameter like:
jmeter -Jsample_variables=TestCase,Date,Number -n -t /path/to/testplan.jmx -l /path/to/results.jtl
References:
Sample Variables
Apache JMeter Properties Customization Guide
I would like to share my experience using BeanShell PostProcessor to write variables to a file.
I captured few responses from the server using "Regular Expression Extractor" and saved it to few variables Var1 & Var2 and when I wrote these variables to a file using "BeanShell PostProcessor", I have observed that it works fine when we run a test with single thread but with multi thread test, the data was being lost.
Say When I inject 100 transactions, I was able to see only 97 records in the output file.
So the best option is to set sample_variables in user.properties file so that you can get the variables out in your .jtl results file.

Resources