How to handle different response for the same request on Karate api testing? - api

I have a question about how to handle different responses for the same request in Karate api test. E.g.
The same request:
Given path '/tickets/2000'
When method get
Response:
1> if ticket #2000 is not expired, then match response = expected result
2> if ticket #2000 is expired, then matching response.error = 'Ticket is expired'
So how to match the 2 different results. I need to handle both.
Can I use "Try... Catch", how to use it? Can you give me a syntax example in Karate, please?
Thanks

Karate discourages "conditional logic" like this. What I would do is just set that field to #ignore or #string:
* match response == { error: '#string' }
For conditional checks, you can refer this answer: https://stackoverflow.com/a/50676868/143475
Also please refer this answer for some extra guidance: https://stackoverflow.com/a/54126724/143475

Related

Why karate dsl replace "space" for "+" in param

i have this code:
Scenario: Get Token
Given url 'https://localhost/api/accessToken'
And param scope = 'collections payments'
Log:
1 > POST https://localhost/api/accessToken?scope=collections+payments
This Post faild for me.
Please, i need this:
https://localhost/api/accessToken?scope=collections%20payments
Karate is doing the right thing and your server probably has a bug.
Refer: https://stackoverflow.com/a/1634293/143475
But if you want to send it the way you are asking, put it as the URL itself, and don't use param:
* url 'https://httpbin.org/anything?foo=one%20two'
* method get
Explained here: https://stackoverflow.com/a/59977660/143475

Karate : How to send query param without url encoding

I'm currently writing Automated REST API tests using Karate dsl and I'm encountering an issue when I try a kind of destructive test. Sending invalid query parameter.
I follow the recommendation from this post Karate: Query Param values are getting encoded who is to use the url only but it seems to not work with query parameter:
Scenario: Destructive testing - Illegal characters in parameters or payload
* def buildURL = 'http://127.0.0.1/identity/client?query={"idClient":{"$eq":9223372036854775807}}'
Given url buildURL
When method GET
Then status 400
error:
java.net.URISyntaxException: Illegal character in query at index 39: http://127.0.0.1/identity/client?query={"idClient":{"$eq":9223372036854775807}}
I have the same kind of test for url path where it works fine, but for query param, this way does not seems to work.
To be clear, my goal is to send query params or at least the character { without url encoding
Any idea to solve that ?
Thanks in advance
karate version : 0.9.6
First, you are trying illegal characters as per the spec, so you may need to manually "URL-encode" the URL - and you already seem to be aware of all this, based on the link in your question. Maybe your server is not compliant with the spec.
Recommend you try upgrading to 1.0 and also refer this open issue: https://github.com/intuit/karate/issues/1561
Anything beyond this will require you to help / contribute code.

Karate API Automation Tooling : Assert SOAP Response

SOAP responses are currently asserted from expected file.
Is there any way i exclude some fields which are dynamic ?
* def soap_response = read("expected.xml")
* match response == soap_response
assertion failed: path /soap:header /soap:time
Yes just use #ignore:
<foo>#ignore</foo>
Please read the docs: https://github.com/intuit/karate#ignore-or-validate

Declare Global variables in background of feature-karate Soap API

I am using karate for SOAP API services. How can I declare a global variable ?? as you can see in below feature file? after print response I have variable name def ourSession = /Envelope/Body/LoginReturn I am using this variable (ourSession) in next scenario but it's failing ? but it's not global.
So how can I declare "ourSession" as a global variable ?? so I can use into other scenarios?
Any help will be highly appreciated. Please have a look of my feature file below;
#
Feature:
SOAP calls to the following service:
Background:
* url baseUrl
* def configSS = Java.type('practice.utilities.Shellscripts')
##################################### LOG IN #########################################################
#DataAcquisition
Scenario: login
Given request
"""
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsh="http://www.informatica.com/wsh">
<soapenv:Header/>
<soapenv:Body>
<wsh:Login>
<RepositoryDomainName>Domain_Aqr_Dev_Powercenter</RepositoryDomainName>
<RepositoryName>Powercenter_Repository_Service</RepositoryName>
<UserName>#(AM_USERNAME)</UserName>
<Password>#(AM_PASSWORD)</Password>
<UserNameSpace/>
</wsh:Login>
</soapenv:Body>
</soapenv:Envelope>
"""
When soap action '/login'
Then assert responseStatus == 200
And print 'response: ', response
* def ourSession = /Envelope/Body/LoginReturn
* print ourSession
Do not create a new scenario for the subsequent call. A single scenario can have multiple requests.
i am using this variable (ourSession) in next scenario
You can't. There are many answers in Stack Overflow addressing this question, please find them and read them.
And please read the docs: https://github.com/intuit/karate#script-structure
To quote:
if you are expecting a variable in the Background to be modified by one Scenario so that later ones can see the updated value - that is not how you should think of them, and you should combine your 'flow' into one scenario.
There are many ways to "re-use" in Karate such as call. So you should be able to figure out how to do what you want.
Now if you really want a "global" variable, please use callonce that is most likely what you are looking for:

How to make more readable and shorter a karate scenario

I'm new in Karate Framework. I would like to write a scenario like here:
version 1 :
Background:
* url 'someURL'
* def user1 = {id:'123', name:'Bill'}
Given I have a user with id '123'
When I create a new user with the same id
Then I should get a response 'user with this id already exists'
But in Karate I have to write it like here:
version 2 :
Background:
* url 'someURL'
* def user1 = {id:'123', name:'Bill'}
Given request user1
When method post
Then status 201
Given path response.id
When method get
Then response == {id:'123', name:'Bill'}
* def idUser1 = response.id
Given request == {id: idUser1, name: 'Gary'}
When method post
Then response == {code: 400, message: 'user with this id already exists'}
How I can get the first version with Karate framework? where I have to detail the 3 lines? ex:
Given I have a user with id '123' and behind (I don't know where and how) detail it with
"Given request user1
When method post
Then status 201
Given path response.id
When method get"
Then response == {id:'123', name:'Bill'} etc.
I'm the author of Karate. If you want the first version, Karate is not for you. The first version is not useful unless you really really want your product-owner or business-analyst or someone non-technical to be able to read (or even create) your tests. In my experience, this never happens in practice.
Even if you decide to go down path 1, you will need to write lots and lots of Java code as Cucumber "Step Definitions". Which is a waste of time, and you will lose the benefit of Karate's detailed assertions, examples of which are given below:
I have more to say on this topic, but my thoughts are explained in detail in this blog post - Yes, Karate is not true BDD.
All the best with whichever option you choose :)