一 断言
测试指定的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