Can I use the status shortcut in Karate to check a response class instead of just one code - karate

I am using Karate to test other people's implementations of an API. When checking response status codes I often need to accept more than one response. For example in response to a PUT I may see 200, 201, 205 - they are equally valid. I know I can use
Then assert responseStatus >= 200 && responseStatus < 300
to check for success but the shortcut really helps readability of the tests.
Would you consider an enhancement to the language to support response classes such as:
success (meaning 200-299)
redirect (meaning 300-399)
fail (meaning 400-499)
2xx
3xx
4xx
If I were to look at submitting a PR for this would you agree it is useful and would you have a preferred mechanism? Would these classes be best as parsed symbols or strings that force a different match to be implemented when it detects the status is not a number?

Yes, my first reaction is not to add a new keyword. Also to be honest, this seems to be a rare requirement - never had this ask before, I guess API testing would generally mean predictable responses.
My proposal is that you can write a custom function:
* def statusSuccess = function(){ var status = karate.get('responseStatus'); return status >= 200 && status < 300 }
* url 'https://httpbin.org'
* path 'status', 200
* method get
* assert statusSuccess()
EDIT - also see this: https://twitter.com/KarateDSL/status/1364433453412851714

Related

Can we use two status validation like for example * match 200 and 208 at same time in karate api testing automation [duplicate]

I am using Karate to test other people's implementations of an API. When checking response status codes I often need to accept more than one response. For example in response to a PUT I may see 200, 201, 205 - they are equally valid. I know I can use
Then assert responseStatus >= 200 && responseStatus < 300
to check for success but the shortcut really helps readability of the tests.
Would you consider an enhancement to the language to support response classes such as:
success (meaning 200-299)
redirect (meaning 300-399)
fail (meaning 400-499)
2xx
3xx
4xx
If I were to look at submitting a PR for this would you agree it is useful and would you have a preferred mechanism? Would these classes be best as parsed symbols or strings that force a different match to be implemented when it detects the status is not a number?
Yes, my first reaction is not to add a new keyword. Also to be honest, this seems to be a rare requirement - never had this ask before, I guess API testing would generally mean predictable responses.
My proposal is that you can write a custom function:
* def statusSuccess = function(){ var status = karate.get('responseStatus'); return status >= 200 && status < 300 }
* url 'https://httpbin.org'
* path 'status', 200
* method get
* assert statusSuccess()
EDIT - also see this: https://twitter.com/KarateDSL/status/1364433453412851714

How to assert a failed API call as a passed test [duplicate]

We have a system that we use in order to make some PUT requests during tests. The issue is that this system has, at the moment, some issues with its resources and sometimes it can't answer in time. We can't increase the read timeout to a value greater than 60 seconds for 2 reasons: if the system doesn't answer fast it most likely won't answer at all and secondly we're using a proxy which times out at 60 seconds.
I'm aware of this question , but waitForHttp or waitForPort don't fit our requirements as the port is available and there is no health endpoint telling us if the PUT request will succeed or just be lost.
Is there anything else we can do?
Example feature:
Background:
* url dep_url
* configure headers = read('classpath:package/headers/headers.json')
* retry until responseStatus !== 429
Scenario: Create entity
Given request read('classpath:package/body/' + file)
When path '/entity/' + entity[index]
And method put
Then assert responseStatus == 200 || responseStatus == 201
We need retries when a SocketTimeoutException is thrown, for example:
java.net.SocketTimeoutException: Read timed out, http call failed after 253 milliseconds for url
Well, try polling then: https://stackoverflow.com/a/56799845/143475
And combine that approach with the fact that you can use a JS try-catch in Karate: https://stackoverflow.com/a/67024149/143475
So maybe something like this:
* def failed = false
* eval try { karate.call('called.feature') } catch (e) { karate.set('failed', true) }
You should be able to figure out a solution now. Do post what you come up with.
EDIT: for those who feel bad about calling a second feature file, you can do everything in one file like this:
Feature:
Scenario:
* call read('#called')
#ignore #called
Scenario:
* print 'called'

Karate: karate.waitForHttp for url that requires a certificate [duplicate]

We have a system that we use in order to make some PUT requests during tests. The issue is that this system has, at the moment, some issues with its resources and sometimes it can't answer in time. We can't increase the read timeout to a value greater than 60 seconds for 2 reasons: if the system doesn't answer fast it most likely won't answer at all and secondly we're using a proxy which times out at 60 seconds.
I'm aware of this question , but waitForHttp or waitForPort don't fit our requirements as the port is available and there is no health endpoint telling us if the PUT request will succeed or just be lost.
Is there anything else we can do?
Example feature:
Background:
* url dep_url
* configure headers = read('classpath:package/headers/headers.json')
* retry until responseStatus !== 429
Scenario: Create entity
Given request read('classpath:package/body/' + file)
When path '/entity/' + entity[index]
And method put
Then assert responseStatus == 200 || responseStatus == 201
We need retries when a SocketTimeoutException is thrown, for example:
java.net.SocketTimeoutException: Read timed out, http call failed after 253 milliseconds for url
Well, try polling then: https://stackoverflow.com/a/56799845/143475
And combine that approach with the fact that you can use a JS try-catch in Karate: https://stackoverflow.com/a/67024149/143475
So maybe something like this:
* def failed = false
* eval try { karate.call('called.feature') } catch (e) { karate.set('failed', true) }
You should be able to figure out a solution now. Do post what you come up with.
EDIT: for those who feel bad about calling a second feature file, you can do everything in one file like this:
Feature:
Scenario:
* call read('#called')
#ignore #called
Scenario:
* print 'called'

Karate retry mechanism for SocketTimeoutException

We have a system that we use in order to make some PUT requests during tests. The issue is that this system has, at the moment, some issues with its resources and sometimes it can't answer in time. We can't increase the read timeout to a value greater than 60 seconds for 2 reasons: if the system doesn't answer fast it most likely won't answer at all and secondly we're using a proxy which times out at 60 seconds.
I'm aware of this question , but waitForHttp or waitForPort don't fit our requirements as the port is available and there is no health endpoint telling us if the PUT request will succeed or just be lost.
Is there anything else we can do?
Example feature:
Background:
* url dep_url
* configure headers = read('classpath:package/headers/headers.json')
* retry until responseStatus !== 429
Scenario: Create entity
Given request read('classpath:package/body/' + file)
When path '/entity/' + entity[index]
And method put
Then assert responseStatus == 200 || responseStatus == 201
We need retries when a SocketTimeoutException is thrown, for example:
java.net.SocketTimeoutException: Read timed out, http call failed after 253 milliseconds for url
Well, try polling then: https://stackoverflow.com/a/56799845/143475
And combine that approach with the fact that you can use a JS try-catch in Karate: https://stackoverflow.com/a/67024149/143475
So maybe something like this:
* def failed = false
* eval try { karate.call('called.feature') } catch (e) { karate.set('failed', true) }
You should be able to figure out a solution now. Do post what you come up with.
EDIT: for those who feel bad about calling a second feature file, you can do everything in one file like this:
Feature:
Scenario:
* call read('#called')
#ignore #called
Scenario:
* print 'called'

Calling Karate feature files based on SOAP response status code 200 or 500

I have a requirement where I needed to call multiple feature files based on status code 200, 201, 500 etc. I tried few examples listed in stackoverflow as well but didn't help.
E.g.
Let's say I created 3 feature files. File1.feature, File2.feature & File3.feature.
1) File1.feature may give response status code 200 or 500
2) Based on response code 200, I need to call File2.feature to do certain tests.
3) Based on response code 500, I need to call File3.feature to do certain tests.
Appreciate your help on this.
After any request, there is a "magic variable" called responseStatus that will hold the HTTP status code value. You can easily use it to do conditional calls.
* if (responseStatus == 200) karate.call('some.feature')
Refer: https://github.com/intuit/karate#conditional-logic