场景文件
标题更新请求.json
{id: 12, name: 'Old Hello', config:[{username: 'qwe', password: 'tyu'},{username: 'abc', password: 'xyz'}]}
标题更新响应.json
{id: 12, name: 'New Hello', config:[{username: 'qwe', password: 'tyu'},{username: 'abc', password: 'xyz'}]}
标题更新错误请求.json
{id: 00, name: 'Old Hello', config:[{username: 'qwe', password: 'tyu'},{username: 'abc', password: 'xyz'}]}
标题更新错误响应.json
{Error: 'not found', Message: 'The provided Book is not found.'}
图书记录功能
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 }
更新功能
功能:更新图书记录。
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
场景 1 的实际 API 响应是:
{name: 'New Hello', config:[{username: 'abc', password: 'xyz'},{username: 'qwe', password: 'tyu'}]}
场景 2 的实际 API 响应是:
{Error: 'not found', Message: 'The provided Book is not found.'}
问题: 我应该如何验证 update.feature 文件中的响应,因为问题是如果我使用 #^^config 进行更改,则不适用于场景:2 且响应 == _arg.ExpectedResponse 不适用于场景:1?
这是典型的测试过度设计。如果有人告诉您测试需要“重复使用”,请不要听那个人的话。
你有两种情况,一种是快乐的道路,一种是消极的道路。我在下面提供了您应该如何写负路径,其余的由您决定。
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.'}
看看有多干净吗?测试中不需要“极端”重用。如果您仍然坚持需要一个超级通用的可重用功能文件来处理所有边缘情况,那么您只是给自己带来麻烦。看看你现有的测试变得多么难以阅读!!
编辑:由于我经常向其他人提及这个问题作为如何不编写测试的示例,因此我想让我的观点更清楚并添加几个链接以供参考。
有时在测试中“重复自己”是可以的。测试不必是DRY。 Karate 是一种 DSL,使您能够用一两行代码进行 HTTP 调用或 JSON 操作。当你开始尝试像这样“重复使用”时,实际上弊大于利。例如,您现在需要查看多个文件以了解您的测试正在做什么。
如果你不相信我,也许你会相信 Google 的团队:https://testing.googleblog.com/2019/12/testing-on-toilet-tests-too-dry-make.html
让我这样总结一下:好的测试是简单易读的,并且不要试图太聪明。当你添加“逻辑”时,它就不再是测试,而是更多需要测试的代码。
在所有 API 测试中,您需要做的就是:
match
即使第二步感觉像是“硬编码”,但在测试自动化领域“完全没问题”。想想吧。