If examples has too many columns ,every row will be too long to read! - karate

If examples has too many columns ,every row will be too long to read!
Feature:
Background:
Scenario Outline:
* match '<msg>' == <prefix> + ',' + '<end>'
Examples:
| prefix | end | msg |
| hello | mike | hello,mike |
| hello | jerry | hello,jerry |
Could it be like that:
Feature:
Background:
Examples:
| prefix |
| hello |
Scenario Outline:
* match '<msg>' == <prefix> + ',' + '<end>'
Examples:
| end | msg |
| mike | hello,mike |
| jerry | hello,jerry |
I want to divide the examples in several parts, or set a base examples before Outline.What should I do?

karate address this in many different ways in its latest versions 0.9.X, Let see
As you asked we can define the Examples: tables before Scenario Outline: using table in karate,
Feature: my feature
Background: BG
* table myExample
| prefix | end | msg |
| 'hello' | 'mike' | 'hello,mike' |
| 'hello' | 'jerry' | 'hello,jerry' |
Scenario Outline: SOW
* match '<msg>' == '<prefix>' + ',' + '<end>'
Examples:
| myExample |
the same can be kept in another feature file and read it in this feature file, but don't complicate as we have some other solutions coming below..
2.karate sees all these table, Examples: as array of JSON's
typically you example above will be represented as,
[
{
"prefix": "hello",
"end": "mike",
"msg": "hello,mike"
},
{
"prefix": "hello",
"end": "jerry",
"msg": "hello,jerry"
}
]
so karate allows you to define these Examples also from JSON or csv formats using karate's dynamic scenario outline feature
if you feel like you examples are too large to accommodate in your feature file keep it in a csv file and do read in your Examples
Feature: my feature
Background: BG
* def myExample = read("myExample.csv")
Scenario Outline: SOW
* match '<msg>' == '<prefix>' + ',' + '<end>'
Examples:
| myExample |
The same applies to JSON also, providing data as JSON array.

Related

Karate: is it possible to match the json from scenario outline

My use case is to have a Scenario Outline implemented with examples and my small Api returns a json output which I want to parameterize.
My use case is something like
Scenario Outline : test
Given url "http://myurl.com"
And params {"id": "<id>"}
When method get
Then match response == "<schema>"
Examples:
| id | schema |
| 123 | {"id":"#present"} |
| 456 | {"id":"#present", "name":"test"} |
| 789 | {"id": "#present", "value":"#present"} |
The problem her is examples are taken as string so the match fails here with error: as it is trying to now compare the response
{"id":"#present"} with "{"id":"#present"}" and fails
Any way to case it back to json when reading from examples.
Help would be appreciated.
Thank you
Add a ! after the column name. Refer: https://github.com/intuit/karate#scenario-outline-enhancements
Scenario Outline : test
Given url "http://myurl.com"
And params {"id": "#(id)"}
When method get
Then match response == schema
Examples:
| id! | schema! |
| 123 | {"id":"#present"} |
| 456 | {"id":"#present", "name":"test"} |
| 789 | {"id": "#present", "value":"#present"} |

Is there a way to add a nested json value from Scenario Outline Examples and have it format the JSON properly [duplicate]

This question already has an answer here:
How to compare 2 JSON objects that contains array using Karate tool and feature files
(1 answer)
Closed 1 year ago.
Here is my script:
Scenario Outline: Test
* def body = {}
* set body
| path | value |
| name | <name> |
| metadata.<key> | <value> |
Given url 'http://localhost/'
* request body
When method post
Examples:
| name | key | value |
| 'John' | 'key1' | 'value1' |
| 'Jane' | | |
When I post the request I get the body as:
{"name": "John", "metadata": {"'key1'": "value1"}}
How do I get the metadata.key to be "key1"?
It is simpler than you think:
Scenario Outline: Test
* def body = { name: '#(name)' }
* body[key] = value
* print body
Examples:
| name | key | value |
| John | key1 | value1 |
| Jane | key2 | value2 |
Also refer: https://github.com/intuit/karate#scenario-outline-enhancements
EDIT: if you really have wildly different payloads in each row, I personally recommend you create a separate Scenario - in my opinion, trying to squeeze everything into a single super-generic-dynamic Scenario just leads to readability and maintainability issues, refer: https://stackoverflow.com/a/54126724/143475
That said, you can do this:
Scenario Outline: Test
* print body
Examples:
| body! |
| { "name": "John", "metadata": { "key1": "value1" } } |
| { "name": "Jane" } |
There are "smart" ways to remove some parts of a JSON like this: https://github.com/intuit/karate#remove-if-null - but you can choose which approach is simpler.

The json key is not being omitted where the cells are empty in examples of Scenario Outline .What change needs to be done?

The following is the scenario Outline i have used . In the first and second row the display_name is empty but still display_name is being sent in my request payload .
Scenario Outline: Negative cases
Given path '/api/check'
And request {name: <name> , description: <description> , display_name: <display_name>}
When method POST
Then status <status>
Examples:
| name | description | display_name |status |
|"" | "sasadss" | | 400 |
|"fddsd" | "" | | 400 |
| "ccs" | "" | "disp " | 400 |
Unfortuately Cucumber Example tables send an empty string. You can use table as an alternative or you can put the whole JSON into a column, many teams do this.
| value |
| { some: 'json' } |
Refer to this example: https://github.com/intuit/karate/blob/master/karate-demo/src/test/java/demo/outline/examples.feature

How to automate an API which takes different combinations of query params and gives corresponding result (Using Karate)

I have a versatile get API which takes multiple query params and gives a corresponding response for each combination of query params. The set of combinations is defined. I need to automate the API so that each case is covered and the response is verified using Karate. I wish to use minimum number of feature files. Please suggest a way to go about it.
You should really read the docs and look at the demos and save yourself a lot of time.
Note that you can use the params keyword for this use-case, and null values will be ignored (no query param will be set).
Scenario Outline:
* def query = { name: <name>, country: <country>, active: <active>, limit: <limit> }
Given path 'search'
And params query
When method get
Then status 200
# response should NOT contain a key expected to be missing
And match response !contains <missing>
# observe how strings are enclosed in quotes, and we set null-s here below
# and you can get creative by stuffing json into table cells !
Examples:
| name | country | active | limit | missing |
| 'foo' | 'IN' | true | 1 | {} |
| 'bar' | null | null | 5 | { country: '#notnull', active: '#notnull' } |
| 'baz' | 'JP' | null | null | { active: '#notnull', limit: '#notnull' } |
| null | 'US' | null | 3 | { name: '#notnull', active: '#notnull' } |
| null | null | false | null | { name: '#notnull', country: '#notnull', limit: '#notnull' } |

how can I retrieve records that include *all* in a list, as opposed to *any*?

I have a table, "posts" like so:
+----+---------+------------+
| id | author | text |
+----+---------+------------+
| 1 | bob | hello |
| 2 | jim | hi bob |
+----+---------+------------+
and also "tags" like so:
+----+--------------+
| id | name |
+----+--------------+
| 1 | bugs |
| 2 | project_foo |
| 3 | project_bar |
+----+--------------+
and lastly "post_tags" like:
+------+------+
| post | tag |
+------+------+
| 1 | 1 |
| 1 | 2 |
| 2 | 1 |
| 2 | 3 |
+------+------+
Posts are tagged with any number of tags. With the above data, what is the best way for me to query "give me the posts that have ALL tags in the list (1,2)"? These would be the posts tagged as "bugs, project_foo"
A joined search with "IN" doesn't work for me as it is returning posts that match any of the listed tags, so I will receive "project_bar" bug posts as well even though they aren't even tagged as "project_foo". It would be completely fine to return posts that contain tags not in the specified list, given that the post at least has the tags mentioned. So "bugs, project_foo, project_bar" would be fine, but "bugs, project_bar" would not.
I would prefer to do this with normal ResultSet usage, but am comfortable doing in a custom ResultSource::View. Problem is, I can't figure out how to do this in raw sql either.
Is there a practical way to do what I am attempting, or is my table setup just wrong for what I am trying to achieve?
Thank you.
The SQL statement would be:
SELECT post
FROM post_tags
WHERE tag IN (1, 2)
GROUP BY post
HAVING COUNT(post) = 2
So something like the following should work with DBIx::Class:
my #tags = (1, 2);
$schema->resultset('PostTags')->search({
tag => { -in => \#tags },
}, {
columns => 'post',
group_by => 'post',
having => \[ 'COUNT(post) = ?', scalar(#tags) ],
});
This would only retrieve the post ids. You could try to add a join or prefetch to retrieve the post contents in a single statement.
I'd go with this query. It'd have a good performance but use it only if you can be sure you'll only need to check for only 2 values. If your requirements could expand to include a third or even fourth one then nwellnhof's answer is better:
SELECT post
FROM post_tags a
WHERE EXISTS (
SELECT 1 FROM post_tags b1
WHERE a.post = b1.post
AND b1.tag=1 )
AND EXISTS (
SELECT 1 FROM post_tags b2
WHERE a.post = b2.post
AND b2.tag=2 );