imbo / behat-api-extension

API extension for Behat, used to ease testing of JSON-based APIs
MIT License
109 stars 42 forks source link

Support JSONPath expression syntax #44

Open oqq opened 7 years ago

oqq commented 7 years ago

Hi @christeredvartsen!

Your current implementation for json tests are not really flexible. I would recommend another approach for a test expression.

How about a new behavior like @Then JSONPath :path in response contains :value, where :path got resolved by something like https://github.com/FlowCommunications/JSONPath and the value could be any scalar value or one of your @function expressions.

christeredvartsen commented 7 years ago

I have a local branch that does exactly that. I haven't added anything regarding that to #39, but will consider it. So it will be added to either 2.0 or 2.1.

christeredvartsen commented 7 years ago

Do you have any experience with mtdowling/jmespath.php? That seems to be somewhat more stable than flow/jsonpath (at least wrt version numbers) and has a bunch more downloads.

oqq commented 7 years ago

To be honest I have only experience with jmespath.php and would prefer it for the same reasons.

christeredvartsen commented 7 years ago

I have finally started working on this, and have currently come up with two possible steps:

Then the :expression expression in the response body JSON matches :value

and

Then the :expression expression in the response body JSON matches: <PyStringNode>

The first does a simple value matching using Assert\Assertion::eq, while the second uses Assert\Asseriton::same, and decodes the value of the <PyStringNode> as JSON before doing the match.

Are you still interested in this functionality @oqq? If so, do you have anything to add to the above?

oqq commented 7 years ago

Of curse I am!

Maybe a test with Assertion::same would fail, since the response string is not exactly the same for a json string.

I would like to a test against json data type (string, number, object, area, boolean and null). Also a test against existent or lacking paths/values.

christeredvartsen commented 6 years ago

Perhaps sending the data through to the array comparator would work better. Then one could use the matcher functions against the data found by the expression.