一、准备阶段
按照开源文档,做一个样例
https://github.com/rest-assured/rest-assured/wiki
vi daybreak.json
内容是文档中的json样例
{ "store": {
"book": [
{ "category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{ "category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{ "category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{ "category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
}
}
python -m CGIHTTPServer
用python快速生成一个本地8000端口的小网站
访问127.0.0.1:8000,daybreak.json文件内容如下:
与新建json文件同样的方法,新建一个daybreak.xml
-
Chocolate
10
-
Coffee
20
-
Paper
5
-
Pens
15
-
Kathryn's Birthday
200
访问127.0.0.1:8000/daybreak.xml,结构如下:
shopping下面有多个不同type的category,每个category下有一个或多个item,item下面有name和price
Tips:(可能遇到的坑)
当使用python -m GCIHTTPServer
时,常常会报错:
socket.error: [Errno 48] Address already in use
解决方法:
ps -fA | grep python
结果:
...
501 23129 20675 0 7:51下午 ttys001 0:00.99 python -m CGIHTTPServer
501 23815 20675 0 9:54下午 ttys001 0:00.00 grep python
找到对应的进程号,然后kill 进程号
,kill 23129
再重新python -m GCIHTTPServer
二、演练
new一个class,Demo.java
1. 对json的断言:
方式一:
import org.junit.Test;
import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.*;
public class Demo {
@Test
public void testJson(){
given().when().get("http://127.0.0.1:8000/daybreak.json")
.then()
.body("store.book.category",hasItems("reference"));
}
}
"store.book.category"
,是昨天提到过的,根节点.子节点.子节点……
hasItems("reference")
,前面的key对应的value是在这个括号里
方式二:
[ ]
是json中的数组
book节点下,是四个对立的数组元素,每个元素中都有category、author、title、price,我要断言book中的第一个author的值是Nigel Rees。
代码
.body("store.book[0].author",equalTo("Nigel Rees"))
"store.book[0].author"
:book数组的第1个元素下的author
第2个元素可以用book[1]
……,最后一个元素可以使用book[-1]
方式三:
官方文档中还有一种方式,叫深度搜索,比如某个子集有n个数组,找出符合特定条件的。
store.book.find{ book -> book.price >= 5 && book.price <= 15 }
获得price在5-15之间的book数组
用法:
.body("store.book.find{ book -> book.price >= 5 && book.price <= 15}.price",equalTo(8.95f))
2. 对xml断言
方式一:同json相似的
@Test
public void testXml(){
when().get("http://127.0.0.1:8000/daybreak.xml")
.then()
.body("shopping.category.item[0].name",equalTo("Chocolate"));
}
.body("shopping.category[0].item[0].name",equalTo("Chocolate"));
虽然结果是一样的,但是category的含义不一样
方式二:
shopping.category.item.size()
,返回itms的个数/长度
用法:.body("shopping.category.item.size()",equalTo("5"));
使用.body("shopping.category.item.size()",equalTo(""));
可以明白category
和category[0]
的区别
category
有5个item,category[0]
有2个item
方式三:深度检索
"shopping.category.findAll { it.@type == 'groceries' }.size()"
,返回type = 'groceries' 的category的size,是1,使用@
表示属性。
示例1:
.body("shopping.category.findAll { it.@type == 'groceries' }.size()",equalTo(1));
示例2:
"shopping.category.findAll { it.@type == 'groceries' }.item.size()",equalTo(2))
:返回上面所述的category.item的size,是2。
示例3:
.body("shopping.category.item.findAll { it.price == 200 }.name",equalTo("Kathryn's Birthday"));
返回price=200的item的name,是"Kathryn's Birthday"
示例4:
.body("**.findAll { it.price == 200 }.name",equalTo("Kathryn's Birthday"));
:shopping.category.item可以换成**
(json path不支持**
)
find
是找第一个,findAll
是找所有,我理解是it
指带find前面的内容。
3. 对html的断言:
昨天的文章中,在百度搜索mp3的响应,是一个html结构的内容,把html也看作是一层一层的节点。
断言示例:
.body("html.head.title",equalTo("mp3_百度搜索"));
三、实战
继续xueqiu.com,对搜索接口进行应用
接口返回结果如下:
{
"q": "sogo",
"page": 1,
"size": 10,
"stocks": [
{
"code": "SOGO",
"name": "搜狗",
"enName": "",
"hasexist": "false",
"flag": null,
"type": 0,
"stock_id": 1029472,
"ind_id": 0,
"ind_name": "通讯业务",
"ind_color": null,
"_source": "sc_1:1:sogo"
}
]
}
.body("stocks.find{it.code == 'SOGO'}.name",equalTo("搜狗"));
四、今日份源码
Demo.java:
import org.junit.Test;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
public class Demo {
@Test
public void testJson(){
when().get("http://127.0.0.1:8000/daybreak.json")
.then()
.body("store.book.category",hasItems("reference"))
.body("store.book[0].author",equalTo("Nigel Rees"))
.body("store.book.find{ book -> book.price >= 5 && book.price <= 15 }.price",equalTo(8.95f));
}
@Test
public void testXml(){
when().get("http://127.0.0.1:8000/daybreak.xml")
.then()
.body("shopping.category.item[0].name",equalTo("Chocolate"))
.body("shopping.category.item.size()",equalTo(5))
.body("shopping.category.findAll { it.@type == 'groceries' }.item.size()",equalTo(2))
.body("shopping.category.item.findAll { it.price == 200 }.name",equalTo("Kathryn's Birthday"))
.body("**.findAll { it.price == 200 }.name",equalTo("Kathryn's Birthday"));
}
}