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.
Related
I have to upload audio files in the Jmeter script which is stored in my system. E.g. abc.wav is the file store in the system. But in the script the file name format should be "Testinstanceid__itemid__ interactionid.wav". Here "Testinstanceid" is the dynamic value which we can get from correlation of previous response.
But how I can upload the file with this dynamic value during run time and it will upload correctly in the script.
Thanks in advance
You can copy your abc.wav file to the Testinstanceid__itemid__ interactionid.wav file using JSR223 PreProcessor and Groovy script like:
org.apache.commons.io.FileUtils.copyFile(new File('abc.wav'), new File(vars.get('Testinstanceid') + '__itemid__ interactionid.wav'))
once you finish the uploading you can delete the file to free up your drive in JSR223 PostProcessor like:
org.apache.commons.io.FileUtils.deleteQuietly(new File(vars.get('Testinstanceid') + '__itemid__ interactionid.wav'))
where vars stands for JMeterVariables class instance, check out the JavaDoc for all available functions
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
I need to create a JMeter script for a batch process. The process will be to check for the file in a inbound folder and then watch for processed folder in the outbound folder.
Is there a way to watch if a file has been processed and is the outbound folder. The file in the outbound folder will have the same name
You can use JSR223 Sampler (or Pre Processor depends on your needs) which check if file exists, for example in Java language:
a = new File("/var/tmp/myFile.txt").exists();
log.info("file exists "+ a);
Other option is execute all in Linux script called by OS Process Sampler.
You can use JMeter's While Controller like:
Add While Controller to your Test Plan
Put the following expression into "Condition" area:
${__groovy(!new File('/path/to/outbound/folder').list().contains('expected_file_name'),)}
Add Test Action sampler as a child of the While Controller and configure it to sleep for i.e. 500 ms
JMeter will "sleep" until expected file will appear in the outbound folder, once it will be there - JMeter will proceed to execution of sampler(s) below the While Controller.
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.
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();