How to reuse assertions for scenarios in single feature file using Karate? - karate

I want to assert responseTime of all scenarios. But i do not want to repeat the assertion code in every scenario. Below is my feature file:
Feature: Reqres api test cases
Background: base url
Given url base_url
Scenario: list single user get request
Given path single_user_path
When method get
Then status 200
And assert responseTime < 4000
Scenario: create user using post and inline json payload
* def path = '/users'
Given path path
And request {"name": "morpheus","job": "leader"}
When method post
Then status 201
And assert responseTime < 4000
In the above code block, I want to avoid responseTime assertion duplication. How to achieve this in karate?. Please help.

No this is not supported and not planned either. It is unlikely every API call will have the exact same SLA. Also this is what the Gatling integration is for: https://stackoverflow.com/a/55146463/143475
EDIT as an example of how you can do "reuse" of response assertions:
Feature:
Background:
* def validateResponse =
"""
function() {
var contentType = karate.get("responseHeaders['Content-Type'][0]");
if (contentType !== 'application/json') {
karate.fail('content type is not json');
}
var responseType = karate.get('responseType');
if (responseType !== 'json') {
karate.fail('response type is not json');
}
}
"""
Scenario:
* url 'https://httpbin.org/post'
* request { foo: 'bar' }
* method post
* validateResponse()
Please note that I absolutely don't recommend the above approach because of reasons best explained here: https://stackoverflow.com/a/54126724/143475

Related

get the params value from a variable

i have one feature file as
Feature: Getting the Token
Background:
header Content-Type 'application/json'
def CookieGenerator = Java.type('com.ade.Helpers.CookiesGenerator');
def endpoints read('classpath: src/test/java/com/ade/resources/endpoints.json')
Given url endpoints.token
Scenario: To check the Schema of the response
Given cookies (new CookieGenerator().getCookieValue())
When method GET
Then status 200
def txnToken = response
#print token
from above code i am getting Token's value as something like this "gdjsgjshjhsjfhsg646"
now i have another feature file where i have to use above Token's value in my query parameter value as
Feature: Testing datent Name and Client
Background:
header Content-Type 'application/json""
def endpoints read('classpath:src/test/java/com/ade/resources/endpoints.json") def CookieGenerator Java.type('com.ade.Helpers.CookiesGenerator");
call read('Token.feature')
Given url baseUrl+endpoints.dit.Client.path
Scenario: To check the Schema of the response
Given def head read('classpath:src/test/java/com/ade/resources/reqpay.json") =
def req head.data[1]
And cookies (new CookieGenerator().getCookieValue())
And request req
And param {txntoken = txnToken}
When method post
Then status 200
from above my endpoint should be like https://something.com/clients?txntoken='gdjsgjshjhsjfhsg646'
but i am getting as https://something.com/clients?txntoken=txnToken
https://something.com/clients?txntoken='gdjsgjshjhsjfhsg646'
Your post is hard to read, as #peter-thomas said, please try formatting it better in the future, or edit the post if I haven't answered your question.
I believe what you're looking for is described in the documentation here
* def signIn = call read('classpath:my-signin.feature') { username: 'john', password: 'secret' }
* def authToken = signIn.authToken
you can see how information can be passed
I also asked a similar question fairly recently here
relevant bit here:
* def key = karate.call('ReadRoundUpSubscription.feature');
* def keyvalue = key.acckey
i prefer to call features like this, and not defining things in the reusable feature.

Validate json Payload before passing It

HI there I am making post call using karate And for that I am passing json Payload but before i pass it i want to validate is there any null or empty string present and if yes then Abort the post call and print message empty string or null values cant be accepted.
Thanks in advance!
peter thomas Thank you in advance
This doesn't make sense to me, because if you are preparing this payload yourself, you never need to validate it.
That said, you can run a match anytime.
* def body = { myKey: 'myValue' }
* match body == { myKey: '#string' }
* url 'https://httpbin.org/anything'
* request body
* method post
* status 200
* match response contains deep { json: { myKey: 'myValue' } }
See how the second line does a validation.
Also refer this answer to see how you can programmatically run karate.match() for advanced use-cases: https://stackoverflow.com/a/50350442/143475

Getting "not defined" error while calling a feature file from another feature file (Karate framework)

Whenever I try to call the feature file(one.feature) from another feature file(starter.feature), I am not able to access the info(caller) in specific scenario
But It is working fine and I am able to access info(caller),
when I run one.feature file standalone.
when I run one.feature file through Junit test case.
CODE WORK-FLOW :
In one.feature :
In the scenario(Scenario: matching two Strings) we are trying to match two Strings and configuring afterScenario JS function to get the info of the scenario and If the info contains any errors, The function will call the other scenario(Scenario: getting caller details) with info details assigned in the variable caller
starter.feature :
Feature: call another feature
Scenario: calling feature file
* def callFeat = call read('one.feature')
one.feature :
Feature: get details
Background:
* configure afterScenario =
"""
function() {
var info = karate.info;
if(info.errorMessage){
karate.call('one.feature#CallCaller', { caller : info });
}
}
"""
#CreateErrorMsg
Scenario: matching two Strings
* def Text1 = 'Hey'
* def Text2 = 'Hello'
* match Text1 == Text2
#CallCaller #ignore
Scenario: getting caller details
* print caller
Can't you use karate.log from the JS function rather than calling another scenario to just print the info? Also, note that karate.info has been deprecated from 1.0 version of Karate and replaced by karate.scenario - https://github.com/karatelabs/karate/wiki/1.0-upgrade-guide#karateinfo-deprecated
* configure afterScenario =
"""
function() {
var info = karate.info;
if(info.errorMessage){
karate.log(info.scenarioName);
}
}
"""

Variables defined at Karate Background is not matching with local Scenario ones

Scenario: I send an image_URL at my Request Body to an endpoint, and I would like to confirm image URL is loaded by asserting from the response (Easy peasy)
Background: Get ready
#Get random image via Java class
* def dataGenerator = Java.type('Com.helpers.DataGenerator')
* def randomImage = dataGenerator.getImage()
Scenario: Pass Image_URL, assert image URL is in the response
Given url myUrl
And request
"""
{
"image": { "upload_url": #(randomImage) },
}
"""
When method POST
* print "=========image URL============== " + response.metadata.image_url
* print "=========random Image============== " + (randomImage)
Then status 201
Then match response.metadata[*].image_url == (randomImage)
The response is something like this:
{
"metadata": {
....,
"image_url": "https://link/image.jpeg",
....}
}
My issue:
`"response.metadata.image_url"` from response is different than `(randomImage)`, hence assertion is failing.
When I manually run from the postman, Response "image_url" is matching with request body "upload url"
From my understanding,
* def randomImage should be called once before Every Scenario, so it should be the exact same entire Scenario during runtime.
Not sure if I am missing some obvious concept. Curious to see any guidance on this one
Versions:
<java.version>1.8</java.version>
<maven.compiler.version>3.8.1</maven.compiler.version>
<maven.surefire.version>2.22.2</maven.surefire.version>
<artifactId>karate-junit5</artifactId>
<karate.version>1.1.0</karate.version>
Also, my Java Helper class is working fine, but I can add it if needed.

Is there way in karate to get the assertion status like pass or fail in variable for further processing in java?

In feature file i am writing assertion as
match response contains {token_type: '#string' }
Is there a way to get the output status of the above assertion value like true or false,
so that i can extend that into java for further processing?
The whole point of Karate is to avoid Java, and I don't recommend doing anything else.
But since you insist, if you want to get the equivalent of the above, just do something like this. Yes, you have to use "normal" JS fundas.
* def response = { token_type: 'foo' }
* def isString = typeof(response.token_type) === "string"
* match isString == true