Permalink
2ddee33 Feb 10, 2018
1 contributor

Users who have contributed to this file

144 lines (119 sloc) 6.49 KB
Feature: dynamic params using scenario-outline, examples and json
see also the file demo/outline/examples.feature
Background:
* url demoBaseUrl
Scenario Outline: using a javascript function to pre-process the search parameters
this particular example has been deliberately over-complicated, the next scenario-outline below is simpler
* def query = { name: '<name>', country: '<country>', active: '<active>', limit: '<limit>' }
# all this function does is to set any empty string value to null, because that is what empty cells in 'Examples' become
* def nullify =
"""
function(o) {
for (var key in o) {
if (o[key] == '') o[key] = null;
}
return o;
}
"""
# here we load a java-script function from a re-usable file
* def getResponseParam = read('get-response-param.js')
* def query = nullify(query)
* print query
Given path 'search'
# the 'params' keyword takes json, and will ignore any key that has a null value
And params query
When method get
Then status 200
And assert getResponseParam('name') == query.name
And assert getResponseParam('country') == query.country
And assert getResponseParam('active') == query.active
And assert getResponseParam('limit') == query.limit
# response should NOT contain a key expected to be missing
And match response !contains { '<missing>': '#notnull' }
Examples:
| name | country | active | limit | missing |
| foo | IN | true | 1 | |
| bar | | | 5 | country |
| baz | JP | | | active |
| | US | | 3 | name |
| | | false | | limit |
Scenario Outline: here the parameters are set to null within the 'Examples' table itself
# notice how this is different from the above, the quotes come from the 'Examples' section
* def query = { name: <name>, country: <country>, active: <active>, limit: <limit> }
* print query
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' } |
Scenario: using a data-driven called feature instead of a scenario outline
this and the above example are the two fundamentally different ways of
data-driven test 'looping' in Karate
* table data
| name | country | active | limit | missing |
| 'foo' | 'IN' | true | 1 | [] |
| 'bar' | | | 5 | ['country', 'active'] |
| 'baz' | 'JP' | | | ['active', 'limit'] |
| | 'US' | | 3 | ['name', 'active'] |
| | | false | | ['name', 'country', 'limit'] |
# the assertions in the called feature use some js for the sake of demo
# but the next scenario below is far simpler and does not use js at all
* def result = call read('search-complex.feature') data
Scenario: using the set keyword to build json and nulls are skipped by default
this is possibly the simplest form of all the above, avoiding any javascript
but does require however - a 'call' to a second feature file
# table would have been sufficient below, but here we demo how 'set' is simply a 'transpose' of table
* set data
| path | 0 | 1 | 2 | 3 | 4 |
| name | 'foo' | 'bar' | 'baz' | | |
| country | 'IN' | | 'JP' | 'US' | |
| active | true | | | | false |
| limit | 1 | 5 | | 3 | |
# note how you can 'compose' complex JSON by referring to existing JSON chunks, e.g: 'data[0]'
* table search
| params | expected | missing |
| data[0] | { name: '#[1]', country: '#[1]', active: '#[1]', limit: '#[1]' } | {} |
| data[1] | { name: ['bar'], limit: ['5'] } | { country: '#notnull', active: '#notnull' } |
| data[2] | { name: ['#(data[2].name)'], country: ['#(data[2].country)'] } | { active: '#notnull', limit: '#notnull' } |
| data[3] | { country: '#[1]', limit: '#[1]' } | { name: '#notnull', active: '#notnull' } |
| data[4] | { active: '#[1]' } | { name: '#notnull', country: '#notnull', limit: '#notnull' } |
* def result = call read('search-simple.feature') search
Scenario: params json with embedded expressions
* def data = { one: 'one', two: 'two' }
Given path 'search'
# using enclosed javascript instead of an embedded expression for convenience
And params ({ name: data.one, country: data.two })
When method get
Then status 200
And match response == { name: ['one'], country: ['two'] }
Scenario: test that multi-params work as expected
Given path 'search'
And param foo = 'bar', 'baz'
When method get
Then status 200
And match response == { foo: ['bar', 'baz'] }
Given path 'search'
And params { foo: ['bar', 'baz'] }
When method get
Then status 200
And match response == { foo: ['bar', 'baz'] }
Given path 'search'
And param foo = 'bar,baz'
When method get
Then status 200
And match response == { foo: ['bar,baz'] }
Given path 'search'
And params { foo: 'bar,baz' }
When method get
Then status 200
And match response == { foo: ['bar,baz'] }