JMeter If Controller - jmeter

not too sure if this is a user error but I can't seem to get this working. I have a test that returns 200 and this always hits the If controller, but the following fails.
I get a productID, if this is nested then i get the first one.
Regex is
prodID
"ProductId":(.*?),
$1$
0
Then as I want to use this in another thread group I cjhange to a property:
${__setProperty(prodID-${__threadNum},${prodID},)}
Then i use If Controller as
${__P(prodID-${__threadNum})} == "18"
Then it runs the same regex, but this time with $2$
Problem is that the If Controller isn't getting run on any, is there a way I can see this, or even is the above correct?
Thanks

The If Controller run its children if the expression evaluates to true
You're giving 18 == "18", it is not equal to true therefore the children are not getting executed.
I would suggest using __groovy() function instead like:
${__groovy(props.get('prodID-' + ctx.getThreadNum()).equals('18'),)}
where
props is a shorthand for Properties class instance holding JMeter Properties
ctx is a shorthand for JMeterContext class instance
See Top 8 JMeter Java Classes You Should Be Using with Groovy article for more information on this and other JMeter API shorthands

Related

How to parametrize number of threads in JMeter 5.2.1

I have a JMeter 5.2.1 project where in the SetUp thread I generate properties with names like ThreadGroupName1-NumberOfThreads, ThreadGroupName2-NumberOfThreads, etc. with values representing integers.
Now, I wish to access these properties in thread groups named ThreadGroupName1, ThreadGroupName2, etc. to parametrize the number of threads. I tried something like ${__jexl3(props.get(threadName + "-NumberOfThreads"))} but it fails as threadName evaluates to standardjmeterengine.
Also, I tried to use ctx but ctx.getThread() and ctx.getThreadGroup() but they evaluate to null.
So far what 'works' for me is ${__jexl3(props.get("ThreadGroupName1-NumberOfThreads"))} but I want it be parametrized by the name of the thread group.
Is it possible to do this?
Is this threadName returning standardjmeterengine a bug?
Update: In fact, the easiest 'solution' that provides the parametrized number of threads there is ${__P(ThreadGroupName1-NumberOfThreads)} and what I want is to generate this key ThreadGroupName1-NumberOfThreads to be something like ${MyCurrentGroupName}-NumberOfThreads, effectively providing a way to have an abstract method like
int GetNumberOfThreads(string threadGroupName)
{
return properties.get(threadGroupName + "-NumberOfThreads";
}
Similarly, I wish to use this patter in Constant Throughput Timer as well with another prefix like -Rpm.
I don't think you can use any JMeter Function in the "Number of Threads" field of the Thread Group so this is not something you can do via UI. If you believe this is something everyone needs you can consider raising an enhancement request
As a workaround you can
Set the number of threads to 1
Add If Controller to the Thread Group and use the following __groovy() function as the condition:
${__groovy(ctx.getThreadNum() == 0 && vars.getIteration() == 1,)}
Add JSR223 Sampler as a child of the If Controller and put the following code into "Script" area:
SampleResult.setIgnore()
2.upto(props.get(ctx.getThreadGroup().getName() + '-NumberOfThreads') as int, { ctx.getThreadGroup().addNewThread(0, ctx.getEngine()) })
This way each thread Group will normally start with 1 thread, however this thread will read the property you defined earlier and add as many threads as needed.
You can use JMeterContext's getThreadNum to get thread number (increment, because it starts with 0)
${__jexl3(props.get("ThreadGroupName"))}${__jexl3((ctx.getThreadNum()+1) + "-NumberOfThreads" )}

Can we control Jmeter's components through Beanshell? I want to disable all assertions through one flag. how can I do it?

Can we control Jmeter's components through Beanshell? I want to disable all assertions through one flag. How can I do it?
If any other solution than beanShell then let me know.
The easiest way is running your JMeter test using Taurus tool as a wrapper, it naturally supports JMeter tests, moreover it provides some nice extensions.
Particular in your case you can use Modifications for Existing Scripts functionality which allows enabling or disabling Test Elements
---
scenarios:
modification_example:
script: /your/jmeter/testplan.jmx
modifications:
disable: # Names of the tree elements to disable
- Response Assertion
- Duration Assertion
I see two ways in addition to previous answers:
1) Wrap assertions into If controllers, then - yes, set a flag var & check at the If block.
2) Run JMeter programmatically through JMeter API - here you'd have programmatic access to each and every element in the TestPlan.
Although that way is documented quite poorly while the API model is far from being clear itself.
UPD: some clues for the way of doing the latter
1) Here's the main reference: http://jmeter.apache.org/api/index.html
2) Instantiate engine and load properties:
StandardJMeterEngine jmeter = new StandardJMeterEngine();
JMeterUtils.loadJMeterProperties("/path/to/jmeter.properties");
3) Instantiate SaveService and load your plan (yes, save service is what resposible for that)
SaveService.loadProperties();
File yourplan = new File("/path/to/yourplan.jmx");
HashTree planTree = SaveService.loadTree(yourplan);
4) Here's the point where you can access & work your plan elements, going through the HashTree, retrieving test elements in sub-hashtrees (for elements, see the reference mentioned in p.1) & changing them and/or the test structure (cast to TestElement must be good enough for enabling/disabling).
5) As you got done with it, the rest is straightforward:
jmeter.configure(planTree);
jmeter.run();
That should be pretty much it.
From my knowledge, you can not disable all Assertions in the Test Plan by using BeanShell
The work around is as follows:
Create a variable as processAssertions in User Defined Variable config element.
Keep All Assertions inside If Controllers.
Add condition as ${processAssertions}==true, so Assertions will be evaluated ONLY when you set the processAssertions value to true. Set any value other than true, to make JMeter to ignore Assertions.
Using Bean Shell Assertion:
Pre-condition: create processAssertions (Set to TRUE) in User Defined Variables
import org.apache.jmeter.assertions.ResponseAssertion;
log.info("hello");
try{
ResponseAssertion obj = new ResponseAssertion();
if(${processAssertions}==TRUE) { // value accessed from UDV
log.info("inside if");
obj.Enabled=false;
SampleResult.setSuccessful(true); // set sample result to PASS, set to false to mark it failure.
}
} catch(Exception e) {
}
If Controller - with assertions:
If Controller - without assertions:
References:
https://www.blazemeter.com/blog/how-use-jmeter-assertions-3-easy-steps
http://jmeter.apache.org/usermanual/component_reference.html#assertions

Jmeter while controller doesn't seem to evaluate variables as numbers

I am writing a jmeter script that keeps loading data until a table reaches a specified size. I have a while loop, in which I have one HTTP Sampler to loads the data, then another HTTP Sampler with an XPath Post-processor to check the table size (they call two different APIs). The reference variable of the XPath Post Processor is currentSize and I have a user defined variable maxSize, but using ${currentSize} < ${maxSize} as the condition for the while loop creates an infinite loop.
Thinking maybe the problem is that the output of XPath is a string, I've tried doing various things in beanshell to coerce it to a number, but I'm a beanshell noob, so I haven't been successful with that either. Can anyone guide me about how to get jmeter to recognize a variable as a number? (Preferably a decimal, but if I have to round to an int, I can live with that.)
Thanks!
I think using __javascript(parseInt()) should suffice for you to check the condition.
e.g.
${__javaScript(parseInt(${time_elapsed_string}) < parseInt(${duration}))}
Assuming that you have following variables:
currentSize
maxSize
continue
where continue is set via User Defined Variables and has the value of true
You can use following Beanshell code to check if current size is equal or greater than maximum size:
import java.math.BigDecimal;
String currentSize = vars.get("currentSize");
String maxSize = vars.get("maxSize");
BigDecimal currentSizeNumber = new BigDecimal(currentSize);
BigDecimal maxSizeNumber = new BigDecimal(maxSize);
if (currentSizeNumber.compareTo(maxSizeNumber) > -1){
vars.put("continue", "false");
}
Make sure that following criteria are met:
Your While Controller has ${continue} as a condition
Beanshell Sampler, Pre / Post Processor or Assertion with the code above is added as a child of the While Controller
See How to use BeanShell guide for more details and kind of Beanshell cookbook.
Everything should work this way.
Hope this helps.

How to make jmeter while controller work

I'm having trouble getting the while controller to work in jmeter.
I've a feeling that I read that it doesn't re-evalute user defined variables, so I am trying to use properties instead.
I start off by using a BSF assertion to set a property called keepLooping
${__setProperty(keepLooping, true)};
This seems to work as it enters the While controller with a condition of
${__property(keepLooping)}
But I cannot for the life of me get it to change that property to something else. I want it to change the property depending on the resulting text of an http request.
So I am using a Regular Expression Extractor to set a variable, which I can see is getting set. Then I am trying to use a BSF assertion to set the keepLooping property on the basis of the variable that I have set. I am using javascript as follows:
log.info("IM IN HERE");
log.info("props is "+props);
//log.info("props keep looping is "+props["keepLooping"]);
if (${surveyRequired} == false){
log.info("IM IN HERE 1A and props is "+props);
${__setProperty(keepLooping, true)};
log.info("IM IN HERE 1B");
}
else {
log.info("IM IN HERE 2A");
${__setProperty(keepLooping, false)};
log.info("IM IN HERE 2B");
}
I can't figure out how to set the property with javascript - I've tried several things. Can anyone help? Many thanks!
Also can anyone recommend a good resource that negotiates what seem to be the many 'quirks' of jmeter? Many thanks!
"I've a feeling that I read that it doesn't re-evalute user defined variables" -- I use JMeter 2.9 and it really does. I use user defined variable in order to count number of loops. It looks like: ${__javaScript(${MY_USER_DEFINED_VARIABLE}>0)}. The only one annoying thing is that I have to get value of variable, increment it, cast to string (toString() in Groovy), and then put new value into MY_USER_DEFINED_VARIABLE (by using vars.putObject("MY_USER_DEFINED_VARIABLE",localBSFVariable))
Using vars.put or props.put will help, as explained in detailed in detail in this jmeter thread.

SoapUI XPath assertion with wildcards

Is there a way to use a wildcard inside an assertion in a XPath test with SoapUI?
I took a look at SoapUI's documentation and they say you can do something like this
<path1>
<path2>*</path2>
</path1>
I checked the 'Allow Wildcards' checkbox.
My question is : I want to assert my date starts with 2012-08-22 but i dont care about the minutes and seconds. I guess my the expression should be something like 2012-08-22* but it doesn't work.
What you are doing sounds like it should work. Here is a quick example i cooked up using a rest service from http://www.geonames.org/export/web-services.html#timezone. I'm using the demo they have supplied
http://api.geonames.org/timezone?lat=47.01&lng=10.2&username=demo
output is
<geonames>
<timezone tzversion="tzdata2012c">
<countryCode>AT</countryCode>
<countryName>Austria</countryName>
<lat>47.01</lat>
<lng>10.2</lng>
<timezoneId>Europe/Vienna</timezoneId>
<dstOffset>2.0</dstOffset>
<gmtOffset>1.0</gmtOffset>
<rawOffset>1.0</rawOffset>
<time>2012-07-25 04:39</time>
<sunrise>2012-07-25 05:50</sunrise>
<sunset>2012-07-25 21:00</sunset>
</timezone>
</geonames>
If you do an xpath match on the result and use the select from current button you get
//geonames/timezone/time
2012-07-25 04:39
If you update this to
//geonames/timezone/time
2012-07-25*
this will work fine and when updating the rest request with a new lat and lng the assertion will still pass since it is not checking the time. If this doesn't help, please supply your full assertion and maybe i could help more.
*note: for soap requests, make sure to declare the namespace and then use the proper format
//ns1:message
It will be sort of a pain, but here is what you can do:
1) Figure out an Xpath 'base' using the assertion tab (sounds like you are here already). I used this public site to test against: http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl
I used the CornerPoints method with 'hawaii' as the single param.
I created this 'base' xpath:
declare namespace ns1='http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl';
declare namespace SOAP-ENC='http://schemas.xmlsoap.org/soap/encoding/';
declare namespace SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/';
/SOAP-ENV:Envelope/SOAP-ENV:Body/ns1:CornerPointsResponse/listLatLonOut
(it will write the declare statements for you if you click declare)
(which you can test out in the assertions window)
2) Create a Properties step
3) Create a Property transfer step
4) Create a groovy script
5) add a property... i called mine misc
6) add a transfer step
* transfer from the CornerPoints - Request 1 --- Response
* paste the Xpath stuff in the box under the 'transfer from'
* Transfer to your property
(You can test with the little play button)
7) Add something like this to your groovy script:
def x = context.expand( '${Properties#misc}' )
def parts = x.tokenize(',')
for (def part in parts)
{
log.info(part)
if (part.startsWith("-153"))
log.info("good")
}
In the groovy step you can do anything you need to get at your (partial) data. The sample code I added gets lat/lons out of a long line wrapped in CDATA and then checks for just the starting part of some of the data.. just an example.
Remember that you can use groovy and java string methods:
http://groovy.codehaus.org/groovy-jdk/java/lang/String.html
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/String.html
More groovy tips:
http://www.soapui.org/Scripting-Properties/tips-a-tricks.html

Resources