JMeter: Resetting Count Value - api

I'm performing basic API testing of CRUD calls to the database. In JMeter, I have 1 thread with 3 thread groups within my test plan where I've set up Loops and Counters within each thread. The reason for Counters is when saving results to a file, I want to append the file's prefix with the counter value.
The issue is the counters never get reset. So for example:
Where Count = 1 for all groups, I would expect:
Thread Group 1, filename_1.json
Thread Group 2, filename_2.json
Thread Group 3, filename_3.xml
Where Group 1 Count = 3, Group 2 Count = 2, Group 3 Count = 1, I would expect:
Thread Group 1, filename_1.json, filename_2.json, filename_3.json
Thread Group 2, filename_4.json and filename_5.json
Thread Group 3, filename_6.xml
Instead, where Count = 1 for all groups I'm getting results like:
Thread Group 1, filename_11.json
Thread Group 2, filename_14.json
Thread Group 3, filename_18.xml
After much searching and trying multiple suggestions, I'm still not getting what I expect. Below is a sample of how the test plan is configured.
Any suggestions are much appreciated.
Thread Group 1
HTTP Header Manager (application/json)
Loop Controller
Counter (Start=1, Increment=1, Maximum=100, Num Format=null, Ref Name=LoopCounter1)
HTTP Request (CREATE)
RegEx (RefName=newRequest, Reg Ex = "id":(.+?)\,"displayName", Template=$1$, Match No.=1, Default=NONE)
BeanShell Assertion (Name=newRequest, Param=${__setProperty(newRequest,${newRequest},)})
Save Response to file (File prefix=requestResult_${LoopCounter}, Var Name=newRequestFile)
Loop Controller
HTTP Request (READ)
HTTP Request (UPDATE)
HTTP Request (DELETE)
Thread Group 2
HTTP Header Manager (application/json)
Loop Controller
Counter (Start=1, Increment=1, Maximum=100, Num Format=null, Ref Name=LoopCounter2)
HTTP Request (CREATE)
RegEx (RefName=newContractId, Reg Ex = "id":(.+?)\,"terminationType", Template=$1$, Match No.=1, Default=NONE)
BeanShell Assertion (Name=newContractId, Param=${__setProperty(newContractId,${newContractId},)})
Save Response to file (File prefix=contractRecords_${LoopCounter2}, Var Name=newContractFile)
Loop Controller
HTTP Request (READ)
HTTP Request (UPDATE)
HTTP Request (DELETE)
Thread Group 3
HTTP Header Manager (application/xml)
Loop Controller
Counter (Start=1, Increment=1, Maximum=100, Num Format=null, Ref Name=LoopCounter3)
HTTP Request (CREATE)
RegEx (RefName=newPricingId, Reg Ex = "id":(.+?)\,"terminationType", Template=$1$, Match No.=1, Default=NONE)
BeanShell Assertion (Name=newPricingId, Param=${__setProperty(newPricingId,${newPricingId},)})
Save Response to file (File prefix=pricingRecords_${LoopCounter3}, Var Name=newPricingFile)
Loop Controller
HTTP Request (READ)
HTTP Request (UPDATE)
HTTP Request (DELETE)
UPDATE
I'm closer to the desired results. With the "Reset counter on each Thread Group" enabled, I would expect Thread Group 2's Count to reset to 0. However, it continues from the previous thread. I need to reset the Counter within each Thread Group. Here's why:
Thread Group 2
HTTP Header Manager (application/json)
Loop Controller
Counter (Start=1, Increment=1, Maximum=100, Num Format=null, Ref Name=LoopCounter2)
HTTP POST Request (CREATE)
${__FileToString(${payloadArchive}/${__eval(contract_${LoopCounter})}.json,,)}
As you can see, I am passing in a different file into the HTTP Request's body with each loop of Thread Group 2. Each .json file contains unique elements based on the unique constraints of the database. The files are named "contract_01.json", "contract_02.json", "contract_03.json", etc. This is why I want Thread Group 2 to restart it's counter.

SOLVED (?)
The following Counter configurations seem to provide the desired results.
Thread Group 1
HTTP Header Manager (application/json)
Loop Controller
Counter
Start=null,
Increment=null,
Maximum=null,
Num Format=null,
Ref Name=LoopCounter1
HTTP POST Request (CREATE)
Thread Group 2
HTTP Header Manager (application/json)
Loop Controller
Counter
Start=1,
Increment=null,
Maximum=null,
Num Format=null,
Ref Name=LoopCounter2
HTTP POST Request (CREATE)
${__FileToString(${payloadArchive}/${__eval(contract_${LoopCounter})}.json,,)}
As you can see, with each loop of Thread Group 2 I am passing in a different file into the HTTP Request's body. (Each file contains unique elements based on the unique constraints of the database.) The files are named "contract_1.json", "contract_2.json", etc. Hence, why I wanted Thread Group 2 to restart its counter.
It is now working and correctly grabbing the correct file contents with each looping. However, I'm not sure why the Start has to be null for Counter 1 and 1 for Counter 2.
If anyone sees a flaw with this, I'd appreciate knowing why and how to correct it. I've only been using JMeter for 1 week with no Java (or any programming) background.

Related

How to update index value of while controller in Thread Group of Jmeter?

I am having a thread group containing HTTP request, JDBC request, If and While controller. Whenever I try to run thread group more than 1 time (using loop controller or by specifying number of times execution required in thread group), then HTTP, JDBC request are executed but while controller is not getting executed.
post using Debug sampler found that index of while controller is not getting changed hence it is not getting executed post 1st time.
While Controller finishes its execution when (if) its "Condition" becomes false
When you enter 2nd iteration of the Thread Group the "Condition" is still false so threads (virtual users) don't enter the While Controller
You need to reset the variable(s) used in the While Controller so the "Condition" of the While Controller becomes true again somewhere in the end of the 1st iteration, it can be done using either Set Variables Action sampler or using JSR223 Sampler or whatever is the most convenient way for you to do this.

JMeter , Execution order is not correct

I have 4 transaction controllers named
Trans_api1
__Http Request
Trans_api2
__Http Request
Trans_api3
__Http Request
Trans_api4
__Http Request
that contain Http Requests, However when I run my test plan, I want them to run in numerical order but then they run randomly. How do I fix the order to it runs from 1-4?
Each JMeter thread (virtual user) runs Samplers upside down so you don't need to do anything, your requests are executed from top to bottom already. If you run your test with 1 user - you will see that requests are being executed sequentially.
If you're seeing some "mess" most probably it's caused by concurrency, like
1st user starts 1st request
2st user starts 2nd request
2nd user starts 1st request
1st user starts 3rd request
etc.
You can see this yourself if you add ${__threadNum} function as the prefix or postfix for your request (or transaction controller) label and eventually ${__groovy(vars.getIteration(),)} function to display the current loop number
With 1 user:
With 2 users:
With 2 users and 2 iterations:
As it evidenced by the above images each users executes samplers sequentially on each iteration, these "inconsistencies" are misleadingly interpreted due to concurrency
See Apache JMeter Functions - An Introduction article to get familiarized with JMeter Functions concept

Jmeter How to make 2 thread group run parallel but not sharing parameter value between thread?

I have a situation like this:
Test Plan
Thread Group 1
var A = 1 ( User parameters)
HTTP request 1
HTTP request 2
Thread Group 2
var A = 2 ( User parameters)
HTTP request 3
HTTP request 4
I know that I can use "Run Thread Groups consecutively" to make these 2 thread run parallel. However, the problem is, because they are running parallel, sometimes var A=2 got recognized in Thread Group 1, and thus make the test case fail. What I ask, is there any way that I can still run these threads parallel and still make sure that the parameter values of these threads won't affect on each other? Thank you!
You can use different name for the variable so that there is no conflict.
Something like below:-
Test Plan
Thread Group 1
var A = 1 ( User parameters)
HTTP request 1
HTTP request 2
Thread Group 2
var B = 2 ( User parameters)
HTTP request 3
HTTP request 4
From the jmeter documentation:-
If you have more than one Thread Group, make sure you use different
names for different values, as UDVs are shared between Thread Groups.
Also, the variables are not available for use until after the element
has been processed, so you cannot reference variables that are defined
in the same element. You can reference variables defined in earlier
UDVs or on the Test Plan.
Hope this helps.
This is not possible as JMeter Variables scope is limited to current Thread Group only so the situation where 2nd Thread Group is reading the values from 1st Thread Group User Parameters element is either a bug in JMeter or your test fails for a different reason. For example not having a User Parameters element in 2nd Thread Group I'm not getting anything as the variable value:
I would recommend double checking expected variable A values using Debug Sampler and View Results Tree listener combination, perhaps your configuration is vague.

JMeter HTTP Request Post Body from File

I am trying to send an HTTP request via JMeter. I have created a thread group with a loop count of 25. I have a ramp up period of 120 and number of threads set to 30. Within the thread group, I have 20 HTTP Requests. I am a little confused as to how JMeter runs these requests. Do each of the 20 requests within a thread group run in a single thread, and each loop over a thread group runs concurrently on a different thread? Or do each of the 20 requests run in different threads as and when they are available.
My other question is, Over each loop, I want to vary the body of the post data that is being sent via the HTTP request. Is it possible to pass the post data body via a file instead of inserting the data into the JMeter Body Data Tab as show below:
However, instead of doing that, I want to define some kind of variable that picks a file based on iteration of the threadgroup that is running, for example, if it is looping over the thread group the second time, i want to call test2.txt, if the third time test3.txt etc and these text files will contain different post data. Could anyone tell me if this is possible with JMeter please and if so, how would I go about doing this.
Point 1 - JMeter concurrency
JMeter starts with 1 thread and spawns more threads as per ramp-up set. In your case (30 threads and 120 seconds ramp-up) another thread is being added each 4 seconds. Each thread executes 20 requests and if there is another loop - starts over, if there is no loop - the threads shuts down. To control load and concurrency JMeter provides 2 options:
Synchronizing Timer - pause all threads till specified threshold is reached and then release all of them at the same time
Constant Throughput Timer - to specify the load in requests per minute.
Point 2 - Send file instead of text
You can replace your request body with __fileToString function. If you want to parametrize it you can use nested function to provide current iteration - see below.
Point 3 - adding iteration as a parameter
JMeter provides 2 options on how you can increment a counter each loop
Counter config element - starts from specified value and gets incremented by specified value each time it's called.
__counter function - start from 1 and gets incremented by 1 each time it's being called. Can be "per-user" or "global"
See How to Use JMeter Functions post series for comprehensive information on above and more JMeter functions.

Force a thread to use same input line when using CSV Data Set Config

I am trying to build a Jmeter test plan that can make http calls to a server. Each thread in the thread group will read 2 parameters from a CSV file and make the http call with the params, and continue to make the same call with same parameters for lets say 1000 times with a delay of 10s between each thread execution.
The http call looks like
/service/method?param1=${param1}&param2=${param2}
The CSV is like this:
1,2
3,4
5,6
7,8
I have the test plan set up that works for the most part except the single issue. I want each thread to use the same parameters (same line of input) whenever the thread executes. Currently the only way to do it is to set Recycle on EOF = true, but the threads randomly pick the values. Param1 and Param2 can be randomly generated values as long as they stick with the same thread throughout the execution.
Is there anyway I can achieve this?
Thanks!
I'm not really sure I understand your issue right (you can possibly describe it more explicitly or using an example) but the schema below should implement your test-plan description:
Test Plan
Thread Group
Number of Threads: N
. . .
While Controller
Condition: ${__javaScript("${param2"!="<EOF>",)} - read csv-file until the EOF
CSV Data Set Config
Filename: [path to your file with test-data]
Variable Names: param1,param2
Recycle on EOF? False
Stop thread on EOF? True
Sharing mode: Current thread group
Loop Controller
Loop Count = 1000 - number of loops for each thread, with the same params
HTTP Request - your http call
Test Action
Target = Current Thread
Action = Pause
Duration (ms) = 10000 - pause between calls
. . .
In case if you need that each of N threads reads and uses single and unique line from csv-file you have to set Sharing mode: Current thread group for CSV Data Set Config (number of csv-entries should be in this case the sane as threads number, or Recycle on EOF? False should be set otherwise).
In case if you need that each of N threads reads and uses all lines from csv-file you have to set Sharing mode: Current thread for CSV Data Set Config.
If that's not what you want please describe your issue a bit more clear.
I was able to find sort of a hack. Basically I just put a constant timer for each thread and used the thread number ${__threadNum} as the parameter to fit my constraint of having the same parameter to be used by the same thread.
I would still prefer a way to read the params from a csv file.