1

I started my adventure with Karate a month ago. I have a simple GET test called getAllCars.feature showing a list of cars currently available:

[   
  {     
    "brandName": "BMW",     
    "id": 1,     
    "winterTires": false,     
    "modelName": "X5"   
  },   
  {     
    "brandName": "Opel",     
    "id": 34,     
    "winterTires": true,     
    "modelName": "Insignia"   
  },   
  {     
    "brandName": "Mercedes-Benz",     
    "id": 36,     
    "winterTires": true,     
    "modelName": "GLE Coupe"   
  },   
  {     
    "brandName": "Huydai",      
    "id": 251,     
    "winterTires": false,     
    "modelName": "i30"   
  } 
]

I have to use each id as a parameter for the next feature file, the problem is, the list of cars is dynamic, ids don't repeat and I will have to use this list of ids for several other feature files. I managed to create a helper getCarIds.feature, which creates an array of objects "carId": "#number":

Feature: Get car IDs

  Scenario: Get car IDs
    * call read('classpath:x/automation/cars/getAllCars.feature')
    * def carIds = $response[*].id
    * def carFeeder = karate.mapWithKey(carIds, 'carId')

The following getCarParameters.feature has to iterate over the array from getCarIds.feature and pass each id as a parameter to get a response with performance parameters of each car and I don't know how to use each id separately as a parameter (keeping in mind that the list of ids is changing):

Feature: Get parameters of each car

  Scenario: Get parameters for each car
    * call read('classpath:x/automation/cars/getCarIds.feature')
    Given url carUrl + '/carparameters'
    And param carId =
    When method GET
    Then status 200

I managed to do it when passing the values from getCarIds.feature to getCarParameters.feature like described here by adding following line to getCarIds.feature:

* call read('classpath:x/automation/cars/getCarParameters.feature') carFeeder

but several other tests require car ids. I need getCarIds.feature to be reusable, so I would have to retrieve data from feature file, which creates the array with ids, instead of passing it to the GET feature and apparently it isn't so easy. Maybe my approach is completely wrong.

Robert
  • 13
  • 3

1 Answers1

0

I think this is a valid case for karate.callSingle(): https://github.com/karatelabs/karate#karatecallsingle

So you can actually stick this in any feature and it is guaranteed to execute only once across your test suite. If the data is indeed something used by a majority of your test suite, you could even do this initialization in karate-config.js.

So this should work. First the reusable feature common.feature. Instead of the hard-coded response, you know how to make an actual HTTP request.

@ignore
Feature:

Scenario:
* def response =
"""
[   
  {     
    "brandName": "BMW",     
    "id": 1,     
    "winterTires": false,     
    "modelName": "X5"   
  },   
  {     
    "brandName": "Opel",     
    "id": 34,     
    "winterTires": true,     
    "modelName": "Insignia"   
  }
]
"""
* print 'getting car ids'
* def carIds = response.map(x => ({ id: x.id }))

Note the use of the JS map() function above, which I have started to recommend instead of JsonPath.

And here is a feature that uses the above. This uses the new @setup annotation that makes it easy to "loop": https://github.com/karatelabs/karate#setup

You can try this example quickly, and watch it make 2 requests using a param id from the loop.

Feature:

@setup
Scenario:
* def data = karate.callSingle('call-single-common.feature').carIds

Scenario Outline:
* url 'https://httpbin.org/get'
* param id = id
* method get

Examples:
| karate.setup().data | 

There are other ways to loop, refer: https://github.com/karatelabs/karate#data-driven-features

Peter Thomas
  • 54,465
  • 21
  • 84
  • 248
  • 1
    Thanks, it's working great up to karate.setup().data, which can't be recognized, so I'm guessing the reason is, my company doesn't use the latest karate version (it's 1.0.1) and I'm getting error: >>> failed features: >>>> js failed: 01: karate.setup().data <<<< org.graalvm.polyglot.PolyglotException: TypeError: invokeMember (setup) on com.intuit.karate.core.ScenarioBridge@2c8662ac failed due to: Unknown identifier: setup - .:program(Unnamed:1) x/automation/cars/getCarParameters.feature:18 – Robert Feb 09 '23 at 11:22
  • @Robert yes, that's in Karate 1.3.1. so please look at the last link in my answer – Peter Thomas Feb 09 '23 at 11:57