How to use for loop for login in karate framework [duplicate] - karate

We're using Karate for backend testing of a microservice. I'd like to be able to make N calls to the backend API, where N is configurable as a number without having to do ugly things.
This was my first approach:
Given url baseUrl
And headers HEADERS
When method get
Then status 200
Given url baseUrl
And headers HEADERS
When method get
Then status 200
Given url baseUrl
And headers HEADERS
When method get
Then status 200
(Just repeating the call) It works, but obviously does not scale well (imagine 1000 of these).
Next approach was a bit better - I put the call in a separate feature and used the https://github.com/intuit/karate#data-driven-features approach:
* table jwts
| headers |
| HEADERS |
| HEADERS |
| HEADERS |
| HEADERS |
| HEADERS |
* def result = call read('call-once.feature') jwts
Slightly better but still does not scale. We also tried varieties of karate.repeat() which seems like the most natural approach, but had trouble with the syntax. None of the examples I could find had an API call inside of a for-each.
* def callFunction = function (HEADERS) { read('call-putaway-once.feature'); { HEADERS: '#(HEADERS)'} }
* def result = karate.repeat(5, callFunction)
But couldn't get any varieties of that working.
Can anyone provide an example of how to repeat the same exact Karate lines N times? I'm really looking for something like:
for (int i = 0; i < numTimes; i++) {
Given url baseUrl
And headers HEADERS
When method get
Then status 200
}
(Or functionally equivalent).
Thanks!

Here you go. First, the second called.feature:
#ignore
Feature:
Scenario:
Given url 'http://httpbin.org'
And path 'headers'
And header X-Karate = count
When method get
Then status 200
And now you can do this in your first feature:
* def fun = function(x){ return { count: x } }
* def data = karate.repeat(5, fun)
* call read('called.feature') data
P.S. by the way search the readme for "polling", there is an example of an API call in a loop: polling.feature

Karate almost have a feature to do this : retry until.
This feature doesn't repeat "n" time, but repeat until a condition is not validate
Example here : polling.feature
For a simple request it's seems like :
Given url baseUrl
And headers HEADERS
And retry until responseStatus == 200
When method get

Related

How to pass parameters to feature file in a loop? [duplicate]

I am making a SOAP request, and I am receiving the response that's returned as an array:
- [print] [
"M4205N",
"M4206U"
]
For each item in the array, I want to make another SOAP request. I've read how you can do this with tables and call a feature file, and I've read how to loop through an array, and call a js function. I cannot figure out how to loop through the array, and pass each value to another SOAP request XML (one at a time).
I want to do something like this:
Given soapURL
And method post
def responseArray = /xml path for the codes I want/
def result = call read('otherRequest.feature') responseArray
The otherRequest.feature file would look something like this:
#ignore
Feature:
Background:
* def myNewRequest = read('soap.xml')
Scenario:
Given soapURL
* replace myNewRequest
| token | value |
| ##refNum## | responseArrayValue |
When request myNewRequest
And method post
However, I get this error:
GetNewMessageList.feature:27 - argument not json or map for feature call loop array position: 0, M4205N
How can I loop through each item in the array, and pass each value to the other feature file?
The addition of this one line should do what you want. Yes there is a hard requirement that the "loop" array should be an array of JSON objects. But you can convert an array of primitives in one step:
* def responseArray = karate.mapWithKey(responseArray, 'responseArrayValue')
This is documented here: https://github.com/intuit/karate#json-transforms

Karate Gatling report - is it possible to avoid url based aggregation?

I just started to use Karate Gatling for performance tests and facing following problem:
I have a call for the search and would like to evaluate different types of search depending on the parameter e.G. https://example.com/search/facetedSearch
'*'
'keyword1'
'keyword1, keyword2' etc.
The feature file looks something like this:
#performance
Feature: Search
Background:
* url 'https://example.com/'
Scenario Outline: Search -> Simple search for a single word
Given path '/search/facetedSearch'
And param facetedSearchAdditionalFilter[searchAreaID] = -1
And param facetedSearchAdditionalFilter[searchKey] = '<SearchTermSimple>'
When method post
Then status 200
And assert iNumHits >= iNumHitsExpected
Examples:
| read('../testData/performanceTestData.csv') |
Scenario: Search -> Simple search for *
Given path '/search/facetedSearch'
And param facetedSearchAdditionalFilter[searchAreaID] = -1
And param facetedSearchAdditionalFilter[searchKey] = '*'
When method post
Then status 200
And assert iNumHits >= iNumHitsExpected
Scenario Outline: Search -> Search for multiple words
Given path '/search/facetedSearch'
And param facetedSearchAdditionalFilter[searchAreaID] = -1
And param facetedSearchAdditionalFilter[searchKey] = '<SearchTermMultiple>'
When method post
Then status 200
And assert iNumHits >= iNumHitsExpected
Examples:
| read('../testData/performanceTestData.csv') |
I would like to evaluate different types of search separately, as the performance is significantly different. What gatling does - it aggregates all different types of search in one result - "POST /search/facetedSearch".
Is there a possibility to let evaluate every type of search individually in one run?
Thanks in advance,
Sergej
Yes, refer the docs on using a custom nameResolver: https://github.com/karatelabs/karate/tree/master/karate-gatling#nameresolver
For your case you should be able to call req.getParam("facetedSearchAdditionalFilter[searchKey]")[0] or something similar. Or you could choose to use an additional header.

How to generate more than one random UUID and use in scenario outline examples in karate [duplicate]

This question already has an answer here:
How to use cucumber table when it is code driven
(1 answer)
Closed 1 year ago.
I am new to Karate API, pardon me for the mistakes if any.
I want to generate multiple random UUID and then use them in scenario outline examples
Example:
Background:
def UUID = function() {return java.util.UUID.randomUUID() + ''}
Scenario outline: to do post call
Given url 'http://localhost:8080'
def UID = UUID()
print UID
And request {CID:"", name :""}
When method POST
Then status 201
Examples:
|CID| name|
|UID1| james|
|UID2| rahul|
Here in above 'Examples' I wanted to use randomly generated UUID in data table of examples so that I can run multiple scenarios for UUID with one POST API call.
First question: How can I generate multiple random UUID ?
Second question: once multiple UUID gets generated how can i call in scenario outline examples and use them?
Can anyone suggest me on this?
Please try running the following simple example.
Feature:
Background:
* def uuid = function(){ return java.util.UUID.randomUUID() + '' }
Scenario Outline:
* url 'https://httpbin.org/anything'
* param foo = uuid()
* request { item: '#(item)' }
* method post
Examples:
| item |
| first |
| second |
It will make 2 requests, and each request will use a different param called "foo" and the URL will be like this:
https://httpbin.org/anything?foo=c1b6ab3d-5952-413b-827c-d9579a0a93b6
So it is simple. Think of the Examples: as like a "loop". Each time the Scenario Outline runs, we are calling the uuid() function again, which will return a different, random value.

Headers modification using Karate [duplicate]

This question already has an answer here:
Karate: Is there a way to pass variable as string in scenario outline and examples table [duplicate]
(1 answer)
Closed 1 year ago.
I am running API execution using Scenario Outline and csv and want to edit header in the below format where i need to change the requestorid each and every time for the execution.
If the headers uses below format and saved in .js and tried saving it in .json file:
"ID-HEADERS" :"{ 'requestorId': '1111', 'authMethod': 'basic'}"
And used below lines to edit the header which is not working:
function() {
var fun = karate.read(headersFilePath + 'headers.js');
var res = fun();
res['ID-HEADERS.requestorId'] = requestorId;
return res;
}
If you just need to set one header don't complicate it with JS:
Scenario Outline:
* url 'https://httpbin.org/anything'
* header foo = bar
* method get
Examples:
| bar |
| one |
| two |
Try it, and see the logs and HTML report. And read the documentation also.

How could response be checked conditionally? [duplicate]

This question already has an answer here:
Check 2 differents status with Karate
(1 answer)
Closed 1 year ago.
I'm doing data driven test with Karate, and met a block issue. The REST API response body is in different structure with different status. For example, when the status is 200, the response body is JSON array. When the status is 4** and 5***, the response body either is string or blank. I hope to check the response conditionally using the blow code. But seems it doesn't work.
"* eval if (verInfo.statusCode == 200) (match each response contains any verInfo.respBody) //verInfo.statusCode and verInfo.respBody is from the test data(DDT)
* eval if (verInfo.statusCode != 200) match response contains verInfo.respBody"
First, you cannot mix Karate script and JavaScript like this.
Second I suggest you use the responseStatus built-in variable. I also suggest using proper data-driven approaches instead of over-engineering your tests with conditional logic.
So you can do this, (and there are many other ways if you go through the docs and examples):
Scenario Outline:
Given url 'http://foo.bar'
And request <req>
When method post
Then match responseStatus == <code>
And match response == <body>
Examples:
| req | code | body |
| 'a' | 200 | 'foo' |
| 'b' | 400 | '' |