i'm trying to save my variables into a csv file by using BeanShell Postprocessor, Code:
String id = "${userID}";
FileWriter fstream = new FileWriter("JmeterBean.csv",true);
fstream.write(id+"\n");
fstream.close();
Test Plan:
HTTP Request GetUsersById => return all IDs
Json extractor => from my response
{"#class":"com.test.dto.userDTO",
"author":"John",
"id":"89BC331D723F", },
{"#class":"com.test.dto.userDTO",
"author":"Alex",
"id":"FTH7JBDRF567",
}
Name of variale : userID
JSON path expression: $.[?(#.#class=='com.test.dto.userDTO')].id
Match Numbers: -1
BeanShell Postprocessor
But my csv file is always empty and look like that:
Use vars to get variable
String id = vars.get("userID");
vars - (JMeterVariables) - gives read/write access to variables:
vars.get(key);
And prefer using JSR223 PostProcessor over Beanshell PostProcessor
String id = vars.get("userID");
FileWriter fstream = new FileWriter("JmeterBean.csv",true);
fstream.write(id+"\n");
fstream.close();
I did it but i got the same result with null in my csv file:
If the JSON Extractor produces more than 1 match you don't have the userID variable, you will have something like:
userID_1=89BC331D723F
userID_2=FTH7JBDRF567
userID_matchNr=2
so I would recommend double checking which JMeter Variables are produced by the JSON Extractor using Debug Sampler and View Results Tree listener combination.
Since JMeter 3.1 it's recommended to use JSR223 Test Elements and Groovy language for scripting
Assuming all above add JSR223 PostProcessor (make sure it's located after the JSON Extractor) and use the following code:
1.upto(vars.get('userID_matchNr') as int, { number ->
new File('JmeterBean.csv') << vars.get('userID_' + number) << System.getProperty('line.separator')
})
#The below mentioned solution worked for me:
OrderID = vars.get("primaryRefID");
FileWriter fstream = new
FileWriter("C://Users/Documents/JMeter/OrderID.csv",true);
BufferedWriter out = new BufferedWriter(fstream);
out.write("TC-"+OrderID);
out.write(System.getProperty("line.separator"));
out.close();
fstream.close();
Related
I've the below JSON response received from the HTTP request. I want to extract the parameters from the node "url" present in the JSON response.
{"Id":"7S9LyBqyv1e0trKrVuP1OOZGHeg","Url":"https://abcd.com:443/u/custom-response?prov=34545sdf-9013e2e61e66&realmeId=%2Fxxxx","realmeId":"/abcd"}
In the above JSON response, i want to retrieve the value of "prov" which is 34545sdf-9013e2e61e66 using JMeter.
Solution Tried: Used Beanshell to read the response.
String url = vars.get("successURL");
vars.put("responseURL",url.toString());
responseURL = responseURL.replaceAll(":"," ");
log.info("String URL "+responseURL.toString());
Error Message:
attempt to resolve method: toString() on undefined variable or class name: responseURL
I think you need to update this line:
responseURL = responseURL.replaceAll(":"," ");
to something like:
responseURL = vars.get("responseURL").replaceAll(":"," ");
However I don't guarantee that it will work because I don't know how do you get this successURL variable.
What will work is doing everything in one shot using JSR223 PostProcessor and Groovy language which has built-in JSON support, suggested code:
def url = new groovy.json.JsonSlurper().parse(prev.getResponseData()).Url
def params = org.apache.http.client.utils.URLEncodedUtils.parse(new URI(url), 'UTF-8')
params.each { param ->
log.info(param.getName() + '=' + param.getValue())
}
Demo:
More information: Apache Groovy - Why and How You Should Use It
You don't need to use complex Beanshell coding, You can do this easily using - Regular Expression Extractor.
Here the example:-
You can see required value extracted and stored in variable name give in Regular expression extractor:
To understand try out reg-ex, you can use https://regex101.com/
import com.jayway.jsonpath.JsonPath
def idCSV = new File('id.csv')
def index = [fileOne.json, fileTwo.json]
def jsonString
index.each { file ->
jsonString = ________
def ids = JsonPath.read(jsonString, '$..id')
ids.each { id ->
idCSV << id << newLine
}
}
How to fill the jsonString = ____, so that I can json file into string and parse the string to extract ids and some information from the json string.
And I don't to do it in http request-> GET-> file format.
Previously i have extraced jsonString from http response and it worked well now I want to do it this way.
Use JsonSlurper:
def jsonString = new groovy.json.JsonSlurper().parseText(new File("json.txt").text)
My expectation is that you're looking for File.getText() function
jsonString = file.text
I have no full vision why do you need to store the values from JSON in a CSV file, however there is an alternative way of achieving this which doesn't require scripting as your approach will work with 1 concurrent thread only, if you will add more users attempting writing into the same file - you'll run into a race condition :
You can read the files from the folder into JMeter Variables via Directory Listing Config
The file can be read using HTTP Request sampler
The values cane be fetched using JSON Extractor, they will be automatically stored into JMeter Variables so you will able to use them later on
If you need the values to be present in the file (although I wouldn't recommend this approach cause it will cause massive disk IO and potentially can run your test) you can go for the Flexible File Writer
i have a queryCassandra which generate json like this one:
{"results":[{"term":"term1"},{"term":"term2"}..]}
Now, i want to get from this all the term values separated by some separator in string format; ex :
term1,term2,term3
So i can pass this list as a string parameter for a java main program which i've alreat set.
(i only need the transofrmation, not the java program execution)
Thank you !
You can easily get those values by using following ways.
GetFile-->EvaluateJsonPath-->PutFile
In get file you have to specify location of json file.
In EvaluateJsonPath configure like following properties.,
Destination:flowfile-attribute
Return Type:json
input.term1:$.results.[0].term //To get term
input.term2:$.results.[1].term
At the result of Evaluate json you have two attributes in which having those values.
Result attributes:
input.term1: term1
input.term2: term2
Above code works for me,so feel free to upvote/accept as answer.
as a variant use ExecuteScript with groovy lang:
import groovy.json.*
//get input file
def flowFile = session.get()
if(!flowFile)return
//parse json to map/array objects
def content = session.read(flowFile).withStream{ stream-> return new JsonSlurper().parse( stream ) }
//transform
content = content.results.collect{ it.term }.join(',')
//write new content
flowFile = session.write(flowFile,{ stream->
stream << content.getBytes("UTF-8")
} as OutputStreamCallback)
session.transfer(flowFile, REL_SUCCESS)
Given a CSV file with some data arranged in columns instead of rows:
Parameters;Data Set 1;Data Set 2
param_1;A;1
param_2;B;2
param_3;C;3
param_4;D;4
param_5;E;5
Is it possible to use this as a "CSV config element" in JMeter? For sure it won't work with the standard config elements but maybe there is another way?
CSV config element cannot do this. You should use a BeanShell Sampler or JSR223 Sampler to read the file and process each line. Here is a simple Java code for BeanShell sampler:
BufferedReader br = new BufferedReader(new FileReader("filename"));
String line = br.readLine();
while (!line.isEmpty()) {
String parts = line.split(";");
String paramName = parts[0];
String dataSet1 = parts[1];
String dataSet2 = parts[2];
// save them in jmeter props or vars and use later
line = br.readLine();
}
In CSV Data Set Config write the names of the parameters in Variable Names(comma-delimited) with , separation. (like Parameters,DataSet1,DataSet2).
Set the Loop Count for the Thread Group as the number of lines you have to read.
Now you will get the values by accessing the variables ${Parameters}, ${DataSet1}, ${DataSet2}.
Instead of "CSV config element", use "User Parameters" pre-processor, it will work as you expected. But you need to add values manually.
I have a json response in 1 request like this:
{"total":1,"page":1,"records":2,"rows":[{"id":1034,"item_type_val":"Business
Requirement","field_name":"Assigned To","invalid_value":"Jmeter
System","dep_value":"","dep_field":""},{"id":1033,"item_type_val":"Risk","field_name":"Category","invalid_value":"Energy","dep_value":"Logged
User","dep_field":"Assigned To"}]}
and in 2nd request like this:
{"total":1,"page":1,"records":2,"rows":[{"id":1100,"item_type_val":"Business
Requirement","field_name":"Assigned To","invalid_value":"Jmeter
System","dep_value":"","dep_field":""},{"id":1111,"item_type_val":"Risk","field_name":"Category","invalid_value":"Energy","dep_value":"Logged
User","dep_field":"Assigned To"}]}
Both are same but different id's. I need to verify the 1st json response from 2nd json response and compare both that both are same or not. here both are same but having different id's which should be acceptable. how can i do this by regex so i can ignore the id's and match whole content?
Not sure if you can do it with a single regex but other way out is you can create a map of it and then compare everything except 'id'
I believe the easiest way would be just discarding these id entries using JSR223 PostProcessor and Groovy language which comes with JSON support
Add JSR223 PostProcessor as a child of the sampler, which returns your JSON
Put the following code into the JSR223 PostProcessor's "Script" area
import groovy.json.JsonBuilder
import groovy.json.JsonSlurper
def slurper = new JsonSlurper()
def jsonResponse = slurper.parseText(prev.getResponseDataAsString())
jsonResponse.rows.findAll { it.remove("id") }
def newResponse = new JsonBuilder(jsonResponse).toPrettyString()
//depending on what you need
vars.put("responseWithoutId", newResponse) // store response withou ID into a JMeter Variable
prev.setResponseData(new String(newResponse)) // overwrite parent sampler response data
log.info(newResponse) // just print the new value to jmeter.log file
So you have the following choices:
vars.put("responseWithoutId", newResponse) - stores the new JSON (without these id) into a ${responseWithoutId} JMeter Variable
prev.setResponseData(new String(newResponse)) - after this line execution parent sampler data won't contain any "id"
log.info(newResponse) - just prints JSON without "id" to jmeter.log file
I don't know your test plan design, personally I would store responses from 2 requests into 2 different JMeter Variables i.e. ${response1} and ${response2} using above approach and compare them with the Response Assertion like: