Create a Java Request in jMeter for validating multiple variables - java

Here in My HTTP Request I extracted some variables using JSON Path Extractor. I want to create a Java Request it will validate the above variables. i.e I want to check the value of reqVar1 is equal to resVar1 or not and reqVar2 is equal to resVar2 or not like that.

You are making things over complicated, you could achieve the same using normal Response Assertion.
For example, if you have a JMeter Variable ${var1} and you need to compare it to ${var2}, ${var3} and ${var4} you can just configure the Response Assertion like:
More information on conditionally marking sampler results as successful or failed: How to Use JMeter Assertions in Three Easy Steps

Instead of Java Request sampler, you can add BeanShell Assertion to compare the values. following is the code:
if(vars.get("reqVar1").equals(vars.get("resVar1")))
{
if(vars.get("reqVar2").equals(vars.get("resVar2")))
{
SampleResult.setResponseCode("200");
SampleResult.setResponseMessage("SUCESS");
}
else{
SampleResult.setResponseCode("403"); // keep error code as per your wish
SampleResult.setResponseMessage("reqVar2 and reqVar2 are NOT same" + vars.get("reqVar2") + vars.get("resVar2"));
}
}
else{
SampleResult.setResponseCode("403"); // keep error code as per your wish
SampleResult.setResponseMessage("reqVar1 and reqVar1 are NOT same" + vars.get("reqVar1") + vars.get("resVar1"));
}
Add the BeanShell Assertion as a child element to the HTTP Sampler in which you are getting the values for reqVar1, reqVar2, resVar1, resVar2
Once the decision is taken based on If condition, you can change the response code and message using SampleResult
Check the following reference that shows all methods available to you:
https://jmeter.apache.org/api/org/apache/jmeter/samplers/SampleResult.html
Image reference:

Related

Sample result's label is not changed through BeanShell post processor for some conditions

I made this code so that if status == 500 the name of the api would be equal to "FAKE_CLIENT_RETRY", if the status of the api == "ERROR", the name would be equal to "FAKE_CLIENT_CALLBACK_ERROR"
import org.apache.jmeter.samplers.SampleResult;
//process main sample
if(("${status}").equals("500")) {
SampleResult.setResponseCodeOK();
SampleResult.setSuccessful(true);
vars.put("Api_Fake_Client_Name","FAKE_CLIENT_RETRY");
}else if(("${status}").equals("ERROR")){
SampleResult.setSuccessful(false);
vars.put("Api_Fake_Client_Name","FAKE_CLIENT_CALLBACK_ERROR");
}else{
vars.put("Api_Fake_Client_Name","FAKE_CLIENT_CALLBACK_SUCESS");
}
But even when status == "ERROR" the name it returns is "FAKE_CLIENT_RETRY"
The strangest thing is that I know that the execution entered the "if" of the condition == "ERROR", because the return that comes with status == "ERROR" appears with execution failure in Jmeter and I forced the return in this case to return with fails via code snippet:
SampleResult.setSuccessful (false);
But despite having entered, it ignores the snippet that asks to rename the api.
Jmeter Sreenshot ----> Jmeter response
You're setting an Api_Fake_Client_Name variable value in the Assertion, it will be available (updated) either in the next sampler of during the next iteration of the current sampler:
Also be aware that starting from JMeter 3.1 you're supposed to be using JSR223 Test Elements and Groovy language for scripting so you could change your code to something like:
switch (vars.get('status')) {
case '500':
prev.setResponseCodeOK()
prev.setSuccessful(true)
vars.put('Api_Fake_Client_Name', 'FAKE_CLIENT_RETRY');
prev.setSampleLabel('FAKE_CLIENT_RETRY')
break;
case 'ERROR':
prev.setSuccessful(false)
vars.put('Api_Fake_Client_Name', 'FAKE_CLIENT_CALLBACK_ERROR')
prev.setSampleLabel('FAKE_CLIENT_CALLBACK_ERROR')
break;
default:
vars.put('Api_Fake_Client_Name', 'FAKE_CLIENT_CALLBACK_SUCESS')
prev.setSampleLabel('FAKE_CLIENT_CALLBACK_SUCESS')
}
More information:
JMeter Test Elements Execution Order
Scripting JMeter Assertions in Groovy - A Tutorial
Following script worked without any issue within BeanShell Post Processor
if(("${status}").equals("500")) {
prev.setResponseCodeOK();
prev.setSuccessful(true);
prev.setSampleLabel("FAKE_CLIENT_RETRY");
vars.put("Api_Fake_Client_Name","FAKE_CLIENT_RETRY");
}else if(("${status}").equals("ERROR")){
prev.setSuccessful(false);
prev.setSampleLabel("FAKE_CLIENT_CALLBACK_ERROR");
vars.put("Api_Fake_Client_Name","FAKE_CLIENT_CALLBACK_ERROR");
}else{
prev.setSampleLabel("FAKE_CLIENT_CALLBACK_SUCESS");
vars.put("Api_Fake_Client_Name","FAKE_CLIENT_CALLBACK_SUCESS");
}
Please note that you have access to the SampleResult through the variable previous. Lets use prev.setSampleLabel("Label"); to set the label of the sample result.
prev - (SampleResult) - gives access to the previous SampleResult
Migration to JSR223 PostProcessor+Groovy is highly recommended for performance, support of new Java features and limited maintenance of the BeanShell library
Add a Debug Post Processor to view the JMeter variables through view result tree.
Sample test plan (JMX) is available in GitHub.

is it possible to delete only one of the returns from the Jmeter result tree? Type specify?

I know it is possible to delete the entire Jmeter result tree, through the code:
import org.apache.jmeter.gui.GuiPackage;
import org.apache.jmeter.gui.JMeterGUIComponent;
import org.apache.jmeter.gui.tree.JMeterTreeNode;
import org.apache.jmeter.samplers.Clearable;
log.info("Clearing All ...");
guiPackage = GuiPackage.getInstance();
guiPackage.getMainFrame().clearData();
for (JMeterTreeNode node : guiPackage.getTreeModel().getNodesOfType(Clearable.class)) {
JMeterGUIComponent guiComp = guiPackage.getGui(node.getTestElement());
if (guiComp instanceof Clearable){
Clearable item = (Clearable) guiComp;
try {
item.clearData();
} catch (Exception ex) {
log.error("Can't clear: "+node+" "+guiComp, ex);
}
}
}
but I didn't want to delete the entire result tree, only the returns that returned with status == 500. Because my api returns 500 until the callback is available for consultation, when it finds the callback it returns "success", so while the api keeps retrying, these retries show up as an error in the report,but in fact the callback has not returned yet, when it returns the api returns the callback and is successful. I would like to remove these requests from the report, which are retry.
Add a JSR223 Post Processor with following code to ignore the test results when the response code is 500
if (prev.getResponseCode()=="500"){
prev.setIgnore()
}
prev - (SampleResult) - gives access to the previous SampleResult (if any)
API documentation for prev variable (SampleResult)
I don't think it's possible without modifying JMeter source code or heavily using reflection. In any case the answer will not fit here.
In general:
You should be using JMeter GUI only for tests development and debugging, when it comes to test execution you should run your test in command-line non-GUI mode
You should not be using listeners during test execution as they don't add any value, just consume valuable resources, all the necessary information is stored in .jtl results file
There is Filter Results plugin which allows removing the "unwanted" data from the .jtl results file
You can also (as well) generate the HTML Reporting Dashboard out of the .jtl results file, the Dashboard has its own responses filtering facilities
guys. First, thanks for the answers, I ended up giving up on the idea of ​​removing the result from the tree and looking for a way to modify the way that result is presented.
I made a beanShell assertion, so that if Status==500, it would return "Success" in the result tree:
BeanShell
I also made it so that if it were a new attempt the name displayed in the results tree would indicate this, leaving the api name mutable depending on the return:
api name = variable
and I have this logic:
import org.apache.jmeter.samplers.SampleResult;
//process main sample
if (${status} == 500) {
SampleResult.setResponseCodeOK();
SampleResult.setSuccessful(true);
vars.put("Api_Fake_Client_name", "API_FAKE_CLIENT_RETRY");
I will configure the answers in the other conditions, but I believe that this way I will be able to solve my problem because the new attempts no longer appear as an error.

JMeter - Variable set in preprocessor is not available to sampler

I have a relatively simple JMeter test plan setup as shown here:
https://imgur.com/c8BIzBB
The relevant part of this is the BeanShell Preprocessor (shown as Setup element data) and its relationship to the HTTP Request sampler (shown as POST /elements). Both of these are inside a Loop Controller (shown as Do a few times).
The Preprocessor gets an array of data stored on the bsh.shared object and randomly selects one item. It then sets a variable called elementTypeId.
When I run this test, elementTypeId gets logged (and I therefore assume is set) correctly. However, the first time around, the variable is not set correctly and still appears as ${elementTypeId}. Further samples appear to be set but use the n-1th value.
The first, failing sample is shown here: https://imgur.com/Gj2YAje
The final sample (and logged values) are shown here: https://imgur.com/OW5HSsS
Setup element data - BeanShell Preprocessor code:
import java.util.Random;
import com.eclipsesource.json.*;
Random rand = new Random();
int idx = rand.nextInt(bsh.shared.elementTypes.size());
JsonValue elementType = bsh.shared.elementTypes.get(idx);
String elementTypeId = String.valueOf(elementType.get("id").asInt());
log.info(elementTypeId);
vars.put("elementTypeId", elementTypeId);
It looks to me as if the sampler is firing before the preprocessor has set the variable - which seems counter to what should be happening.
Update following UBIK's answer
When I disable the SetQueryParams PreProcessor, it appears that the variable is set correctly (although the request fails as it needs a query parameter to be added).
SetQueryParams PreProcessor:
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase;
if (sampler instanceof HTTPSamplerBase &&
sampler.getMethod().equalsIgnoreCase("post")) {
// add query parameter to url
var customPath = sampler.getPath() + '?' + sampler.getQueryString();
sampler.setPath(customPath);
// remove query parameter from body
arguments = sampler.getArguments();
while (arguments.getArgumentCount() > 1) {
arguments.removeArgument(arguments.getArgumentCount() - 1);
}
sampler.setArguments(arguments);
}
Is it possible to have both preprocessors applied to the POST request?
I think you issue might be coming from the other PreProcessor :
SetQueryParams PreProcessor
As per scoping rules , this one runs for every HTTP Sampler.
Check in console for the exception thrown.
try resolving that
if nothing is working please copy your script, delete Beanshell preprocessor and add BeanShell again and paste your script.
This may be silly but it worked for me.

Webservice Exception Javascript DWR

I'm trying to unravel a Webservice work and replicating it's call, but I've been unable to do it.
In this website, if you input, for example, HY6210 a new window appears with data already filled in.
Using Firebug I was able to determine it was calling
this link,
but no matter what I do in terms of parameters, headers, and cookies, I always get either:
throw 'allowScriptTagRemoting is false.';
//#DWR-REPLY
if (window.dwr) dwr.engine._remoteHandleBatchException({ name:'java.lang.SecurityException', message:'Call IDs may only contain Java Identifiers' });
else if (window.parent.dwr) window.parent.dwr.engine._remoteHandleBatchException({ name:'java.lang.SecurityException', message:'Call IDs may only contain Java Identifiers' });
or
throw 'allowScriptTagRemoting is false.';
//#DWR-REPLY
if (window.dwr) dwr.engine._remoteHandleBatchException({name:'org.directwebremoting.extend.ServerException', message:'The specified call count is not a number' });
else if (window.parent.dwr) window.parent.dwr.engine._remoteHandleBatchException({ name:'org.directwebremoting.extend.ServerException', message:'The specified call count is not a number' });
Any ideas on what I'm doing wrong?
Suppose, historyTracking is the class name and getStoppageV3 method then you pass device1 variable in JavaScript and then you forcefully convert this variabal in string then you use device1.toString().
Example:
historyTracking.getStoppageV3(device1.toString()

Variable Path Param for REST service testing in Jmeter

I'm testing RESt service which has path parameter.
/my-service/v1/Customer/order/{ordernumber}
I want to increment the number by 1 for each request. How to achieve this in Jmeter? Till now i had been passing a fixed path param, therefor our test result were on only one input parameter.
/my-service/v1/Customer/order/5247710017785924
The good point to start with is putting your initial order value into User Defined Variable
Given start order as "5247710017785924" you need to create an "ordernumber" variable and set it's value to 5247710017785924.
After each request you can increment variable value by adding BeanShell postprocessor to your HTTP Sampler with following code:
long ordernumber = Long.parseLong(vars.get("ordernumber"));
ordernumber++;
vars.put("ordernumber",String.valueOf(ordernumber));
And set ordernumber in your HTTP Sampler path as
/my-service/v1/Customer/order/${ordernumber}
None of the solutions worked for me. Here is what I did
Define HTTP request as shown below and add path /api/v2/state/find/${id} to the request
Right click on HTTP request --> Preprocessor -> User Parameters ->Add variable -> input id and it's value
Start HTTP request, this should work
Use JMeter Counter component to increment variable.
This question is path parameter related, where the value of the order number is incremented by 1 in each successive request. But I faced a scenario where I got a list of order numbers and I had to make request for those order numbers. So, I am gonna answer this question with respect to that, this solution can be applied in both the scenarios.
What I did is put all the parameter paths in a CSV file, like this -
/my-service/v1/Customer/order/5247710017785924
/my-service/v1/Customer/order/5247710017785976
/my-service/v1/Customer/order/5247710017785984
/my-service/v1/Customer/order/5247710017785991
Then I iterated through the list of paths in the CSHTTPle and made http request to the server. To know how to iterate through the CSV file and make http request in Jmeter, you can check this link:
https://stackoverflow.com/a/47159022/5892553
You can use a JMeter Counter:
right click on your Thread Group (under the Test Plan)
select Add–>Config Element–>Counter
set the Starting value (0), Increment (1), Maximum value, Exported Variable Name ("ordernumber")
Then you can use the exported variable name as path param:
/my-service/v1/Customer/order/${ordernumber}
I used a BeanShell PreProcessor to generate an id
vars.put("id", UUID.randomUUID().toString());
Then used the path Http Request
/api/v1/event/${id}/
BINGO!!!

Categories