JMeter- Sending one email for multiple http responses - jmeter

I am using csv for http requests and sending emails in case of failure. Can I send only one email at the end of http requests from csv file. Like if 10 http request failed then I want to send a single email containing urls of all pages for which response was 404 or a failure response returned by server. Image Attached

Add JSR223 Listener to the main Thread Group
Put the following code into "Script" area:
if (!prev.isSuccessful()) {
StringBuilder builder = new StringBuilder()
def failures = props.get("failures")
if (failures != null) {
builder.append(failures)
}
builder.append(prev.getUrlAsString())
builder.append(System.getProperty("line.separator"))
props.put("failures", builder.toString());
}
Add tearDown Thread Group with 1 virtual user and 1 loop to your Test Plan
Add If Controller to this tearDown Thread Group
Use ${__groovy(props.get("failures") != null,)} as the If Controller's condition
Put your SMTP Sampler as a child of the if controller
Use ${__P(failures,)} in the mail body - it will hold failed samplers URLs.
Assuming above configuration JMeter will send only one email with the list of all failed samplers URLs and only if any sampler has failed. Feel free to amend the code as required.
References:
__P() function
__groovy() function
Groovy is the New Black

I made it simple and moved SMTP Sample under tearDown ThreadGroup and attached Aggregate Report with Email which contains all information which I want to send in email.
Also In Aggregate Report I selected option that show only Errors which made this report more concise.
Thanks for Answers. #Dmitri T
If anyone having issue feel free to consult.

Related

Jmeter result configuration to use grafana

I have a transaction controller and in that 5 requests are there. Now when i run a load test and in my script "Generate parent sampler" is checked. So here what is happening is whenever a failure occurs in any of the requests within this sampler, the transaction controller shows a message like "None" or "Number of sampler" etc.
I am using Grafana to monitor my test results, so how can i show the failed response message of a failed request to a transaction controller first and then show the message in grafana
JMeter's Backend Listener doesn't send response message to Grafana, you can see the possible values in the Metrics Exposed chapter.
The only way to send the response message to Grafana is changing Transaction Controller label using JSR223 Test Elements and Groovy language.
Example code for the JSR223 Sampler:
SampleResult.setIgnore()
def failure = prev.getParent().getSubResults().find { subResullt -> !subResullt.isSuccessful() }
if (failure != null) {
failure.getParent().setSampleLabel(failure.getParent().getSampleLabel() + ': ' + failure.getResponseMessage())
}
Demo:

How to run the request based on previous request response data

I have test plan with following request in sequence with 2 loops.
ApiHttp request
Mqtt request
I need to run 1st loop & verify API reaponse is true or false:
If it's true, run Mqtt request , else start the 2nd loop and same verify the API response, if it's true run Mqtt else stop.
In above scenarios, I put beanshell to read the API response:
vars.put("response", new String(data));
But don't know how to verify of its true or false & execute the Mqtt. Any help pls.
Add If Controller as the very first test element under the Thread Group and use the __groovy() function as the condition:
${__groovy(vars.getIteration() <= 2,)}
Put ApiHttp request as a child of the If Controller
Add another If Controller after the ApiHttp request and use the following __groovy() function as the condition:
${__groovy(ctx.getPreviousResult().getResponseDataAsString().contains('true'))}
Add Mqtt request as a child of the If Controller
Add Flow Control Action sampler after the Mqtt request and configure it like:
First switch from Beanshell to JSR223 Test elements and use Groovy.
Use If Controller and just put in it:
${response}
To stop the test based on iteration number, be aware that a Loop Controller exposes iteration as a variable based on name of variable, for example if your LoopController is named LC, then you can access iteration as:
vars["__jm__LC__idx"].toInteger()
And to stop a test from Groovy using JSR223 Assertion you can throw:
throw new org.apache.jorphan.util.JMeterStopTestException();
See:
https://jmeter.apache.org/api/org/apache/jorphan/util/JMeterStopTestException.html

How to loop a sampler in a thread group in Jmeter until a specific response value is returned

I have to performance test an application which does a PDF to PNG image conversion. For that, I have 3 requests to be sent, ie, 1 POST and 2 GET requests. My requirement is to measure the performance of one the GET request which does the conversion part and downloads the converted PNG file. Note that this GET request that download the image is dependent on the other POST and the GET request which checks the status of the job. The full work flow in a nutshell is as follows:
Send a POST request to trigger a job to generate a unique identifier string.
Using the string value generated in step 1 above, the GET request checks the status of creation of a PDF document. Since this process has dependencies, the GET request polls until a status of 'Complete' is returned in its response. If the response status is not 'Complete', then we have to retry this GET request.
And finally, once the response from step 2 is returned as 'Complete', the GET request to convert the generated PDF to PNG image has to be triggered.
So 3 requests above are dependent to each other and has to run sequentially as the input for one is the output of the previous request. So we have to run this in the same order (1__> 2 --> 3) for the entire duration of the performance test.
I have tried using the While controller, however, the issue I am facing is, the sampler inside the While controller (ie GET request in step 2 which checks the status) is getting executed only for a limited number of times and not for the entire test duration.
The jmx file I have created is as follows:
Test Plan{
Thread Group{
POST Request sampler{ //step 1
//stores unique string response to variable
}
User Defined variable (initialize a Status variable to null string, initialize a counter variable)
While Controller(condition '${__javaScript("${Status}" == "" && (${counter} < 4),)}')
{
GET Request Sampler { //step 2
Regular expression extractor to get the status from response and store to variable
}
JSR223 Post processor { //to check if the status value = 'Complete', otherwise set status back to null string
/*
String status = vars.get("labelStatus")
if(status.equals("Complete")){
log.info("Label Status is Complete");
}
else{
vars.put("labelStatus","")
}
*/
}//end of JSR223 post processor
}//end of while loop
GET Request sampler to download the PNG image //step 3
} // end of Thread Group
}//end of Test Plan
screenshot of my Jmeter script:
Ideally for each POST request I make (step 1), there should be a corresponding GET request (step 2) which checks for a particular status in response. If the response contains the matching text, then have to exit the while loop and continue with the next sampler (ie GET request in step 3 above) in the thread group. This needs to be repeated in each iteration.
As per your While Controller condition its children will be executed while ${Status} variable is empty or 4 times, whatever comes the first.
I fail to see where do you update the value of the ${Status} variable, it might be the case you made a typo and need to change it to ${labelStatus}?
I would recommend using Debug Sampler and View Results Tree listener combination in order to check the values of ${labelStatus} and ${counter} variables for each While Controller's iteration
Also pay attention to JMeter Scoping Rules as your last JSR223 PostProcessor is being executed after every sampler in the Thread Group and this is something you might want to change.

jMeter - Re-use response data in follow-up requests

We have a service that works the following way:
First, a request with search parameters is sent, for which we get back a searchId. This searchId is then used to continue fetching information until service response it has no more data left (hasMore parameter becomes "false").
The question is this - I have set up jMeter to send first requests, but not certain how then to keep sending requests in parallel for each response in the Thread Group, and need your advice on it. My thought was to set up another Thread Group since I cannot set it inside the first one, but then how do I get access to responses and process them in parallel?
EDITED:
This is what I ended up with. First Beanshell Sampler extracts searchId and hasMore and puts it into vars. Second Sampler extracts hasMore and again puts it into vars, overwriting the first. At the end, the While loop worked as intended, using ${__javaScript("${hasMore}" == "1",)}.
I would recommend designing your test as follows:
Request to get searchId
While Controller with condition like ${__javaScript("${hasMore}" != "false",)}
Request to continue to fetch information
PostProcessor to extract hasMore parameter and store it into the relevant JMeter Variable
This way "fetch information" requests will be executing until hasMore parameter becomes false. See Using the While Controller in JMeter article for more details.
I suggest 2 Thread group
First Thread group:
Save searchIds in file (JSR223 Sampler) or database (JDBC Sampler) with key as counter (1,2,...) and value as the searchId value
Save a number of IDs in property ${__setProperty(threadCount,${counter})}.
Second Thread group:
In definition - Number of thread use ${__P(threadCount)}
Read from file (JSR223 Sampler) or database (JDBC Sampler)
using ${__threadNum} as key get the relevant searchId you need

How do I resend a sampler upon a failed assertion on JMeter?

I am designing a load test in JMeter.
With the current application that we have whenever a HTTP request is sent, the web server will very occasionally send back a page with a message. To get around this we just have to reload the page. This page could come up for literally any HTTP request.
Is there any way to design a test in JMeter where when a sampler fails, the sampler simply retries?
I'm not sure how I can get a Beanshell sampler to resend a HTTP request.
It is possible via additional Beanshell Assertion
You can re-run arbitrary sampler from the Beanshell Assertion as simple as
ctx.getCurrentSampler().sample(null);
Add a Beanshell Assertion after all other assertions. It matters as assertions are being executed upside-down.
Put the following code into Beanshell Assertion's "Script" area (just change "message" to what your server returns on error.
import org.apache.jmeter.samplers.SampleResult;
if (new String(ResponseData).equals("message")) {
SampleResult result = ctx.getCurrentSampler().sample(null);
if (result.getResponseDataAsString().equals("message")) {
Failure = true;
} else {
SampleResult.setSuccessful(true);
}
}
You'll have only one result recorded.
If assertion passes 1st time - it'll be successful
If assertion fails 1st time and passes 2nd time - it'll be successful
If assertion fails 2 times - it'll be recorded as failed.
For extended information on Beanshell scripting check out How to use BeanShell: JMeter's favorite built-in component guide.
Create such hierarchy:
Thread Group (1 user, 1 second ramp-up, forever)
-While Controller (empty condition = forever)
--Counter (start – 1, increment – 1, reference name – counter)
--HTTP request
---Timer (I prefer constant Timer, responseble for pause betwee retrying)
---BeanShell Post Processor
BeanShell Post Processor should contains(pseudo code):
if(Integer.parseInt(vars.get("counter")>5)
{
prev.setSuccessful(false);
prev.setStopTestNow(true);
}
if(successCondition)
{
prev.setStopTest(true);
}
There is no direct way to achieve it, but I think you can use While controller in conjuction with Regex extractor to resend the failed requests.
Logical flow could be,
1. HTTP request
2. Regex extractor post processor - check response contains failure extract value in msg variable, default is success
3. While controller - run till msg=failure, default value of msg is success
Example screenshot,
Let me know if this works.

Resources