I am trying to validate the below conditions in the sample response
Based on subjectType attribute if it is either Person or Organization.
If subjectType is Person, check if it has a birthDate attribute
Sample response:
{
"subject": "ABC",
"subjectType": "Person",
"birthDate": "1951-03-07"
},
{
"subject": "ABC",
"subjectType": "Organization"
}
I tried this, but no luck.
def expected = {subjectType: 'Person', birthDate: '#present'}
def schema = { subjectType: '#? _ == "Person" || _ == "Organization"', birthDate: '#($.subjectType == "Person" ? "#present" : "#present")' }
match expected == schema
Any help is appreciated!
There are many answers that give you solutions, please start here:
https://stackoverflow.com/a/50350442/143475
Since I just came up with a new idea to solve this, I'm posting it below. Note that there is no right answer, and there are many, many ways to do what you want.
* def schemas =
"""
{
Person: { subject: '#string', subjectType: 'Person', birthDate: '#string' },
Organization: { subject: '#string', subjectType: 'Organization' }
}
"""
* def response = { "subject": "ABC", "subjectType": "Person", "birthDate": "1951-03-07" }
* def expected = schemas[response.subjectType]
* match response == expected
Also search slack overflow if you want to validate dates later.
Related
I have an endpoint with the following response:
{
"id": 1,
"status": "ACTIVE"
}
The possible values for status are the following: ACTIVE, INACTIVE, DELETED.
To check the schema I tried the following:
* def statusValues = ["ACTIVE", "INACTIVE", "DELETED" ]
* def schema =
"""
{
"id" : #number,
"status" : '#(^*statusValues)'
}
"""
And to validate I use the following sentence:
Then match response == schema
But it doesn't work. This is the error
actual: 'ACTIVE', expected: ["DELETED","ACTIVE","INACTIVE"], reason:
actual value is not list-like
Can you help me, please?
This is probably the simplest option:
* def isValidStatus = function(x){ return statusValues.contains(x) }
* def schema = { id: '#number', status: '#? isValidStatus(_)' }
I have a un-named JSON array like this from the response and would like to check whether it contains "confirmationNumber": "pqrs" or not. May I know how can I check that in Karate?
[
{
"id": 145,
"confirmationNumber": "abcd"
},{
"id": 723
"confirmationNumber": "pqrs"
}
,{
"id": 7342
"confirmationNumber": "sfeq"
}
]
karate.filter() is good for these situations:
* def response =
"""
[
{
"id":145,
"confirmationNumber":"abcd"
},
{
"id":723,
"confirmationNumber":"pqrs"
},
{
"id":7342,
"confirmationNumber":"sfeq"
}
]
"""
* def fun = function(x){ return x.confirmationNumber == 'pqrs' }
* def found = karate.filter(response, fun)
* match found == '#[1]'
Also see examples of JsonPath: https://github.com/intuit/karate#jsonpath-filters
EDIT: apologies, there is a much simpler way, please read the docs !
* match response contains { id: '#number', confirmationNumber: 'pqrs' }
* def item = { confirmationNumber: 'pqrs' }
* match response contains '#(^item)'
Sample Response
{
"data": [
{
"name": "DJ",
"status": "ACTIVE"
}
]
}
Sample Feature File
#ignore
Feature: Sample
#smoke
Scenario: Karate expression to check if value exists in array
Given url url
And path '/test'
When method GET
Then status 200
And def users = response.data
And def possibleStatus = ["ACTIVE", "INACTIVE"]
And def schema =
"""
{
name: '#string',
status: ?
}
"""
And match each users contains schema
Is there a way to check if status is either ACTIVE or INACTIVE using karate expression ?
NOTE: It can be achieved by writing custom JS function.
* def statuses = [ 'ACTIVE', 'INACTIVE' ]
* def response = [{ name: 'DJ', status: 'ACTIVE' }, { name: 'PJ', status: 'INACTIVE' }]
* match each response == { name: '#string', status: '#? statuses.contains(_)' }
I am trying to assert that a key is not in the JSON response. This is the response
{
"_type": "UserAccount",
"accountName": "Account_Name",
"accountType": "regular",
"whiteList": true,
"sfAccountId": "1",
"preferredLanguage": "english",
"imageSize": "highRes",
"_id": "775a8451-6a07-42da-a199-fe98f44bdc06"
}
I have tried both of these steps according to the documentation karate#null-and-notpresent and this answer from Peter Thomas
And match response.appClientId == '#notpresent'
And match response == {appClientId:'#notpresent'}
However this is the error I keep getting for the first step above
com.jayway.jsonpath.PathNotFoundException: No results for path: $['appClientId']
and for the second step
com.intuit.karate.KarateException: path: $, actual
Thanks in advance
Maybe your version is out of date, the below works for me in 0.9.1:
* def response =
"""
{
"_type": "UserAccount",
"accountName": "Account_Name",
"accountType": "regular",
"whiteList": true,
"sfAccountId": "1",
"preferredLanguage": "english",
"imageSize": "highRes",
"_id": "775a8451-6a07-42da-a199-fe98f44bdc06"
}
"""
* match response.appClientId == '#notpresent'
* match response contains { appClientId: '#notpresent' }
This question already has an answer here:
Karate Tests: How to match contains each nested array response with just one schema
(1 answer)
Closed 1 year ago.
Assume that I have a response-Json look like below
def resJson =
"""
{
"id": 1,
"code": "OU82883",
"features":
[
{
"id": 12,
"class": "OU8811",
"school": "parent",
"course": "abc",
"sortOrder": 123
}
]
}
"""
To be easily manage file to compare, I am placing the expected schema - expected result in a file ("getCourseDetails.txt"), with structure below
{
id: '#number',
code: '#string',
features: ##[{
id: '#number',
class: '##string',
school: '##string',
course: '##string',
sortOrder: '#number'
}
]
}
Then in executed feature file, perform the code as
* json expSchema= read ('../Data/Schema/getCourseDetails.txt')
* match resJson == expSchema
The system informs AssertionFailed Error
To find another way to validate schema, I kept only the structure inside of "features" in "getCourseDetails". The outside of "features", I put into executed feature file. So my code now is:
GetCourseDetails file:
{
id: '#number',
class: '##string',
school: '##string',
course: '##string',
sortOrder: '#number'
}
Feature file:
* json courseDetails= read ('../Data/Schema/getCourseDetails.txt')
* def expSchema = {id: '#number', code: '#string', features: '##[] courseDetails'}
* match resJson == expSchema
There is no error and validate works well, but this approach is not my expected.
I would like to know is there a way to centralize all things in a file, and user just calls the file to validate against actual response's schema
Thank you so much.
I think you are over-engineering your tests, but you can use JS to do advanced set-up and building the schema the way you want, and it will be re-usable. For example:
first.json:
{ "foo": "#string" }
second.json:
{ "value": "#number" }
schema.js:
function() {
var first = read('first.json');
karate.set('second', read('second.json'));
first.bar = '##[] second';
return first;
}
now your feature file can be:
* def schema = call read('schema.js')
* def response = { foo: 'test', bar: [{value: 1}, {value: 2}] }
* match response == schema
Above, if you * print schema you will see:
{
"foo": "#string",
"bar": "##[] second"
}
And if you want a one-liner - * match response == call read('schema.js') should work !