How to share access token between JMeter thread groups - jmeter

I have added the Test Plan in below-following orders
1.Test Plan with user defined variables
2.Header Manager
3.Thread Group 1
4.Http Request
5.JSON extractor
6.Thread Group 2
7.Http Request
8.BeanShell Preprocessor
9.Result Tree
Screenshot
How to pass the access token(s) from the first thread group to the second thread group?

Variables cannot be passed/shared between the thread groups.
There could be a number of solutions.
Option 1
Use JMeter properties to share the access token between the thread groups.
props.put("accessToke", accessToke) to add the token and use props.get('accessToken') to retreive the values from the second thread group.
In this solution, you can share just one token across the thread groups.
Options 2
Using Inter Thread Communication plugin.
These queues work in First-In-First-Out manner. You can put a string
value into a queue from one thread, and then get that value from
another thread, even in another Thread Group.

There were at least 3 errors during your last test execution:
Check jmeter.log file for details, the reason should be there
You should be using different thread groups for representing different groups of business users, if you're simulating authentication flow it makes sense to keep both HTTP Request samplers under one Thread Group
JMeter Variables are local to the thread (virtual user) so you won't be able to access the variable value in the different thread and thread group
Since JMeter 3.1 you should be using JSR223 Test Elements and Groovy language for scripting
There is no need to go for scripting at all, just add a HTTP Header Manager as a child of the workspace request (see JMeter Scoping Rules - The Ultimate Guide article to learn more about the scope of JMeter Test Elements) and define the token there. Suggested Test Plan Structure:

Just finished figuring this out. Don't know if it's the best solution. Looked like there were other options.
In my case the first thread group was reading a list of users and passwords from a csv file.
I did it by writing a csv file in the first thread using "JSR223 PostProcessor" after each authentication API call.
Then I read the newly created csv using the "CSV Data Set Config" in the second thread.
Groovy script follows:
import org.apache.jmeter.services.FileServer
log.info("*************************************")
def userId = vars.get("user_id") //JMeter var from parsing auth request
def authToken= vars.get("auth_token")
def configDir = vars.get("config_dir")
log.info("userId:" + userId)
log.info("authToken:" + authToken)
def outputFilePath = configDir + "/userToken.csv"
File outputFile = new File(outputFilePath)
//check if the file exists
if (!outputFile.exists()) {
log.info("File " + outputFilePath + "does not exist")
log.info("Creating a new file")
outputFile << "userId,authToken\n"
}
outputFile << userId + "," + authToken + "\n"
Test Plan on JMeter

Related

How to save 10 different id from Jmeter response and use it in next 10 requests

I am currently running 10 different threads like this:
each of the thread response will provide a different id in the response and i want to save them and use it as a request in the next test case(10 threads) so there will be 10 ids and 10 threads and each thread will have a unique id as a request. This is what I am doing:
Here is the first request
This is how I am extracting the values
This is how i am using the final request however i am not able to get the desired results
UPDATE:
I tried Dmitri Answer but still no luck i am extracting the id by using this
I used __threadNum() function as the prefix or postfix for the property name like:
${__setProperty(loginassistant_${__threadNum},${loginassistant_},)}
and read it similarly:
${__P(loginassistant_${__threadNum},)}
but it is not working and it is setting the value as a static string(see screenshot below):
This is how and where i am defining my loginassistant using the simple controller:
You're using properties which are global, if you have more than one thread the next thread will overwrite the property defined by the previous thread so it could be mismatch.
If you don't need to pass values across thread groups - go for JMeter Variables instead, variables are local to the thread (virtual user) and the properties are global for the whole JMeter/JVM instance
If you do need to pass values across thread groups - either use __threadNum() function as the prefix or postfix for the property name like:
${__setProperty(loginassistant_${__threadNum},${loginassistant},)}
and read it similarly:
${__P(loginassistant_${__threadNum},)}
or go for Inter-Thread Communication Plugin

JMeter - Hitting specific endpoints based on user credentials via multiple CSV files

My JMeter test:
Iterate over a CSV file (logins.csv) with login credentials, and their unique identifier user a CsvDataSetConfig
Sign in
Based on the login credentials (unique identifier from logins.csv), identify and load a second file in the format of <user_identifier>_invoices.csv which then has the necessary path to view an invoice for that user.
Simplified test setup:
ThreadGroup
> CsvDataSetConfig - file: logins.csv, variables: user_identifier,email,password, sharing_mode: all threads
> `SignIn` TransactionController using email and password from above CSV file to login via series of HTTP Requests
> UserParameters - USER_IDENTIFIER,INVOICE_CSV_FOR_USER
> BeanShellSampler
props.setProperty("USER_IDENTIFIER", vars.get("user_identifier"));
props.setProperty("INVOICE_CSV_FOR_USER","${__P(USER_IDENTIFIER)}_invoices.csv");
> WhileController - condition: ${__javaScript("${invoice-id}" != "<EOF>",)}
> CsvDataSetConfig - file: ${__P(INVOICE_CSV_FOR_USER,)}, variables: invoice-id, sharing_mode: current thread
> `ViewInvoice` TransactionController with HTTP Request to url `../${invoice-id}`
# logins.csv
c7beaa99c6d99fa7754fc2213f9b17b8,foo#example.com,password321
9c8466bee65e39c9d3cf715e42933c3b,bar#example.com,password456
# c7beaa99c6d99fa7754fc2213f9b17b8_invoices.csv
f54eca1cbbba4a97c1dc459e0ba64970
0024f2cdf28dd7ebf3606988fd229afd
# 9c8466bee65e39c9d3cf715e42933c3b_invoices.csv
64f725fdeb2980b28bdf5e02076a55cd
60ac45a12ea3d6b59c2cb82f27da1722
Problem:
In local JMeter, seeing requests to invoice urls being made with incorrect invoice-id for the business. So seems the parameters are not being treat correctly between threads.
In BlazeMeter, seeing the content of the while controller never being hit.
I've tried loop controllers, having 50 rows per _invoices.csv file, but not got anywhere with that either. I also originally started off with
User Defined Variables rather than User Parameters, but the latter seems to be what I should be using for this use case.
Threads are running at the same time and sharing JMeter properties.
In your test plan each thread sets the property USER_IDENTIFIER. So this and other property can/will be overriden by different thread(s) and create inconsistency.
I suggest you save (and get) in variables which aren't shared by threads:
vars.put("USER_IDENTIFIER", vars.get("user_identifier"));
vars.put("INVOICE_CSV_FOR_USER"," ${USER_IDENTIFIER}_invoices.csv");
Also about beanshell, JMeter advice to change to JSR223
Since JMeter 3.1, we advise switching from BeanShell to JSR223 Test Elements (see JSR223 section below for more details), and switching from __Beanshell function to __groovy function.

Get number of threads in a thread group from the setup thread group (jmeter)

I have a JMeter test plan which performs a simple action once.
The problem I am having is that my test setup needs to know how many threads the thread group will have. To make things clearer, here is a simple representation of the test plan:
setUp Thread Group
needs to know the number of threads in the below thread group
Thread Group
The number of threads for this thread group is determined via the "Number of Threads (users)" Thread Property.
I can dynamically get the number of threads from within the thread group, but I can't find any way of getting this number from within the setup thread group instead.
Any ideas?
Ideally I was hoping to find something like ${__groovy(ctx.getTestPlan().getThreadGroupByIndex(1).getNumThreads())}, but I can't find anything of the sort.
To be clear, I'm looking for the number of threads as assigned directly in JMeter in the Thread Group properties. This question has absolutely nothing to do with BlazeMeter and is therefore not a duplicate of Get number of threads (defined via BlazeMeter) in a thread group from the setup thread group (jmeter)
You can try defining a User Defined Variable in the Test Plan, let's say "Users_test" and assign it the number of virtual users you want to run the test.
Then simply use that variable in the Thread Group "Number of Threads (users): ${Users_test}, and you can do the same in the setUp.
The fast that you don't know the number of threads indicates that your test is badly designed.
The fact that you have already been given the answer for the same question 6 hours before indicates that you are unwilling to learn and prefer the community to solve problems for you.
Just in case I will repeat using simpler words:
if you need to overcome a JMeter limitation you have to go for scripting
the recommended approach is using JSR223 Test Elements and Groovy language
JMeter API reference lives at https://jmeter.apache.org/api/
Check out Groovy Is the New Black article for examples of using Groovy with JMeter API
Example code to get the number of threads for all thread groups:
import org.apache.jmeter.engine.StandardJMeterEngine
import org.apache.jmeter.threads.ThreadGroup
import org.apache.jorphan.collections.HashTree
import org.apache.jorphan.collections.SearchByClass
import java.lang.reflect.Field
StandardJMeterEngine engine = ctx.getEngine()
Field test = engine.getClass().getDeclaredField("test")
test.setAccessible(true)
HashTree testPlanTree = (HashTree) test.get(engine)
SearchByClass<ThreadGroup> threadGroupSearch = new SearchByClass<>(ThreadGroup.class)
testPlanTree.traverse(threadGroupSearch)
Collection<ThreadGroup> threadGroups = threadGroupSearch.getSearchResults()
threadGroups.each {
log.info("Thread Group: " + it.getName() + "; Number of threads: " + it.getNumThreads())
}
Demo:

Jmeter Inter Thread group communication MxN invocations

I Have a setUp Thread group in which i am creating A resource with unique Id,path it will give me a url to test
In main Test group I have to Test each url created in setupthread group needs to be rigorsly tested.
testplan
In tearDown thread group i need to clear the setupgroup creation .
The problem i am facing is , the property value is getting overridden
Suppose say in SetUpthread group i have created 10 resources then its the last resouce always the mainTest thread group is getting executed
I am looking for a way foreach setupThread group resource the mainTest theadgroup must execute the no of times i specified in the TheadCount and LoopCount
eg: setUpThread group ThreadCount is 10 and Loop count is 10 then i will get 100 different unquie resources would be created then its the mainTest ThreadGroup
100 TC , 100 LC i.e., for each resource its 10000 times gets invoked .
please help me in acheiving this attached pic
You can take a look at http://jmeter-plugins.org/wiki/InterThreadCommunication/ plugin.
This will help in your case. Let me know if this works.
It is hard to suggest anything without having your test plan itself so here is just an approach, I don't guarantee that it'll work, however the idea should be fine.
You need to set up as many properties as many URLs you would like to be hit in the main thread group.
For instance, if you write some URL down in JSR223 Sampler using __counter() function output as postfix like:
This will generate the following properties:
URL_1=http://some.url
URL_2=http://some.other.url
etc.
After that in 2nd Thread Group you can add another JSR223 Sampler to convert JMeter Properties to JMeter Variables like:
Enumeration e = props.propertyNames();
while (e.hasMoreElements()) {
String propertyName = e.nextElement().toString();
if (propertyName.startsWith("URL_")) {
vars.put(propertyName, props.getProperty(propertyName));
}
}
Then you should be able to use ForEach Controller to iterate the variables.
Also make sure you use Groovy as JSR223 PostProcessor and Sampler language

Running a Beanshell pre-processor once in a test plan

I have a Bean shell preprocessor which ends up setting up some global variables like host name and the path according to the value that the user passes.
The variables that the bean shell sets would be used by all the thread group.
Currently i've placed my BS pre-processor outside a thread and it runs perfectly..
The issue is that it runs for every thread which isn't performance friendly.
I just want it to run once at the start of the Test plan to improve performance.
I tried to put it into a setUp thread but it doesn't work.
Is there something other that the BS-preprocessor that i can use which would be performance effective(which runs only once for the entire plan rather than for every thread).
You can put it under If Controller and use the following condition:
${__BeanShell(vars.getIteration() == 1)} && ${__threadNum} == 1
You can use setUp Thread Group which is designed for executing pre-test actions but in that case change all occurrences of vars.put() to props.put() as JMeter variables scope is limited to current thread group only and Properties are global for the whole JVM instance. See How to Use Variables in Different Thread Groups guide for additional information
JMeter SetUp thread group and TearDown thread group are meant for exactly this. These threads run at the start and the end of test plan. So, just add Setup thread group and add beanshells into. See links for more information:
http://jmeter.apache.org/usermanual/component_reference.html#setUp_Thread_Group
In the other hand, vars are limited for each thread groups. Use props to put a value which is shared with all thread groups.
This worked for me... Just configure a User Defined Variable called firstTimeIndicator and set the value to 1
String firstTimeIndicator = "";
firstTimeIndicator = vars.get("firstTimeIndicator");
if (firstTimeIndicator.equals("1")) {
log.info("The code inside the if statement executes once per test run...");
firstTimeIndicator = "0";
vars.put("firstTimeIndicator",firstTimeIndicator);
}
log.info("The code after the if statement executes once per thread");

Resources