Validate the response from JDBC request using beanshell or JSR223 - jmeter

For my JDBC request, the following result I am receiving from Oracle DB and want to validate the response should not give more than 1 records and EVENT_LOG_ID=48144960
AUDIT_CONTEXT_KEY, EVENT_LOG_VALUE, EVENT_LOG_ID, EVENT_LOGGED_DTTM
72454_2021-09-16T07:44:41.439Z ENG_SITE 48144960 16-SEP-21 07.44.43.456000000 AM
Config Details:
Result Details:
Debugger Sampler Result:
dataFromDB=[{EVENT_LOG_VALUE=ENG_SITE, EVENT_LOG_ID=48144960, EVENT_LOGGED_DTTM=2021-09-16 07:44:43.456, AUDIT_CONTEXT_KEY=72454_2021-09-16T07:44:41.439Z}]

Please add a JSR223 Assertion with the following code, this will validate what you are looking for,
1.upto(vars.get('AUDIT_CONTEXT_KEY_#') as int, {
if (vars.get('AUDIT_CONTEXT_KEY_' + it) == '1') {
if (vars.get('EVENT_LOG_ID_' + it) != '48144960') {
AssertionResult.setFailure(true)
}
}
})

Related

How to assert failure if string is in JSON response from http request JMeter

I am trying to write a test that ensures that the name property in a JSON response is not MYGROUP. I'm stuck here because I'm trying to use the code from a test that checks that the name property is MYGROUP. I know I need to fix something in the if condition of this test:
# Check AD group deletion
- url: ${ADSubscriptions}/${NetworkID}/clientsyncs/${syncId}/groups
label: 1360_CheckADGroupDeletion
method: GET
headers:
Authorization: Bearer ${access_token}
Content-Type: "application/json"
Accept: "application/json, text/plain, */*"
assert-httpcode:
- 200
- 202
jsr223:
- langauge: groovy
execute: after
script-text: |
import groovy.json.JsonSlurper
def slurperresponse = new JsonSlurper().parseText(prev.getResponseDataAsString())
for (entry in slurperresponse){
if(entry.name == "MYGROUP" || entry.name == "mygroup" ){
{RETURN FALSE HERE}
break;
}
}
- langauge: groovy
execute: after
script-file: jsr223/logger.groovy
parameters: check_adgroup_deletion
The expected json structure for the request used in the test looks like this:
[
{
"id": "id1",
"name": "MYGROUP",
"selected": true
}
]
The above response would equate to a failing test. The below would equate to a passing test.
[
{
"id": "id1",
"name": "MYGROUP",
"selected": false
}
]
The code snippet you're looking for is prev.setSuccessful(false) where prev stands for the parent SampleResult class instance.
See the above JavaDoc for all available functions and Top 8 JMeter Java Classes You Should Be Using with Groovy article to learn more about JMeter API shorthands available for JSR223 blocks.
In particular your case it would be easier to use assert-jsonpath Taurus assertion

Geocoding requests to HERE API randomly fails

I am trying to geocode addresses with HERE API. I am not free plan. I try following code (Spring Boot in Kotlin):
override fun geocode(address: Address): Coordinate? {
val uriString = UriComponentsBuilder
.fromHttpUrl(endpoint)
.queryParam("app_id", appId)
.queryParam("app_code", appCode)
.queryParam("searchtext", addressToSearchText(address))
.toUriString()
logger.info("Geocode requested with url {}", uriString)
val response = restTemplate.getForEntity(uriString, String::class.java)
return response.body?.let {
Klaxon().parse<GeocodeResponse>(it)
}?.let {
it.Response.View.firstOrNull()?.Result?.firstOrNull()
}?.let {
Coordinate(
latitude = it.Location.DisplayPosition.Latitude,
longitude = it.Location.DisplayPosition.Longitude
)
}.also {
if (it == null) {
logger.warn("Geocode failed: {}", response.body)
}
}
}
It turned out that when I call this method many times in a row, some requests returns empty responses, like this:
{
"Response":{
"MetaInfo":{
"Timestamp":"2019-04-18T11:33:17.756+0000"
},
"View":[
]
}
}
I could not figure out any rule why some requests fail. It seems to be just random.
However, when I try to call same URLs with curl of in my browser, everything works just fine.
I guess there is some limit for amount requests per seconds, but I could not find anything in HERE documentation.
Does anyone have an idea about the limit? Or may it be something else?
Actually, there was a problem with my code. Requests were failing for addresses having "special" symbols like ü and ö. The problem was with building request URL
val uriString = UriComponentsBuilder
.fromHttpUrl(endpoint)
.queryParam("app_id", appId)
.queryParam("app_code", appCode)
.queryParam("searchtext", addressQueryParam(address))
.build(false) // <= this was missed
.toUriString()

Performance test for graphQL API

Today I'm doing my API automation testing and performance testing with Jmeter when the server is a REST API.
Now the development changed to graphQL API, and I have two questions about it:
What is the best way to perform the automation API and performance testing?
Does Jmeter support graphQL API?
I use Apollo to build the GraphQL server, and use JMeter to query the GraphQL API as below.
1. Set up HTTP Request
2. Set up HTTP Headers
Depending on your application, you might also need to set up HTTP header Authorization for JWT web tokens, such as:
Authorization: Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxx
3. Set up HTTP Cookie if needed for your app
4. Run the test
Disclaimer: I work for LoadImpact; the company behind k6.
If you are willing to consider an alternative, I've recently written a blog post about this topic: Load testing GraphQL with k6.
This is how a k6 example looks like:
let accessToken = "YOUR_GITHUB_ACCESS_TOKEN";
let query = `
query FindFirstIssue {
repository(owner:"loadimpact", name:"k6") {
issues(first:1) {
edges {
node {
id
number
title
}
}
}
}
}`;
let headers = {
'Authorization': `Bearer ${accessToken}`,
"Content-Type": "application/json"
};
let res = http.post("https://api.github.com/graphql",
JSON.stringify({ query: query }),
{headers: headers}
);
Looking into Serving over HTTP section of the GraphQL documentation
When receiving an HTTP GET request, the GraphQL query should be specified in the "query" query string.
So you can just append your GraphQL query to your request URL.
With regards to "best practices" - you should follow "normal" recommendations for web applications and HTTP APIs testing, for example check out REST API Testing - How to Do it Right article.
You can try using easygraphql-load-tester
How it works:
easygraphql-load-tester is a node library created to make load testing on GraphQL based on the schema; it'll create a bunch of queries, that are going to be the ones used to test your server.
Examples:
Artillery.io
K6
Result:
Using this package, it was possible to me, to identify a bad implementation using dataloaders on the server.
Results without dataloaders
All virtual users finished
Summary report # 10:07:55(-0500) 2018-11-23
Scenarios launched: 5
Scenarios completed: 5
Requests completed: 295
RPS sent: 36.88
Request latency:
min: 1.6
max: 470.9
median: 32.9
p95: 233.2
p99: 410.8
Scenario counts:
GraphQL Query load test: 5 (100%)
Codes:
200: 295
Results with dataloaders
All virtual users finished
Summary report # 10:09:09(-0500) 2018-11-23
Scenarios launched: 5
Scenarios completed: 5
Requests completed: 295
RPS sent: 65.85
Request latency:
min: 1.5
max: 71.9
median: 3.3
p95: 19.4
p99: 36.2
Scenario counts:
GraphQL Query load test: 5 (100%)
Codes:
200: 295
I am testing our GraphQL Implementation, you will need:
Thread Group
HTTP Header Manager: You need to add as Content-Type: Application/json
https://i.stack.imgur.com/syXqK.png
HTTP Request: use GET and add in the Body Data your query
https://i.stack.imgur.com/MpxAb.png
Response Assertion: You want to count as correct requests only responses without errors
https://i.stack.imgur.com/eXWGs.png
A Listener:
https://i.stack.imgur.com/VOVLo.png
I have recently tried API testing with GraphQl with both GET and POST request in Jmeter
Make sure its POST request for both Query and Mutation
Example Your Graph Ql query
{
storeConfig{
default_title
copyright
}
}
For Jmeter it would be like this
{
"query":"{ storeConfig { default_title copyright } }"
}
Step up HTTP Request
In place of the localhost, your domain name will come. Make sure you don't add https
Example:- https://mydomainname.com
In Jmeter :- mydomainname.com
Setup HTTP Header Manager
For requesting Mutation in Jmeter
Example mutation in Graphql
mutation {
generateCustomerToken(
email: "rd#mailinator.com"
password: "1234567"
) {
token
}
}
In Jemeter mutation will be like this
{
"query":"mutation { generateCustomerToken( email: \"rd#mailinator.com\" password: \"1234567\" ) { token } }"
}
Replace double quotes with (\") as shown in above query
The easiest way will be to use the GraphQL queries directly in JMeter without the need to convert them to JSON.
All you need to do is to pass "Content-Type" as "application/graphql" in the header.
Image Link for: HTTP Request with GraphQL Query as input
Image Link for: Header details

JMeter - How to read JSON file?

I used the CSV format for the data files in JMeter. Our VP wants to change the format to JSON. How can I read a JSON file from the disk?
You have at least 2 options:
Use HTTP Request sampler and file protocol like:
JSON files are basically plain-text files so you will be able to use JSON Extractor or JSON Path Extractor to parse JSON data and store the result into JMeter Variables for later reuse
References:
Jayway JsonPath - Getting Started
Advanced Usage of the JSON Path Extractor in JMeter
Use JSR223 Test Elements and Groovy language. Groovy has built-in JSON support via JsonSlurper so you will be able to parse the JSON file programmatically.
References:
The Groovy programming language - Parsing and producing JSON
Groovy - JSON
The best solution for this problem is to use JSR223 Sampler to read JSON file and load into the vars or props and use it wherever it is required.
For this,
Add a JSR223 Sampler in JMeter
Add the below code
import java.io.File
import java.util.Base64
def propertiesFromMap(map, prefix) {
for (item in map) {
id = prefix+item.key;
if (item.value instanceof Map) {
propertiesFromMap(item.value, id+".");
} else {
value = item.value.toString();
log.info("Loading property " + id + ": " + value);
if(value.startsWith("ENC:")) {
props.put(id, new String(Base64.getDecoder().decode(value.substring(4, value.length()))));
} else {
props.put(id, value);
}
}
}
}
def baseDir = org.apache.jmeter.services.FileServer.getFileServer().getBaseDir();
def jsonFilePath= baseDir + "/configs/" + "configuration-dev" + ".json";
log.info("Loading properties from " + jsonFilePath);
def jsonMap = new groovy.json.JsonSlurper().parse(new java.io.File(jsonFilePath));
propertiesFromMap(jsonMap, '');
Create a directory named configs where you placed the .jmx file
Create a file named configuration-dev.json in configs directory
Add JSON content e.g. in the file:
{
"key1": "value1",
"key2": "value2",
"key3": "ENC:base64_encoded_value"
"group1": {
"grp1_key": "value"
}
Access values in Samplers e.g. ${__P(key1)}, it will return value of key1. For group1 variables access e.g. ${__P(group1.grp1_key)}
For accessing the values into JSR223 use props e.g. props.get("key1")
You can pass base64 encoded values into JSON by adding ENC: as value prefix which will be resolved automatically when accessing values from props or __P()

log stack trace when HTTP request return error in Jmeter

I want to log all error message for failed HTTP request. I am going to run the thread group for 1B users and I don't want to use the View Result Tree because it logs everything and log file will bloat.
Currently I am using Beanshell Assertion as below.
if (Boolean.valueOf(vars.get("DEBUG"))) {
if (ResponseCode.equals("200") == false) {
log.info(SampleResult.getResponseMessage());
log.info("There was some problem");
}
}
But in this case it just prints the error message but I am interested to log the stack trace returned by the server.
I also used this method as mention in this thread
for (a: SampleResult.getAssertionResults()) {
if (a.isError() || a.isFailure()) {
log.error(Thread.currentThread().getName()+": "+SampleLabel+": Assertion failed for response: " + new String((byte[]) ResponseData));
}
}
But in this case I don't get an object out of SampleResult.getAssertionResults() method and it doesn't display anything in case of HTTP request failure.
Any idea how to get the stacK trace?
I figured it out. SampleResult has one more method called getResponseDataAsString(). This method returns the response message. In case of error it contains the error message.

Resources