How could response be checked conditionally? [duplicate] - karate

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 | '' |

Related

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.

Forcing a null value as a parameter does not get included in the call [duplicate]

This question already has an answer here:
The json key is not being omitted where the cells are empty in examples of Scenario Outline .What change needs to be done?
(1 answer)
Closed 1 year ago.
I read in the Karate documentation that if one uses "null", it will result in the key being omitted from the call. However, if one still wants to force a null, they could wrap it in parentheses like: "(null)".
It does go through with the key. However, on the actual call, the key is still omitted from the parameters. How can I force it there as well? Is it LITERALLY the same thing as an empty string?
I.e:
| Environment| Application| Version | status |
| Environment| Application| (null) | 401 |
call read....
Results:
{
"Environment": "Environment",
"Application": "Application",
"Version": "null",
"status": 401
}
But the URL looks like:
GET https://?Environment=Environment&Application=Application
Please advise.
EDIT below for a better example:
In my "primary" file, I have the following:
* table requestTable
| q | um | ie | status |
| (null) | 1 | utf | 400 |
Where all three params (q, um, ie) are required parameters.
My "secondary" runner file, looks like the following:
* def requiredParams = { q: '#(q)', um: '#(um)', ie: '#(ie)'}
* def mainUrl = 'https://www.google.com'
* def apiPath = '/search'
Given url mainUrl
And path apiPath
And params requiredParams
When method GET
Then status 400
I am expecting a 400 since a required param is required. It doesn't get sent as "null", even if I use (null), it removes that field altogether in the actual call. This example obviously won't work in real life since I am using example google stuff. I apologize about that. If you still need a real life example, please show me how I can do it.
I assume that you are talking about Examples: but your question is incomplete.
Try this: https://github.com/karatelabs/karate#scenario-outline-enhancements
Examples:
| Version! |
| '' |

Karate- Good way to send custom headers with each request

I have a scenario where I am doing a GET call and on my table I have parameters defined. Now for the headers, I want to purposefully send incorrect values to make sure the test fails as expected. Not really sure how to do it though.
I have the following setup:
* table input
| machine | version | osSystem | status |
| machineName| version | windows | 401 |
My secondary file that the above calls on, looks like this:
Given url env
And path path
And header Content-Type = 'application/xml; charset=UTF-16'
And header Accept = '*/xml; charset=UTF-16'
And header key = key
When method GET
In above, I want to send bogus values for "key" header. Total of six bogus values (random alpha string, random number string, random alphanumerical value, random guid, etc). I have obviously tried entering the values as a json under "and header key = {}" but how do I make each request run EACH header per request, instead of running them all in one request?
Thank you in advance!
Try this example and observe how it works, it will answer all your questions:
Scenario Outline:
* url 'https://httpbin.org/anything'
* header foo = header
* method get
Examples:
| header |
| one |
| two |
And for an alternate way to "loop" refer to this answer: https://stackoverflow.com/a/69422451/143475

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

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

How to pass variable into the title of a scenario/scenario title in Karate framework

While using data-driven feature in Karate framework, I see the generated report just show the title as configured in Scenario Outline NOT attached the value using in Example table. It causes the Tester confuse which data is using, and take time to expand each scenarios to know which data is using; so I want the report can pass variable into the title - Scenario/Scenario Outline. Please take a look at the example below.
E.g.
Feature: Login Feature
Background:
* configure headers = { 'Webapp-Version': '1.0.0'}
Scenario Outline: As a <description> user, I want to get the corresponding response_code <status_code>
Given def path = 'classpath:features/Authentication/authentication.feature'
And def signIn = call read(path) {username: '<username>', password: '1234567890'}
Then match signIn.status == <status_code>
Examples:
|username | status_code| description |
|test#gmail.com | 200 | valid user |
|null | 400 | invalid user|
My expected result, the generated report should fill the value on table for field "status code" and "description" fields.
-> As a valid user user, I want to get the corresponding response_code 200.
Please share your ideas and comments on it.
Thanks,
Learn.
Not supported. Just use the print syntax and you will see it in the report.
EDIT: okay this will be possible in the next version: https://github.com/intuit/karate/issues/553