How to use OR operator with contains to assert/ match in Karate [duplicate] - karate

I am trying to use a match contains to verify my schema response and data types and sometimes it returns a null and sometimes it will return a string, as an example. I am trying the following but I am getting the assertion failed because it did not evaluate to true.
I am trying the following:
* match each $response.data.Results contains
"""
{
"providerID": '#number',
"firstName": "#? _ == '#string' || _ == '#null'",
"lastName": '#string',
"mI": "#? _ == '#string' || _ == '#null'",
"title": '#string',
"name": '#string',
"nameLFMT": '#string',
"status": '#string',
"specialties": '#array',
"locations": '#array',
"institutions": '#array',
"acceptNewPatient": '#string',
"imageUri": '#string',
"nearestLatitude": '#number',
"nearestLongitude": '#number'
}
"""
The data returned for "firstName" for example is "firstName":null,
Prior to the match each I am sending this:
Scenario: SearchResults
#Verify 200 response status returned
Given text query =
"""
{
Results: getSearchResults(searchLatitude:"48.942833",
searchLongitude: "-119.984549",
providerType: "Primary Care Physicians",
sortBy: "distance",
maxDistance:"600",
skip: 0,
take: 10) {
providerID
firstName
lastName
mI
title
name
nameLFMT
status
specialties
locations
institutions
acceptNewPatient
imageUri
nearestLatitude
nearestLongitude
}
}
"""
And request { query: '#(query)' }
When method post
Then status 200
I am not defining the schema, I have yet to figure out how to do this so I am not sure if that is my issue. I know this is probably how I should do this but I'm still learning.
Thanks for any help.

Ok I see one problem here:
"firstName": "#? _ == '#string' || _ == '#null'"
That's not going to work. The part that follows the #? has to be a valid JavaScript expression. This may be hard to understand if you are not familiar with JS but #string and friends are specific to the Karate match keyword and not something that works in JavaScript.
So what the above line is doing is checking if the value of firstName is equal to the literal string #string.
Fortunately Karate has a solution: (refer doc for 'fuzzy matching'):
"firstName": "##string"
Which is a convenience, the double ## means 'optional' that will match for both a string or null.
EDIT: for advanced cases, please read this: https://stackoverflow.com/a/50350442/143475

Related

In Karate, how can I assert that an array does not contain a matching string?

Let's say I'm writing a Karate test for a service whose response might look like tha following...
{
"messages": [
"The blurfl is wop",
"The zog is ipfy",
"The wuxhat is neet"
]
}
Is there some syntax for match to assert that none of those messages starts with "The baz "? Or is there a more gereral way to test that in Karate?
This worked for me:
* def response =
"""
{
"messages": [
"The blurfl is wop",
"The zog is ipfy",
"The wuxhat is neet"
]
}
"""
* match each response.messages != '#regex ^The baz .+'
You could also do this:
* match each response.messages == "#? !_.startsWith('The baz ')"
And for completeness:
* def filtered = response.messages.filter(x => x.startsWith('The baz '))
* assert filtered.length == 0

Is there a way to use as an optional field a json array value inside the payload? Karate DSL [duplicate]

This question already has an answer here:
Optional field in JSON response
(1 answer)
Closed 1 year ago.
I'm starting to use Karate DSL for API testing. I've used before to do some basic tests.
I'm kind of mixing a dynamic data driven test, so I've read the documentacion and usages for this. I'm using the standalone jar file. Now, the problem is that I'm trying to use a json file as shown below:
[
{
"name": null,
"type": "informational",
"description": "Poseidon was one of the Twelve Olympians in ancient Greek religion and myth, god of the sea, storms.",
"tags": null,
"myAuth": null
},
{
"name": "RegressionTestKarate-dsfdgfdgdfsgfdgsfdgfdsgfdsgsdfg",
"type": "transactional",
"description": null,
"tags": ["regression", "poseidon", "suite", "test"],
"myAuth": null
}
]
And in my *.feature, I'm using the data to send a request like this:
* def myJson = { name: "##(name)", type: '##(type)', description: '##(description)', tags: '##(tags)' }
Given url poseidonHostUrl
And path "v1/projects"
And request myJson
When method post
Then assert responseStatus == 400 || responseStatus == 401 || responseStatus == 403
So, when I run my script, the replacement for the tags array when is not null is not as expected. It literally takes the following value: [...] "tags": "##(tags)".
Thanks!
As the above example shows your tags data is an array or null so you should try this as
* def myJson = { name: '##(name)', type: '##(type)', description: '##(description)', tags: '##[] #string' }
Given url poseidonHostUrl
And path "v1/projects"
And request myJson
When method post
Then assert responseStatus == 400 || responseStatus == 401 || responseStatus == 403

is it possible to extract the value of one of the key value pairs in request to be asserted

peter had provided me a solution to use karate 0.9.3 to apply assertion from examples
Trying to do some assertion from request, which will be present in response
i was wondering if it is possible to assert a value from request instead of full request.
**Background:**
* configure headers = read('classpath:merchantServiceheaders.js')
Given url MservUrl
And path 'XXXXXX'
And request Data
When method POST
Then status 200
And match response != null
And match $ contains {serviceName: 'XXXXX'Service', responseMessage:
'Success' }
And match each $.clauses..responseMessage == 'Success'
And match each $..predicate != null
And match each $..predicate == '#present'
And match each $..predicate == '#regex [^0-9]+[0-9]*$'
And match $..predicate contains Data.clauses.subject
Examples:
|Data! |
|'{"clauses":[{"subject":"XXXX","predicate":"999999"},
{"subject":"XXXXX","predicate":"99999"}]}'|
what i am trying to do is on the And match $..predicate contains Data.clauses.subject
is that possible?
Yes, it is very much possible if Data is defined as a variable. But note that $..predicate will always be a JSON array: https://github.com/intuit/karate#get-plus-index
If you want help, please create a proper simple working example.
Sample Code:
Feature: Validation
Scenario:
* def resp = {predicate : "4325325456545646"}
* def data =
"""
{
"clauses": [
{
"subject": "5432154321543210",
"predicate": "4432154321543210"
},
{
"subject": "4325325456545646",
"predicate": "4325325456545646"
}
]
}
"""
* def sublist = get data.clauses[*].subject
* print sublist
* match sublist contains resp.predicate

How to validate Nested JSON Response

I am facing issue while validate Nested JSON response in API Testing using Karate Framework.
JSON Response:
Feed[
{ "item_type": "Cake" ,
"title": "Birthday Cake",
"Services":
[
{
"id": "1",
"name": {
"first_name": "Rahul",
"last_name": "Goyal"
}
},
{
"id": "2",
"name":{
"first_name": "Hitendra",
"last_name": "garg"
}
}
]
},
{
"item_type":"Cycle",
"title": "used by"
},
{
"item_type": "College"
"dept":
[
{"branch": "EC"},
{"branch": "CSE"},
{"branch": "CIVIL"}
]
},
]
}
Now i need to validate response based on Item type. as we can see nested JSON is different for different item_type.
I have tried with below solution
Schema Design for Item_type value cake
def Feed_Cake_Service_name={first_name: '#string',last_name: '#string'}
def Feed_Cake_Services= {id: '#string',name:#(Feed_Cake_Service_name)}
def Feed_Cake={item_type:'#string',title: '#string',Services: '#[] Feed_Cake_Services'}
def Feed_Cake_Response= {Feed: '#[] Feed_Cake'}
Schema Design for item_type Cycle
def Feed_Cycle={item_type:'#string',title:'#string'}
Schema Design for item type College
def Feed_College_Dept_Branch={branch:'#string'}
def Feed_College={item_type:'#string',dept: '[] Feed_College_Dept_Branch'}
now if i want to verify only item type Cake then i have written match like below
match response contains Feed_Cake_Response
but here my test case is getting failed. because it is comparing for all item type.
so here i have two question
1.) How we can compare particular item type schema
2.) How we can include all item type in one match equation since any item type can come in JSON response , and i want to validate all
Thanks
I'll just give you one hint. For the rest, read the documentation please:
* def item = { item_type: '#string', title: '##string', dept: '##[]', Services: '##[]' }
* match each response == item

karate - how to match partial string of the field in response?

i have a json response as below where i just want to match the string "harry"
in autoComplete, id in autoCompleteAuthors
Response {"data": {
"autoComplete": [
"Harry Hole"
],
"autoCompleteAuthors": [
{
"id": "search_authors_harry martinson",
"title": "Harry Martinson",
"type": "Authors"
}
]
}
}
Please suggest how to perform this validations using contains?
i tried like below which is not working
* def autoComlete = get response.data.autoComplete[*]
* match autoComlete contains any 'harry'
you can use match each and #regex marker in karate,
Case sensitive matching
* match each $response.data.autoComplete == "#regex .*Harry.*"
Case in sensitive matching
* match each $response.data.autoComplete == "#regex (?i).*harry.*"
Hope this works for your need.
Edit:
As requested on comments to pass name
* def query = 'harry'
* match each $response.data.autoComplete == "#regex (?i).*" + query + ".*"