2

This question is resulting from a previous question here

Lets says our implemented server v1 and v2 response looks as follows

* def v1Response = { id: "1", name: "awesome" }
* def v2Response = { id: "2", name: "awesome", value: "karate" }

Similarly we define the client schema for v1 and v2 like as follows

* def v1Schema = { id: "#string", name: "#string }
* def v2Schema = { id: "#string", name: "#string, value: "#string" }

From the above given data, all I want is to test following three cases in a single generic line and they must pass

1. * match v1Response == v1Schema
2. * match v2Response == v2Schema 
3. * match v2Response contains v1Schema

using a single generic line as follows

* match response ==/contains schema <--- should be able to test all above three cases above and they must pass. 

See my proposed suggestion in previous question for maybe possible ways to achieve this.

I have already tried the solution noted in previous question using karate.filterKeys(), however the third case will fail because it focuses on filtering the keys not the comparison itself so the below last line will not be able to test all three cases above.

* def response = { id: "2", name: "awesome", value: "karate" } 
* def schema = { id: "#string", name: "#string" } 
* match response == karate.filterKeys(schema, response) <--- This will fail

For an accepted answer all three case must pass

Dixie
  • 81
  • 1
  • 1
  • 7

1 Answers1

3

Looks like you over-engineered so much you forgot about contains :P

* def schemas =
"""
{
  v1: { id: "#string", name: "#string" },
  v2: { id: "#string", name: "#string", value: "#string" }
}
"""

* def env = 'v1'
* def response = { id: "1", name: "awesome" }
* match response contains karate.filterKeys(schemas[env], response)

* def response = { id: "2", name: "awesome", value: "karate" }
* match response contains karate.filterKeys(schemas[env], response)

* def env = 'v2'
* def response = { id: "1", name: "awesome" }
* match response contains karate.filterKeys(schemas[env], response)

* def response = { id: "2", name: "awesome", value: "karate" }
* match response contains karate.filterKeys(schemas[env], response)
Peter Thomas
  • 54,465
  • 21
  • 84
  • 248
  • Note 1st and 2nd cases are being matched using "==" not "contains" so your suggested solution is not on point (I could just use contains to pass all three but that is not what I am looking for). If we cannot do it then I will have to maintain two separate branches with only difference being of "==" vs "contains" between them. The notion to match using "==" is to find early bugs/extra keys during development and later when moved to production we can use contains for matching. Maybe karate's simplicity has given high hopes here :) is it too much of a ask to convince you on my proposed solution ? – Dixie Jul 29 '19 at 13:48
  • if you want "backwards compatibility" there is no better way, feel free to challenge using the above example and show how you would make the syntax work. `maintain two separate branches` - strongly disagree. I've provided enough options on how to handle different environments. you are the only one to ask for this in 2 and a half years, finally - karate is open source, so please contribute the fix if you feel so strongly about it :) – Peter Thomas Jul 29 '19 at 13:58
  • Not sure how others have been doing it all along but I feel this could be useful feature. However I could not think of any better solutions 1st Solution. Syntactically speaking this might be a challenge `* def equalsOrContains = ((client == server) ? 'response == schema' : 'response contains schema')` `* match equalsOrContains` 2nd Solution. Seems possible as long as we add 'eqOrCont' in enum in MatchType and later parse it out based on string val ? `* def eqOrCont = 'contains' OR '=='` `* match response eqOrCont schema` Sorry, if suggestions are invalid due to limited knowledge. – Dixie Jul 29 '19 at 19:11
  • 1
    @Dixie I freely admit that I can't understand all that above. I'll suggest one trick with I've seen a team use. you have two feature files, one like `* match lhs == rhs` and another `* match lhs contains rhs` and you can use conditional logic to call either one at run time. this will 100% solve for what you have been asking for all along. all the best ! https://github.com/intuit/karate#conditional-logic – Peter Thomas Jul 29 '19 at 19:30