While I have not looked at contains any in a while, I do have tests setup, as mentioned in the documentation, https://github.com/karatelabs/karate#match-contains-any, with the original values ... contains any... options
in my assertions, but in working on my current flow, I am seeing that I have to place the options first. Was this a recent change?
lines 42 and 43 show the options listed first and passing, while lines 45 and 46 show the method listed in the documentation failing
I also tired response versus $ and see the same results
Did something change that would affect the order of the match?
Code samples added for troubleshooting as requested:
Feature: Match Testing
Background: Setup Info
* url "https://swapi.dev/api/"
* def namesEnumeration = [ "Luke Skywalker", "Darth Vader", "Beru Whitesun lars", "R5-D4", "Obi-Wan Kenobi" ]
* configure continueOnStepFailure = true
# matches defined for the response object - https://github.com/karatelabs/karate#response
# the three lines below are equivalent
# Then match response.name == 'Billie'
# Then match response $.name == 'Billie'
# Then match $.name == 'Billie' - this example shows the $.name on the left side so unclear on why these tests all fail
# this also contradicts or is convoluted by the following statement a little lower in the same reposne object
# There is no need to prefix variable names with $ on the left-hand-side of match statements because it is implied.
# You can if you want to, but since only JsonPath (on variables) is allowed here, Karate ignores the $ and looks only at the variable name.
# None of the examples in the documentation use the $varName form on the LHS, and this is the recommended best-practice.
# Maybe a distinction between the response short-cut and the $variable reference could clarify
Scenario: Match Testing as variable - method 1 - everything defined as a variable
# match contains any reference - https://github.com/karatelabs/karate#match-contains-any
Given path 'people'
When method GET
Then status 200
* def names = $.results[*].name
* print "Current names from variable are available are: ", names
* match names contains any namesEnumeration
* def matchResult = karate.match("names contains any namesEnumeration")
* print "matchResult is - ", matchResult
* match namesEnumeration contains any names
* def matchResult = karate.match("namesEnumeration contains any names")
* print "matchResult is - ", matchResult
Scenario: Match Testing with response as defined variable - attempt 2 - Issue scenario 1
Given path 'people'
When method GET
Then status 200
* def responseObj = $
* print "Current response from variable are available is: ", responseObj
* match responseObj.results[*].name contains any namesEnumeration
* def matchResult = karate.match("responseObj.results[*].name contains any namesEnumeration")
* print "matchResult is - ", matchResult
# The following do not work due to the RH side containing "[*]"
* match namesEnumeration contains any responseObj.results[*].name
* def matchResult = karate.match("namesEnumeration contains any responseObj.results[*].name")
* print "matchResult is - ", matchResult
Scenario: Match Testing with response defined in karate.jsonPath and karate.get functions - attempt 3
# methods implemented per https://stackoverflow.com/questions/71749751/karate-cant-print-values-from-the-response-array-of-json-objects
# unsure why we would need to use karate.jsonPath if the response value is already pure jsonPath
# As a short-cut, when running JsonPath expressions - $ represents the response. This has the advantage that you can use pure JsonPath and be more concise.
Given path 'people'
When method GET
Then status 200
* print karate.jsonPath(response, '$.results[*].name')
* match karate.jsonPath(response, '$.results[*].name') contains any namesEnumeration
* def matchResult = karate.match("karate.jsonPath(response, '$.results[*].name') contains any namesEnumeration")
* print "matchResult is - ", matchResult
* match namesEnumeration contains any karate.jsonPath(response, '$.results[*].name')
* def matchResult = karate.match("namesEnumeration contains any karate.jsonPath(response, '$.results[*].name')")
* print "matchResult is - ", matchResult
* print karate.get('$.results[*].name')
* match karate.get('$.results[*].name') contains any namesEnumeration
* def matchResult = karate.match("karate.get('$.results[*].name') contains any namesEnumeration")
* print "matchResult is - ", matchResult
* match namesEnumeration contains any karate.get('$.results[*].name')
* def matchResult = karate.match("namesEnumeration contains any karate.get('$.results[*].name')")
* print "matchResult is - ", matchResult
Scenario: Match Testing with built in JSON response variable - attempt 4 - Issue scenario 2
Given path 'people'
When method GET
Then status 200
# Based on your comment here - https://stackoverflow.com/questions/62869540/printing-database-query-response-as-json-array-list-in-karate
# when you see a * or .. it is JsonPath
# This explains why the following line does not work since it is not a js object
# * print "Current names from response are available are: ", response.results[*].name
* match $.results[*].name contains any [ "Luke Skywalker", "Darth Vader", "Beru Whitesun lars", "R5-D4", "Obi-Wan Kenobi" ]
* def matchResult = karate.match("$.results[*].name contains any namesEnumeration")
* print "matchResult is - ", matchResult
* match namesEnumeration contains any $.results[*].name
* def matchResult = karate.match("namesEnumeration contains any $.results[*].name")
* print "matchResult is - ", matchResult
* match $.results[?(@.height == "172")].name contains any [ "Luke Skywalker", "Darth Vader", "Beru Whitesun lars", "R5-D4", "Obi-Wan Kenobi" ]
# * def matchResult = karate.match("$.results[?(@.height == "172")].name contains any namesEnumeration")
# * print "matchResult is - ", matchResult
# had to declare as variable because placing the jsonPath with a condition, in the LH side of the match checks results in error that stops further evaluations
* def jsonPart = $.results[?(@.height == "172")].name
* print "jsonPart is - ", jsonPart
* match jsonPart contains any [ "Luke Skywalker", "Darth Vader", "Beru Whitesun lars", "R5-D4", "Obi-Wan Kenobi" ]
* def matchResult = karate.match("jsonPart contains any namesEnumeration")
* print "matchResult is - ", matchResult
* match namesEnumeration contains any $.results[?(@.height == '172')].name
* def matchResult = karate.match("namesEnumeration contains any $.results[?(@.height == '172')].name")
* print "matchResult is - ", matchResult
Scenario: Match Testing with built in JSON response variable - attempt 5 - Issue scenario 3
# example of match with response on the left side - https://stackoverflow.com/questions/73530906/karate-test-framework-how-to-check-presence-of-parameter-in-response/73545783#73545783
Given path 'people/1'
When method GET
Then status 200
* print "Current response name is: ", response.name
* match response.name == [ "Luke Skywalker", "Darth Vader", "Beru Whitesun lars", "R5-D4", "Obi-Wan Kenobi" ]
* match response.name contains [ "Luke Skywalker", "Darth Vader", "Beru Whitesun lars", "R5-D4", "Obi-Wan Kenobi" ]
* match response.name contains any [ "Luke Skywalker", "Darth Vader", "Beru Whitesun lars", "R5-D4", "Obi-Wan Kenobi" ]
########################
# Summary
########################
# since actual is typically on the left, and expected on the right, per documentation, changing the actual to the RH seems
# a little confusing when other review the scenarios and assertions.
# something like the following might be a solution to eliminate the confusion as this topic appears to have come up before
# * match response.name isIncludeIn [ "Luke Skywalker", "Darth Vader", "Beru Whitesun lars", "R5-D4", "Obi-Wan Kenobi" ]
# * match response.name isPartOf [ "Luke Skywalker", "Darth Vader", "Beru Whitesun lars", "R5-D4", "Obi-Wan Kenobi" ]
# * match response.name isListedIn [ "Luke Skywalker", "Darth Vader", "Beru Whitesun lars", "R5-D4", "Obi-Wan Kenobi" ]