Search code examples
apiautomationkarateweb-api-testing

Unordered array assertions in Karate


I am working API testing where expected (source) and actual (target) both are apis. So I need to hit both apis dynamically with an account number and have to assert both expected and actual.

Feature: un ordered array assertions

   Scenario :
    * url 'https://source.org/anything'
    * path id
    * method get
    * def expected = expecteResponse.empDetails
    * url 'https://actual.org/anything'
    * path id
    * method get
    * def actual = actualResponse.emps
    * match expected  == actual
  1. Here is my problem is expected [100,30,50], actual [50,100,30]. How can I assert them? And also, I need to validate string vs string (source = [sea,bus,air], target[bus,air,sea]) or integer vs float (Source = [10,1,20], target = [20.0,10.0,1.0]) or float vs integer (source =[20.0,10.0,1.0] target = [10,1,20]) or integer vs integer(source = [10,0,1] target = [0,10,1]. This my current.

But, it would be great if you answered for following questions (This top most problem for me to choose a framework to compare/validate apis which developed extract to api or api to api by using strapi technology)

  1. Mostly my tickets like source and target - content-as-a-service(CaaS) both are apis' need to validate regard less data type or array. Need to write re-usable functions (I am already using bearer tokens, but need to implement with other).

  2. same source and target validations but incorporate so many logics/expressions from source to target. can I adapt Karate framework for my testing?


Solution

  • Karate is very well suited for calling 2 APIs and comparing data. Karate has built-in support for comparing arrays ignoring element order. So here is one possible solution:

    * def response1 = { empDetails: [ 100, 30, 50] }
    * def response2 = { empDetails: [ 50, 100, 30] }
    * match response1.empDetails contains only response2.empDetails
    

    There are many more possibilities here since you can transform one payload and then do a compare. For further reading, refer: https://stackoverflow.com/a/53120851/143475

    For example if you want to compare integers vs float-strings:

    * def response1 = { empDetails: [ '100.0', '30.0', '50.0'] }
    * def response2 = { empDetails: [ 50, 100, 30] }
    * def expectedEmpDetails = response1.empDetails.map(x => parseInt(x))
    * match response2.empDetails contains only expectedEmpDetails
    

    Refer the docs on type-conversions and JSON transforms.