I want to implement error handling in my script (like textcheck in LR).
Iām able to validate the Text using Response Assertion.
But my question is how to stop the thread if the Response Assertion (text check) fails.
In Thread group, choose Stop Thread under Action to be taken after a sample error. This will stop the test once assertion fails
If you need to limit this behaviour to one request, add a Result Status Action Handler as a child of the request, then set it to Stop Thread
Related
I am using Jmeter for functional Testing, below is a problem that I am facing and need some help/suggestion on how to overcome that.
I have a thread-group that consists of 2 requests, 1st is API call and 2nd is sending message to Active MQ.
Now the flow is that I need to do first the API call (this will wait for response), then send the message to a particular Active MQ queue and then only I will get the response for the API.
But since jmeter does sequential execution of requests, its get stuck at the API call waiting for the reply and never executes the second part.
I worked on the below solution but even that did not help.
1 Use a parallel controller and put both the API and ACtive MQ call under the same.
2 Add a Timer to the Active MQ call, so that it just did after the API call (2 Sec)
But when I checked in details I see that both the requests are sent at the same time and the timer does not come into effect anywhere.
Any way I can handle this scenario?
Please note I will get a response to the API only when I send message to the particular Active MQ Queue, else it will timeout in a minute.
Your Parallel Controller approach will work, however you need to amend the configuration a little bit, something like:
You could put your ActiveMQ Request under a different Thread Group and use Inter-Thread Communication Plugin for synchronization between threads
You can keep the current setup but replace the JMS Sampler with the JSR223 Sampler and send the message to ActiveMQ programmatically:
Textual code representation for your convenicence:
sleep(2000)
def connectionFactory = new org.apache.activemq.ActiveMQConnectionFactory('your activemq URL')
def connection = connectionFactory.createConnection()
connection.start()
def session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE)
def destination = session.createQueue('your queue name')
def producer = session.createProducer(destination)
def message = session.createTextMessage('your message body')
producer.send(message)
connection.close()
For your Problem statement, following design will work.
Use 2 Thread Groups, add API call to first Thread group and Message to Active MQ call to second Thread Group
Add a delay to second Thread Group so that it should not run before first Thread Group
Run Test Plan
Use while controller. It will keep on executing till the desired outcome then the next request will be executed.
Hope this helps.
Update:-
While Loop controller execute its samplers until the condition specified is not set to False. The condition can be any variable or function that eventually evaluates to the string 'false'.
So, you need to specify a variable or function in While Loop, that has value 'true' and becomes 'false' somewhere else in the script. Once it changes to 'false', JMeter will exit the While loop.
For example if you are using a X-Path extractor in your script which have a variable named Status and its value changes from 'Start' to 'Finish' during the execution and you want to execute your script till 'Finish' has not been met, then you can use the expression ${__javaScript("'${imp_Status}'!='finish'",)} in your While loop and it will execute the samplers under While controller till the status = finish is met.
It is sort of polling based on certain condition. In your first API reponse, consider one value to be appear as the condition upon which first api call is successful.
It sounds that you just need to define timeout for HTTP Request,
If you define Response Timeout as 60000 (milliseconds), and it will only wait for a minute and then continue to next request
Connect Timeout Connection Timeout. Number of milliseconds to wait for a connection to open. No
Response Timeout Response Timeout. Number of milliseconds to wait for a response. Note that this applies to each wait for a response. If the server response is sent in several chunks, the overall elapsed time may be longer than the timeout.
I know that I can stop a thread conditionally in JMeter.
In my script I'm sending a requests and then I'm extracting their response json to further process it. There are some rare cases, where the parameter response provides some value that I cannot process in further steps.
I could actually detect this valid response by extracting another parameter. Would it be possible to just restart the thread based on condition, instead of stopping it?
Without scripting, you can add Flow Control Action (was: Test Action )
Choose Target: Current Thread and Action: Start Next Thread Loop
It'll skip "damaged" thread and continue to the next thread
For further researchers:
The easy way to start another iteration of a thread based on condition (i.e extracting some data out of json) is to use a BeanShell Sampler in way like described above.
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.threads.JMeterContext;
import org.apache.jmeter.threads.JMeterContext.TestLogicalAction;
String statVar = vars.get("statusVariable"); //getting some data for condition check (statusVariable is a variable that has been set previously in the Jmeter JSON Extractor)
if(statVar.equals("NOK")){ . //checking the condition
SampleResult.setTestLogicalAction(TestLogicalAction.START_NEXT_ITERATION_OF_THRE
AD); //Starting thread again (it starts the thread from the beginning, so we may compare this to restart effect)
}
Threads: 1000
1. Validate username
2. Validate Password
If controller
3. User Info
4. Settings
5. Payments
etc...
20. Logout
Now if Validate Password is failed then the subsequent run will be not run.. But still thread is counted.. Consider 800 is success and 200 login is failing still it shows Active 1000 Started: 1000.
I dont want the thread which is failed on validate password, How to stop the thread which is failed and instead getting new thread..
In Thread groups, there is setting "Action to be taken after a sampler error"
I have selected Start Next Thread Loop. so that if it fails on Validate login, should start new thread. But It also create new thread, if there is a fail on the if loop block. that is actual application failure.
I wanted stop current thread start new thread on fail of validate username and password call but if it is failed on the if block it should report error not stop and start new thread.
Is it possible? Because thread group controls whole group of test?
You can create new thread in JSR223 component, but use it carefully
ctx.getThreadGroup().addNewThread( 0, ctx.getEngine() )
You can stop in specific case using Test Action using Stop Actions:
The "Stop" action stops the thread or test after completing any samples that are in progress. The "Stop Now" action stops the test without waiting for samples to complete
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.
Let's say I have a Jmeter test which emulate some user login and several more actions. I also have 'start new thread on error' turned on. So in case some user fail - it will just get another user and keep processing the test for specified amount of time.
But I have some periodic calls for authorized user and to emulate them I'll need to use "Inter-Thread Communication" and additional thread group(-s). Basically this works fine in following way - in main thread I do login and fill some FIFO queue with required cookies, and obtain that cookie in another thread group. In that another thread group I do also check one more FIFO queue (that is filled on user logout), and stop that thread if get what I need.
The problem here is when main thread is fail after login. In that case child thread will be executed 'forever', since that periodic call keeps session active.
And the question - is there some possibility in Jmeter to execute some action on thread failure (smth like finally block). Basically I need fill that second FIFO queue either on logout or on thread failure
Add a Beanshell Assertion at the same level as all your requests go. It'll apply to each of the requests and in case of failure you'll be able to do what your need.
Something like:
Thread Group
Login Sampler
Some other Sampler
Some else Sampler
Beanshell Assertion
The example assertion code:
if (!SampleResult.isSuccessful()){
log.info("Test " + SampleResult.getSampleLabel() + " has failed");
// handle the error
}
See How to Use JMeter Assertions in 3 Easy Steps guide for more information on JMeter Assertions.
I also had to logout on sample error which needs something like try-catch-finally. An IF Controller with condition ${JMeterThread.last_sample_ok} and checked Evaluate for all children? as below, satisfied my need in a clean way:
TestPlan
HTTP Cookie Manager
HTTP Request Defaults
ThreadGroup - (continue on error)
HTTP Request - login
IfController - (Evaluate ${JMeterThread.last_sample_ok} for all children)
HTTP Request 1
HTTP Request 2
....
HTTP Request n
HTTP Request - logout (after and outside of IF)