I have a scenario of Creating 10 objects, Reading the 10, Updating and Deleting the same objects.
I am using a CSV file for the request,test data, response verification.
I will be receiving a token on creating a object, and am i have no idea on how to store the tokens of 10 created objects and use the same token for GET,UPDATE and DELETE operations.
Note : I have tried to store single token in a variable but am not aware of storing multiple variables and accessing them.
Need inputs on this, Thanks in advance
According to JMeter Functions and Variables User Manual Chapter
Properties are not the same as variables. Variables are local to a thread; properties are common to all threads, and need to be referenced using the __P or __property function.
So if you extract some value into a JMeter Variable in setUp Thread Group and plan to refer it from the other Thread Group(s) you need to convert it into a JMeter Property using __setProperty() function
See Knit One Pearl Two: How to Use Variables in Different Thread Groups article for more details if needed
Related
I am currently designing a test case for multiple users testing using jmeter and I kind of need some help.
Here's the scenario:
Suppose I have 2 different login portals with 500 different users on each portal. I want to do login, access getExamSchedule, startExam, getListQuestion, getOneQuestion, submitOneQuestion and finishExam so I create one new thread group for each request. Each thread has 2 samplers (1 for portal A, 2 for portal B).
My question is how am I supposed to pass the multiple generated tokens from login thread so that I can access the rest of the thread with different tokens. And also each http request has some response I need to extract to be used on another thread. I tried to extract the tokens and the responses to csv file but somehow it didn't work. Let me know if there's any best practice for this scenario. Thank you in advance!
so I create one new thread group for each request - normally you should create separate/different Thread Groups only for new logical groups of virtual users, for your use case I think everything could be in one Thread Group.
As per JMeter Documentation:
Properties are not the same as variables. Variables are local to a thread; properties are common to all threads, and need to be referenced using the __P or __property function.
So if you really need to pass values across different Thread Groups - you can take a look at following solutions:
__setProperty(), __threadNum() and __P() functions combination like:
To set the property:
${__setProperty(token_${__threadNum},${jmeter-variable-holding-the-token},)}
To read the property: ${__P(token_${__threadNum},)}
Use Inter-Thread Communication Plugin
I am currently trying to extract 10 different ids(each request will generate a different id) then i am trying to use those 10 different ids in the next thread group.
The way i am doing this is by first using a HTTP request inside a simple controller then i am using a thread group and using a module controller.
First i extract the id from the response and creating a variable like this:
Then i am setting property name like:
${__setProperty(loginassistant_${__threadNum},${loginassistant},)}
Then i am using thread group and inside a thread group i am using a module controller with 10 threads
then in the next request i am reading it similarly:
${__P(loginassistant_${__threadNum},)}
But unfortunately in all my requests(10) it is using the same id generated from the first thread group. However, i would to see 10 different ids being used to each 10 of the other requests
How many threads does your Thread Group which executes Journey Steps have? If its only one - you will have only one ID generated as JMeter properties are global.
Since JMeter 3.1 you're supposed to be using JSR223 Test Elements and Groovy language for scripting so consider migrating to JSR223 Assertion and the following Groovy code (it's equivalent of your functions calls)
props.put('loginassistant_' + (ctx.getThreadNum() + 1), vars.get('loginassistant'))
where:
props is a shorthand for JMeter Properties
vars stands for JMeterVariables
ctx is for JMeterContext
See Top 8 JMeter Java Classes You Should Be Using with Groovy article for more details.
Here is the evidence of the approach working:
Any reason for not going for Inter-Thread Communication Plugin?
I have a thread which writes data to a csv file and data looks like this in that file, as you see below each data is separated by a , then line feed.
ApiKey
20a145260241463194bf84f43952da9c:dut8ghdt+iQrsmYEgKzHzF1It79aWRIjb/d1wM8U3WE=,
93,
d0e29bb7-476d-4a52-9527-e5d9bb0ac34a
In another thread I am trying to read the data so I have done the following. Added a "CSV Data Set Config" with correct filename variables X,Y,Z and my Delimiter I have tried all these A=,n or B=n or C=n, I am not able to get Y and Z properly. What am I doing wrong?
Synchronization of data between thread groups using CSV files is not the best idea as you will have to implement a form or read/write lock to ensure that only one thread is writing data to the CSV file at a time and that will cause throughput degradation.
So I would recommend going for one of the following solutions:
Use __setProperty() function to convert the data from JMeter Variables into JMeter Properties. JMeter Properties are global for the whole JVM therefore they can be accessed from another Thread Group(s). See Knit One Pearl Two: How to Use Variables in Different Thread Groups article for more information.
Use Inter-Thread Communication plugin which implements FIFO queue so you can block threads in 2nd thread group unless data from 1st thread group is available. You can install Inter-Thread Communication Plugin using JMeter Plugins Manager
Both approaches are in-memory therefore you will not need to store data in interim files.
I have created a thread with three steps to:
Access token request: it generates a token to be used in step three. This token is stored in a property
${__setProperty(accessToken,${accessToken})}
Logon Get request to hit a url
Logon Post request, pass some data to the url and I have set the Authorisation header using the Bearer + accessToken (the one generated in first step.
Running a single thread it works, perfect; but when I increase the number of threads, the 3 steps are not running in sequence, maybe I have some Access token before the first Logon Post and I see the token this one is using is not the token generated in the first step, it is the last one generated.
If I set a rump time longer of the total execution time it works, but then I cannot run several threads on parallel.
How can I configure the script to run the threads using the correspondent token generated in step 1 in each Post? How can I different properties or variables to store the token of every thread and use them?
Thanks.
Your issue is that you are mixing Variables and Properties.
In summary, as per functions reference:
Variables are per Thread
Properties are shared accross Threads
So don't use setProperty, just use ${accessToken}
Use property only when you want to effect all threads. Otherwise you can save variables in other variable as in User_Parameters where you put new variable name the value can be a different variable as ${accessToken}
filling in the Variable name in the 'Name:' column. To add a new value to the series, click the 'Add User' button and fill in the desired value in the newly added column.
Values can be accessed in any test component in the same thread group, using the function syntax: ${variable}.
I currently have a test plan where I use a random variable to submit a post request to a given URL (/app/${app_id}).
I want to also re-use the random variable app_id to poll the status of that app (/app/${app_id}/status). Note there would be multiple requests to the status URL.
My current idea is to:
have one thread group that submits the posts
save a list of the randomly generated app_ids
in another thread group, read the list of app_ids and for each app_id, loop the status request
Is this a sensible approach? If so, how can I go about saving the randomly generated app_ids and then reading them?
Also, if there is a better approach to this situation, I'm all ears :)
You can pass the values from one thread group to another one using __setProperty() function like:
${__setProperty(appid-${__counter(FALSE)},${your_variable_holding_appid},)}
Each time the function will be called it will generate a JMeter Property in form of
appid-1=foo
appid-2=bar
appid-3=baz
etc.
Where numbers like 1, 2, etc. are coming from __counter() function
In another Thread Group you will be able to access the generated values using __P() function like:
${__P(appid-${__counter(FALSE)},)}
Demo:
See Apache JMeter Functions - An Introduction for more information on JMeter Functions concept.
There is more "advanced" way of passing JMeter variables between threads and even thread groups, moreover you will be able to synchronise your threads, i.e. don't start thread in 2nd thread group until variable is not set using Inter-Thread Communication plugin.
Solution with Thread Groups is feasible, although you also can do all that in one thread group, by configuring one of the threads to be "monitor", while remaining threads submit posts. Something like this:
Thread Group
If [${__threadNum} == 1]
Samplers to check status
If [${__threadNum} != 1]
Samplers to submit posts
One reason to use 1 thread group for both types of users is if you need any sort of synchronization between writing and reading app_id list - that is easier to achieve in one thread group. Or if you already have many thread groups.
As for providing app_id to various threads/thread groups, you can use one of the approaches:
To pass IDs from one thread group to the other without a file, you can use one of the methods described here (using properties is the most popular way).
In your case, probably the easiest is to save them in one property with some delimiter, e.g. ID1,ID2,.... The "status" thread then can get this property, split it using either script or __split function to convert property into serialized variables: app_id_1, app_id_2, etc. Those variables are a natural choice for ForEach Controller.
Also first thread group could be saving app_ids into file, while the other reads from the same file with CSV Data Set Config. A bit of caution here though, if they are doing it at the same time.
If app-ids can be pre-generated, a more economical approach would be to have SetUp Thread, which generates them and saves them to CSV file (you will only need one script, e.g. BeanShell to do that, see example here). And then both thread groups read from that file using CSV Data Set Config