一 斷言
測試指定的restful api是否正常,判斷它的響應值是否符合預期標准,需要用到斷言知識。在soapUI里斷言使用的Groovy語言。在項目中測試起來非常簡單,測試過程如下。
1,准備測試數據
以下是准備的測試數據,它是一個JSON格式的數據列表。在resources節點中,它包含3個用戶消息子節點。
{ "total": 3, "resources": [ { "username": "test03-SD", "created": "1496800026000", "uuid": "8f6cae8a24ab4d0887dd5907430075e7", "contractNumber": "131" }, { "username": "test02", "created": "1489479452000", "name": "8bbf9fded675472aa852cf1940bc8234", "contractNumber": "133" }, { "username": "test01", "created": "1487576620000", "name": "156b396f9b354467b5d1d1a1014b2d10" } ], "time": "2017年06月13日 10時25分07秒", "pageNum": 1 }
2 添加斷言
在HTTP Request里添加斷言,如下圖所示。

然后在彈出的Add Assertion窗口,選擇Script項。

3 判斷total屬性的值
使用Script Assertion 測試JSON 格式的列表,在Script Assertion 窗口中寫入如下代碼:
def booksRoot = net.sf.json.JSONSerializer.toJSON(messageExchange.responseContent); def total = booksRoot.get("total"); assert total == 3
返回結果如下:

可以看到斷言中total對應的值與測試值是一樣的,如果故意寫錯,會怎么樣呢?錯誤的斷言如下:
def booksRoot = net.sf.json.JSONSerializer.toJSON(messageExchange.responseContent); def total = booksRoot.get("total"); assert total == 10
返回結果如下:

可以看到soapUI提示斷言中total的判斷是錯誤的,應該為3。
4 判斷resources節點的長度
使用的斷言腳本如下:
def root = net.sf.json.JSONSerializer.toJSON(messageExchange.responseContent); def resources = root.get("resources"); assert resources.size() == 3
5 判斷resource第一個節點的username屬性為 test03-SD
def root = net.sf.json.JSONSerializer.toJSON(messageExchange.responseContent); def resources = root.get("resources"); assert resources[0].get('username') == 'test03-SD'
二 例子
1,測試帶參數的restful api
請求地址:
http://127.0.0.1:8083/auth/api/v2/user/userList?param={"user_userType":"1","startpage":"1","pagesize":"10","morgId":"e1339799-628e-11e6-9e1b-e0db55cd9154"}
請求方法: get
返回json格式數據:
[ { "uuid": "053c951668a04144addc3336fc3967ad", "created": 1491976927000, "username": "吉林域管理員", "password": null, "firstname": "吉林", "lastname": null, "email": "123@qq.com", "state": "enabled", "apiKey": null, "secretKey": null, "salt": "c271b448fe2bf0dacadc7680a85116bc", "userType": "1", "tenantId": null, "sex": "2", "location": null, "contractNumber": null, "qq": null, "photoPath": null, "incorrectLoginAttempts": 0, "roleList": null, "tenantName": null, "morgId": "9ea8e621-628e-11e6-9e1b-e0db55cd9154", "morgName": "吉林分公司", "userMorgUuid": null, "uorgName": null, "uorgPath": null, "projectName": null, "morgPath": "//吉林分公司", "roleUuid": null, "userIds": null }, { "uuid": "088d6cf6a9c345b2b7191fe9a8366fcb", "created": 1487226069000, "username": "湖北域管理員2345", "password": null, "firstname": "111", "lastname": null, "email": "1@1.cn", "state": "enabled", "apiKey": null, "secretKey": null, "salt": "a41cd19102835984efba2f03af18b619", "userType": "1", "tenantId": null, "sex": "1", "location": null, "contractNumber": null, "qq": null, "photoPath": null, "incorrectLoginAttempts": 0, "roleList": null, "tenantName": null, "morgId": "9ebbe3c1-628e-11e6-9e1b-e0db55cd9154", "morgName": "湖北分公司", "userMorgUuid": null, "uorgName": null, "uorgPath": null, "projectName": null, "morgPath": "//湖北分公司", "roleUuid": null, "userIds": null } ]
soapUI中Http Requst配置,添加請求參數。
測試斷言:
def root = net.sf.json.JSONSerializer.toJSON(messageExchange.responseContent);
log.info( root.size() ) assert root.size() == 2
2,測試帶參數的restful api
請求地址:
http://127.0.0.1:8083/auth/api/v2/role/general/morg
請求方法: post
請求數據:
{ "uuid": "f38d750764104239a395b882e2818b6d4", "created": 1497404266481, "removed": null, "roleName": "soapui111", "description": "測試崗位", "sourceId": null, "roleType": "0", "adminType": null }
注意: 這個JSON請求數據中的uuid值必須保證每次發送請求都是唯一的,因為這個uuid代表插入數據數據的主鍵,必須保證是唯一的。
soapUI HttpRequest設置
斷言腳本:
httpResponseHeader = messageExchange.responseHeaders contentType = httpResponseHeader["Content-Type"] log.info("Content-Type: => " + contentType) assert contentType.get(0) == "application/json","Content Type is not an image"
log.info( httpResponseHeader["#status#"] )
使用場景:
適用於簡單的restful請求,如果多個restful請求有關聯關系,比如第一個restful請求測試添加一條數據記錄,返回值有uuid,第二個restful測試刪除依賴這個uuid,做刪除數據測試。在這種復雜場景下,就不適用於soapUI 了。
參考資料:
https://www.soapui.org/functional-testing/validating-messages/using-script-assertions.html
https://wenku.baidu.com/view/40b3598e680203d8ce2f245e.html
http://blog.csdn.net/liuchangxin1982/article/details/50561104
