Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.5k views
in Technique[技术] by (71.8m points)

api - How to compare 2 JSON objects that contains array using Karate tool and feature files

Files for the scenario

  • All the files are on same directory.

title-update-request.json

{id: 12, name: 'Old Hello', config:[{username: 'qwe', password: 'tyu'},{username: 'abc', password: 'xyz'}]}

title-update-response.json

{id: 12, name: 'New Hello', config:[{username: 'qwe', password: 'tyu'},{username: 'abc', password: 'xyz'}]}

title-update-error-request.json

{id: 00, name: 'Old Hello', config:[{username: 'qwe', password: 'tyu'},{username: 'abc', password: 'xyz'}]}

title-update-error-response.json

{Error: 'not found', Message: 'The provided Book is not found.'}

book-record.feature

Feature: CRUD operation on the book records.

Background:
        * def signIn = call read('classpath:login.feature')
        * def accessToken = signIn.accessToken
        * url baseUrl

 Scenario: Change title of book in the single book-record.
    * json ExpResObject = read('classpath:/book-records/title-update-response.json')
    * json ReqObject = read('classpath:/book-records/title-update-request.json')
    * call read('classpath:/book-records/update.feature') { Token: #(accessToken), ReqObj: #(ReqObject), ResObj: #(ExpResObject), StatusCode: 200 }

  Scenario: Change title of book in the non-existing book-record.
    * json ExpResObject = read('classpath:/book-records/title-update-error-request.json')
    * json ReqObject = read('classpath:/book-records/title-update-error-response.json')
    * call read('classpath:/book-records/update.feature') { Token: #(accessToken), ReqObj: #(ReqObject), ResObj: #(ExpResObject), StatusCode: 400 }

update.feature

Feature: Update the book record.

Scenario: Update single book-record.
    Given path '/book-record'
    And header Authorization = 'Bearer ' + __arg.Token
    And header Content-Type = 'application/json'
    And request __arg.ReqObj
    When method put
    Then status __arg.StatusCode
    And response == __arg.ExpectedResponse

Actual API response for scenario: 1 is :

{name: 'New Hello', config:[{username: 'abc', password: 'xyz'},{username: 'qwe', password: 'tyu'}]}

Actual API response for scenario: 2 is :

 {Error: 'not found', Message: 'The provided Book is not found.'}

Question: How should I validate the response in update.feature file since problem is if I make change s as using #^^config that will not works for scenario :2 and response == _arg.ExpectedResponse is not working for Scenario: 1?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This is classic over-engineering of tests. If someone has told you that "re-use" is needed for tests, please don't listen to that person.

You have two scenarios, one happy path and one negative path. I am providing how you should write the negative path here below, the rest is up to you.

Scenario: Change title of book in the non-existing book-record.
Given path 'book-record'
And header Authorization = 'Bearer ' + accessToken
And request {id: 00, name: 'Old Hello', config:[{username: 'qwe', password: 'tyu'},{username: 'abc', password: 'xyz'}]}
When method put
Then status 400
And response == {Error: 'not found', Message: 'The provided Book is not found.'} 

See how clean it is ? There is no need for "extreme" re-use in tests. If you still insist that you want a super-generic re-usable feature file that will handle ALL your edge cases, you are just causing trouble for yourself. See how un-readable your existing tests have become !!

EDIT: Since I refer the question to others often as an example of how NOT to write tests, I wanted to make my point more clear and add a couple of links for reference.

Sometimes it is okay to "repeat yourself" in tests. Tests don't have to be DRY. Karate is a DSL that enables you to make HTTP calls or JSON manipulation in one or two lines. When you start attempting "re-use" like this, it actually leads to more harm than good. For example, you now need to look at multiple files to understand what your test is doing.

If you don't believe me, maybe you will believe Google: https://testing.googleblog.com/2019/12/testing-on-toilet-tests-too-dry-make.html


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...