How to assert stdout statements from JMeter logs? - jmeter

We have a beanshell test that executes a JAR, that in turn, prints the response on stdout; very similar to the process described in this article. However, I'm wondering if there is a way to validate the statements printed in the log as part of the tests without resorting to manual verification.

Forget about Beanshell, since JMeter 3.1 you should be using JSR223 Test Elements and Groovy language
Your test design looks very flaky ang vague, however if you cannot think of a better option than capturing stdout you can create your own PrintStream and use System.setOut() function to use your own PrintStream instead of STDOUT. Something like:
Add setUp Thread Group to your Test Plan
Add JSR223 Sampler to the setUp Thread Group
Put the following code into "Script| area:
def baos = new ByteArrayOutputStream()
def ps = new PrintStream(baos)
System.setOut(ps)
props.put('baos', baos)
Once done you can access all the messages which were printed to the STDOUT using the following code:
def stdout = props.get('baos').toString()
Demo:

Related

Jmeter : validating a log viewer result with sampler

I am executing a jp#gc - WebDriver Sampler script in which console - log view i am getting a result in text for example check the below image INFO c.g.j.p.w.s.WebDriverSampler: Result1:Image not present
I need to validate the webdriver sample from that result . Any suggestion pls
If you really want to read jmeter.log file and look for the specific message in there you could do something like:
def log = org.apache.commons.io.FileUtils.readFileToString(new File('jmeter.log'), 'UTF-8')
if (org.apache.commons.lang3.StringUtils.containsIgnoreCase('Banner not present', log)) {
WDS.sampleResult.setSuccessful(false)
WDS.sampleResult.setResponseMessage('Failed to locate message "Banner not present" in the log')
}
where WDS.sampleResult stands for SampleResult implementation and you can amend response code, message, mark the sampler as passed or failed and so on.
however it's better to do it on Groovy variable level, i.e.
if (!k) {
WDS.sampleResult.setSuccessful(false)
}
you can also consider relying on Groovy Truth, there is no need to declare booleans
More information on Groovy scripting in JMeter: Apache Groovy: What Is Groovy Used For?

Jmeter JSR223 Unable to read data from CSV file

Requirement is ItemID should be read from external CSV file and passed in the JSR223 preprocessor script. This is the groovy code in JSR223 and it is working as expected in the grrovy executer.
def items = []
List<String> lines = new File("C:\\Users\\854986\\itemid.csv").readLines()
def itemNo = RandomUtils.nextInt(5, 10)
1.upto(itemNo) { index ->
def item = [:]
def lineFromCsv = lines.get(index as int)
item.put('itemId', lineFromCsv)
But it jmeter it is throwing error and below is the error message.
"2022-11-15 12:34:14,398 ERROR o.a.j.m.JSR223PreProcessor: Problem in JSR223 script, JSR223 PreProcessor 3
javax.script.ScriptException: org.apache.commons.jexl2.JexlException$Parsing: JsonBuilder#1:20 parsing error near '... ment, miss ...'
at org.apache.commons.jexl2.scripting.JexlScriptEngine.compile(JexlScriptEngine.java:237)"./
I have java 19.0.1, Jmeter 5.4.3 and groovy 4.0.2.
You're talking about "groovy code". Any reason to use jexl2 language in the JSR223 PreProcessor?
Make sure to choose groovy as the language and at least this error should go away. Groovy is the recommended scripting option since JMeter 3.1 mainly because Groovy provides maximum performance comparing to other engines

How to pass a 2-D array from one thread to another thread in Jmeter

So I am using a bean shell post processor and towards the end I am storing the result in a 2-D array. Result is stored this way.
testArray[0][0] = "1"
testArray[0][1] = "Test"
testArray[1][0] = "2"
testArray[1][1] = "STG"
My requirement is that I need to pass this 2-D array to the next thread. How am I supposed to proceed ?
First of all since JMeter 3.1 you're supposed to be using JSR223 Test Elements and Groovy language for scripting so consider migrating to Groovy.
Coming back to your question just use props shorthand like:
In first thread:
props.put("testArray", testArray);
in the other thread:
testArray = props.get("testArray");
you might also want to add the current thread number as the prefix/postfix so different threads could have different arrays with separate values like:
props.put("testArray_" + ctx.getThreadNum(), testArray);
where ctx stand for JMeterContext class instance
More information on these ctx, props and other JMeter API shortcuts available for JSR223 Test elements: Top 8 JMeter Java Classes You Should Be Using with Groovy

How to create simple counter using Beanshell?

I'm trying to create a simple counter that will print the iteration number to the log.
the problem is that I didn't find a way to initialize the int value of i to 0.
if I'll do it inside the Beanshell script it will keep initializing, I need it to run only once at the beginning of the test.
My code:
int i=0;
log.info(string.valueOf(i));
i=i+1;
Add Once Only Controller, under it JSR223 Sampler with the initialization
vars.putObject("i", 0);
Then you can increment it after it (not under the Controller) with other JSR223 Sampler:
myI = vars.getObject("i")
log.info(String.valueOf(myI));
vars.putObject("i", ((Integer)myI+1));
It is recommended to avoid scripting where possible, and if you cannot live without scripting you should be using the most performing option which is JSR223 Test Elements and Groovy language.
Particularly your case can be implemented without any scripting, you can use the following JMeter Functions:
__log() - which prints an arbitrary message to jmeter.log file
__iterationNum() - which returns the number of current iteration
So if you use the statement like: ${__log(Current iteration is: ${__iterationNum},,,)} JMeter will return it where the function is called and additionally print the corresponding message to the log file.
Demo:
You can install __iterationNum() function as a part of Custom JMeter Functions bundle using JMeter Plugins Manager

Error while processing a beanshell preprocessor

I am new to the beanshell scripting.So my query might have basic syntactical issue.
I am getting "DocConnectionId" from regular expression extractor which is the number of elements in app screen. I have GetNewReferralId which the variablevalue i want to match with DocConnectionId.
I have written the below code:
int DocConnectionId = Integer.parseInt(vars.get("connectionIDWithDoc_matchNr"));
int GetNewReferralId = Integer.parseInt(vars.get("GetNewReferral"));
for(int i = 1;i<=DocConnectionId;i++)
{
if(GetNewReferralId.equals(vars.get("connectionIDWithDoc_"+i))){
Integer.parseInt(vars.put("ConnectionWithDoc"));
break;
}
}
But I am getting the below error in error log.
jmeter.util.BeanShellInterpreter: Error invoking bsh method: eval Sourced file: inline evaluation of: ``int DocConnectionId = Integer.parseInt(vars.get("connectionIDWithDoc_matchNr")); . . . '' : Typed variable declaration : Method Invocation Integer.parseInt
Integer.parseInt(vars.put("ConnectionWithDoc"));
This line is wrong, and is guaranteed to generate a Integer parse exception. vars.put returns void value, so you're effectively trying to parse an integer from void, which will throw an exception.
I cant really tell from your code, but are you trying to store the value of i in variable ConenctionWithDoc? In which case, you should do:
vars.put("ConnectionWithDoc", Integer.toString(i));
Most probably connectionIDWithDoc_matchNr is not defined or you made a mistake in its case.
Could you show you full test plan.
Your code does not make a lot of sense, try elaborating what needs to be done so we could come up with more elegant solution in explanations.
Till that time here is a piece of advice:
If you add debug(); line at the very beginning of your Beanshell script - you'll get extra debug output to STDOUT (console, where you launched JMeter from)
If you surround your code in try/catch block like:
try {
//your code here
}
catch (Throwable ex) {
log.error("Error in script", ex);
}
you'll be able to see more readable and understandable stacktrace in jmeter.log file (usually being generated in the folder, you launch JMeter form)
Familiarize yourself with JMeter API w.r.t. classes you're targeting to use. Copy-pasting from stackoverflow without understanding what does the code do can lead to undefined results
See How to Use BeanShell: JMeter's Favorite Built-in Component article for a little bit more detailed explanations and several real-life examples of using Beanshell in JMeter test scripts.

Resources