JMeter Regular Expression Extractor - jmeter

I made a test with JMeter and I made a regex which takes a ticketid from a response. That works when loop count = 1. But when loop count = 2, in next loop we have a new ticketid, but regex don't takes it and test fails. How make a regex which in every next loop takes a new ticketid that appears?

You will have to write java code using Beanshell Sampler to save extracted data to CSV file
Extract your data using Regex Extractor
See the sample code below to write your data to CSV file
import java.io.FileWriter;
import java.io.IOException;
String ID = vars.get("ticketid");
//Change the file path below
FileWriter writer = new FileWriter("F:\test_20140529.csv", true);
if (ID != "")
{
writer.append(ID);
writer.append('\n');
writer.flush();
}
writer.close();`
Use CSV Data Set Config, use "test_20140526.csv" created.
pass CSV data as parameters for the next request.
Hope this will help.

Related

Iterating over each row and accessing every column in HTTP Sampler in JMeter

I have explored and tried solution mentioned on Google or StackOverflow but could not solve my problem.
I am trying to iterate over each row of CSV and use every column of a row in "HTTP Sampler"
This is what I have tried till now.
My Test plan structure
This is my CSV file
This is my CSV Data Set Config
I am reading entire CSV and storing values in JMeter properties variable using Bean Shell Sampler.
This is the code in Bean Shell Sampler
import java.text.*;
import java.io.*;
String filename = "load_test_date.csv";
ArrayList strList = new ArrayList();
try{
log.info("starting bean shell");
File file = new File(filename);
if(!file.exists()){
throw new Exception ("ERROR: file " + filename + " not found");
}
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
String line = null;
log.info("while loop starting");
headerLine = br.readLine();
while((line = br.readLine())!=null){
log.info(line);
String[] variables = line.split(",");
props.put("header_1",variables[0]);
props.put("header_2",variables[1]);
props.put("header_3",variables[2]);
props.put("header_4",variables[3]);
props.put("header_5",variables[4]);
}
}catch(Exception ex){
log.error(ex.getMessage());
}
Now I want to iterate over props variable and fetch each column. I tried using While controller and ForEach Controller, but it is not giving me desired output.
while controller
While loop is executing twice (instead of three times for three rows in csv file) and always using last row values
I used ForEach controller too but could not produce desired outcome
First of all, forget about Beanshell, since JMeter 3.1 you should be using JSR223 Test Elements and Groovy language for scripting.
Second, if I correctly got your point and you want to iterate all the values, i.e. from 1 to 15, you need different approach, for example read the whole file into memory, split each line by comma and create a JMeter Variable for each "cell" value, example Groovy code would be something like:
SampleResult.setIgnore()
def lines = new File('load_test_date.csv').readLines()
def counter = 1
1.upto(lines.size() - 1, { index ->
def line = lines.get(index)
line.split(',').each { column ->
vars.put('value_' + counter, column)
counter++
}
})
if you execute the script and look into Debug Sampler output you will see the following JMeter Variables
In order to iterate the generated variables you can use ForEach Controller configured like:
And use ${value} in the HTTP Request sampler to access the next "cell" value on each iteration:

JMeter Array of variables to text file

I am running a query via JDBC request and I am able to get the data and place it in a variable array. The problem is I want the values of the variables to be saved to a text file. However, each variable is being given a unique number appended to it i.e. SCORED_1, SCORED_2,SCORED_3 etc. I am using a beanshell post processor to write to the text file. The problem is I unless I define A LINE Number. How can I get all results from a SQL query and dump them into a single variable without the variables separated by brackets and line separated on their own row.
import org.apache.jmeter.services.FileServer;
// get variables from regular expression extractor
ClaimId = vars.get("SCORED _9"); // I want to just use the
SCORED variable to contain all values from the array
without "{[" characters.
// pass true if want to append to existing file
// if want to overwrite, then don't pass the second
argument
FileWriter fstream = new FileWriter("C:/JMeter/apache-
jmeter-4.0/bin/FBCS_Verify_Final/Comp.txt", true);
BufferedWriter out = new BufferedWriter(fstream);
out.write(ClaimId);
out.write(System.getProperty("line.separator"));
out.close();
fstream.close();
We are not telepathic enough to come up with the solution without seeing your query output and the result file format.
However I'm under impression that you're going into wrong direction. Given you're talking about {[ characters it appears that you're using Result Variable Name field
which returns an ArrayList which should be treated differently
However if you switch to Variable Names field
JMeter will generate a separate variable per each result set row and it should be much easier to work with and eventually concatenate
More information:
JDBC Request
Debugging JDBC Sampler Results in JMeter
JDBC request>Enter a Variable Name> Store as string>Add a Beanshell PostProcessor and add the following script.
import org.apache.jmeter.services.FileServer;
{
FileWriter fstream = new FileWriter("C:/JMeter/apache-jmeter-4.0/bin/FBCS_Verify_Final/Comp.txt", false);
BufferedWriter out = new BufferedWriter(fstream);
Count = vars.get("SCORED_#");
Counter=Integer.parseInt(vars.get("SCORED_#"));
for (int i=1;i<=Counter;i++)
{
ClaimId = vars.get("SCORED_"+i);
out.write(ClaimId);
out.write(System.getProperty("line.separator"));
}
out.flush();
out.close();
fstream.close();
}

Exclude blank values from csv file for JSON array in Jmeter

I have jsonarray as [foodid1,foodid2,foodid3] .The values of these are reading from a csv file
csv file content
foodid1,foodid2,foodid3
10,12,14
if I don't want to pass the value to foodid2, the JSON array is being passed as [10,,14]
Instead, I wanted it to be passed as [10,14].
following is the JSON body:
customerdetails={
"regDate":${regDate},
"regNo":"${regNo}",
"firstName":"${fname}",
"lastName":"${lname}",
"dateOfBirth":"${dob}",
"bloodGroupId":0,
"mobileNo":"${mobile}",
"residenceNo":"${resdno}",
"officeNo":"${officeno}",
"email":"${email}",
"address1":"${adr1}",
"address2":"${adr2}",
"pincode":"${pin}",
"stateId":${stateid},
"city":"${city}"}
&customerhistory={
"historyId":[${food1},${food2},${food3},${food4}]}
how can I handle this situation in Jmeter
Thanks in Advance
The easiest solution would be replacing double commas with single commas on the fly using Beanshell PreProcessor
Add Beanshell PreProcessor as a child of the HTTP Request you're going to modify
Put the following code into the PreProcessor's "Script" area:
import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.config.Argument;
import org.apache.jmeter.protocol.http.util.HTTPArgument;
Arguments oldArgs = sampler.getArguments();
Arguments newArgs = new Arguments();
for (int i = 0; i < oldArgs.getArgumentCount(); i++) {
Argument argument = oldArgs.getArgument(i);
String oldValue = argument.getValue();
String newValue = oldValue.replaceAll(",,", ",");
newArgs.addArgument(new HTTPArgument(argument.getName(), newValue));
}
sampler.setArguments(newArgs);
When you will run your test the PreProcessor will replace ,, with , for each parameter value.
See How to Use BeanShell: JMeter's Favorite Built-in Component article for more information about using Beanshell in JMeter tests.

Problems using CSV Data Set Config and EOF condition

I have a CSv Data Set Config which I am using in a while loop. I have this in a module and use this same module several times in my test.
My first problem is that I have set the while loop with this condition:
${__javaScript("${data}"!="<EOF>")}
The "data" being the first column in my csv file. This works fine except for the last iteration where ${data} gets set to "EOF" and has all the tests performed on it. I want it to stop before this, not after all the tests have ran once on it.
My other problem is that when I use this module again later, ${data} is still set to "EOF" and no tests are run at all.
To avoid this <EOF> bit just put your logic under the If Controller and use "${data}" != "<EOF>" as the "Condition"
See Using the While Controller in JMeter guide for detailed explanation of this and other common use cases.
UPD. Reusing the same CSV file:
Add a Beanshell Sampler after 1st While Controller and before the 2nd While Controller and use the following code in "Script" area:
import org.apache.jmeter.services.FileServer;
FileServer.getFileServer().closeFile("yourfile.csv");
vars.put("data", "");
The above script will "close" the original CSV file so it could be reused later on in the script and "clear" ${data} variable as it contains <EOF> value.
See How to Use BeanShell: JMeter's Favorite Built-in Component guide for details on using Beanshell scripts in JMeter tests.
If you would use Loop Controller, with number of CSV lines being number of iterations you could avoid that. Just put this code into Beanshell Sampler:
import org.apache.commons.io.FileUtils;
int lines = FileUtils.readLines(new File("/home/username/csv.file")).size();
vars.put("linesCount", String.valueOf(lines));
After that you can use lineCount in the Loop Controller.
If your data variable needs to be reverted to original state, you could store default value in other variable, and at the end of Loop revert data to it using Beanshell pre/post proccesor.
EDIT:
Or you could insert If Controller in your While Controller and process all child elements only if data doesn't equals EOF:
${__javaScript("${data}"!="<EOF>")}
Neither of the previous suggestions to go and re-use a csv file had worked for me. I ended up doing something different. It's way more complicated than I like, but it works.
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):
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.
Thread Group
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.
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("<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()));
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.
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]);
Http request sampler
Here's the HTTP request that's using the data extracted.
result
When running this, as desired, I end up sending 6 http requests over to the endpoint I defined.

Extracting a value from jmeter response and exporting it to a csv file

I need to know how can I extract a value from response in jmeter and export it to a csv file.
Suppose my response is like this:
<ns3:UpdateConsumerResponse
xmlns:ns3="http://Pandora.NextGenCRM.Integrations.UpdateConsumerResponse"
xmlns:ns0="http://tempuri.org/"
xmlns:ns1="http://schemas.datacontract.org/2004/07/Pandora.Xrm.DataModel.Request"
xmlns:ns2="http://schemas.datacontract.org/2004/07/Pandora.Xrm.DataModel.Response">
<MasterConsumerID>
CRM-CONID-000000519344
</MasterConsumerID>
</ns3:UpdateConsumerResponse>
I need to extract the master consumer value and export it to an csv file.
First of all you have to add an regular expression extractor as a child of this request
and then mention below inputs
1.Reference Name: MasterConsumer (or any variable)
2.Regular expression: abc(.*?)d (suppose your value is like abcCRM-CONID-000000519344d
then provided reg ex will work, now replace abc with your left
boundary and d with right boundary which you can get from your response. if still you need more help then
please provide this value along with more text from both side )
3.Template: $1$
4.Match No:1
5.Default Value: null
now you have your value stored in MasterConsumer variable (apply debug sampler to verify). Just you need to write into csv file, so add beanshell post processor as a child of same request and write below code for printing data into csv file
MasterConsumer =vars.get("MasterConsumer");
f = new FileOutputStream("Path"-Output.csv",true);
p=new PrintStream(f);
this.interpreter.setOut(p);
p.println(MasterConsumer);
f.close();
Add XPath Extractor as a child of the request, which returns above value
Configure it as follows:
Check Use Namespaces box
Reference Name: anything meaningful, i.e. ID
XPath query: /ns3:UpdateConsumerResponse/MasterConsumerID/text()
Add Beanshell PostProcessor after the XPath Extractor
Add the following code into the PostProcessor's "Script" area:
import org.apache.commons.io.FileUtils;
String file = "path_to_your_file.csv";
String ID = vars.get("ID");
String newline = System.getProperty("line.separator");
FileUtils.writeStringToFile(new File(file),ID + newline, true);

Resources