我们除了可以为一个请求指定请求参数之外,还可以指定请求头(header)、cookies、请求体(body)以及请求内容类型(content-type)等,下面我们就来一一介绍一下:
一、请求HTTP资源
我们通常在 request specification 中可以调用任何 HTTP方法 来执行一个请求,比如:
when().get("/x"). ..;
上面的例子中,get 就是HTTP请求方法。
从rest-assured的3.0.0版本开始,我们可以通过下面的方法在HTTP请求当中使用HTTP动词来发送请求:
when().
request("CONNECT", "/somewhere").
then().
statusCode(200);
上面的例子中,rest-assured就会发送一个 connect 请求到服务端。
扩展:对于资源的具体操作类型,由HTTP动词表示。常见的HTTP动词包括下面五个动词(括号里是对应的SQL命令):
- GET(SELECT):从服务器取出资源(一项或多项)。
- POST(CREATE):在服务器新建一个资源。
- PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)
- PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)。
- DELETE(DELETE):从服务器删除资源。
二、请求参数
通常我们是通过下面的方式来指定请求参数:
given().
param("param1", "value1").
param("param2", "value2").
when().
get("/something");
上面的例子中,rest-assured将会根据HTTP的请求方法自动判断使用哪一种参数类型(query or form ,查询类型或者表单类型),如果是 GET 请求方法,那么将使用查询类型(query parameters)请求参数;如果是 POST 请求方法,那么将会使用 form 表单参数。在有些测试用例(PUT 或者是 POST)当中,将表单参数和查询参数分开是非常重要的。那么我们就可以这么做:
given().
formParam("formParamName", "value1").
queryParam("queryParamName", "value2").
when().
post("/something");
请求参数也可以直接设置在URL上面:
..when().get("/name?firstName=John&lastName=Doe");
对于 multi-part parameters 下面再介绍。
1.多值的请求参数设置(Multi-value parameter)
多值请求参数的意思就是每一个参数名称对应于一个或者多个值(也就是说,一个参数名称的值是一个list集合),我们可以使用 var-args 的形式来表示:
given().param("myList", "value1", "value2"). ..
也可以使用list集合的形式来表示多值参数:
List<String> values = new ArrayList<String>();
values.add("value1");
values.add("value2"); given().param("myList", values). ..
2.无值请求参数(No-value parameter)
我们可以指定一个没有值的查询参数、表单参数以及请求等:
given().param("paramName"). ..
3.路径参数(Path parameters)
在我们的请求当中,我们也可以指定路径请求参数:
post("/reserve/{hotelId}/{roomNumber}", "My Hotel", 23);
在rest-assured中这些类型的路径请求参数都被称之为“未命名路径参数”,因为它们是基于索引的(hoteId 将会等于"My Hotel",因为它是第一个占位符)。
我们也可以使用已命名的路径参数:
given().
pathParam("hotelId", "My Hotel").
pathParam("roomNumber", 23).
when().
post("/reserve/{hotelId}/{roomNumber}").
then().
..
路径请求参数使用请求的URL更易读,同时也使得请求路径在很多需要不同参数值的测试用例当中更加容易重复使用。
rest-assured的2.8.0版本以后,我们还可以混合使用 未命名路径参数和命名路径参数:
given().
pathParam("hotelId", "My Hotel").
when().
post("/reserve/{hotelId}/{roomNumber}", 23).
then().
..
在这里 roomNumber 的值等于23.
需要注意的是,指定过少或过多的请求将会导致错误信息的出现。我们可以使用过滤器来实现更加高级的测试用例,比如新增(add)、更改(change)、删除(remove,一些冗余的路径参数)。
4.Multi-part 表单数据
当我们传送大容量的数据到服务端时,我们通常使用 multipart 表单数据技术。rest-assured提供了一个叫做 multiPart 的方法可以让我们指定文件(file)、字节数组(byte-array)、输入流或者是上传文件。在最简单的表单中,我们可以通过下面的方法来上传文件:
given().
multiPart(new File("/path/to/file")).
when().
post("/upload");
它将会承担一个叫做"file"的控制器。在HTML中,这个控制器的名字就是input标签的属性名。让我们来看一下下面的HTML表单:
<form id="uploadForm" action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="file" size="40">
<input type=submit value="Upload!">
</form>
在这个例子当中,控制器的名字就是一个名为"file"的input标签。如果我们有不一样的控制器名称,我们需要指定它:
given().
multiPart("controlName", new File("/path/to/file")).
when().
post("/upload");
当然也可以在一个请求当中提供多个"multi-part"实体:
byte[] someData = ..
given().
multiPart("controlName1", new File("/path/to/file")).
multiPart("controlName2", "my_file_name.txt", someData).
multiPart("controlName3", someJavaObject, "application/json").
when().
post("/upload");
我们还可以使用 MultiPartSpecBuilder 来使用一些更高级的用法:
Greeting greeting = new Greeting();
greeting.setFirstName("John");
greeting.setLastName("Doe"); given().
multiPart(new MultiPartSpecBuilder(greeting, ObjectMapperType.JACKSON_2)
.fileName("greeting.json")
.controlName("text")
.mimeType("application/vnd.custom+json").build()).
when().
post("/multipart/json").
then().
statusCode(200);
我们还可以通过使用 MultiPartConfig 来指定默认的 control-name 和 文件名,比如:
given().config(config().multiPartConfig(multiPartConfig().defaultControlName("something-else"))). ..
这将会配置控制器的名字为"something-else",而不是" file "。
三、cookies设置:
在最简单的form表单中我们可以指定cookies,这样做:
given().cookie("username", "John").when().get("/cookie").then().body(equalTo("username"));
我们也可以指定一个多值的cookie,如下:
given().cookie("cookieName", "value1", "value2"). ..
上面的写法将会创建两个cookies,cookieName=value1 和 cookieName=value2 。
我们还可以通过下面的方式来指定一个详细的cookie :
Cookie someCookie = new Cookie.Builder("some_cookie", "some_value").setSecured(true).setComment("some comment").build();
given().cookie(someCookie).when().get("/cookie").then().assertThat().body(equalTo("x"));
或者是同时指定多个具有详细信息的cookies :
Cookie cookie1 = Cookie.Builder("username", "John").setComment("comment 1").build();
Cookie cookie2 = Cookie.Builder("token", 1234).setComment("comment 2").build();
Cookies cookies = new Cookies(cookie1, cookie2);
given().cookies(cookies).when().get("/cookie").then().body(equalTo("username, token"));
四、请求头设置
given().header("MyHeader", "Something").and(). ..
given().headers("MyHeader", "Something", "MyOtherHeader", "SomethingElse").and(). ..
同样,我们也可以指定多值的header :
given().header("headerName", "value1", "value2"). ..
这里也会创建两个headers,headerName=value1 和 headerName=value2 .
1.头部合并/覆盖
默认情况下,头部是会被合并(merged)的,所以假如你这样写:
given().header("x", "1").header("x", "2"). ..
请求将会包含两个头部,"x:1" 和 "x:2"。我们也可以在 HeaderConfig 的基础上修改它为一个 header :
given().
config(RestAssuredConfig.config().headerConfig(headerConfig().overwriteHeadersWithName("x"))).
header("x", "1").
header("x", "2").
when().
get("/something").
...
这样的话,就只有一个 header,"x:2"会被发送到服务端。
五、Content-Type的设置
given().contentType(ContentType.TEXT). ..
given().contentType("application/json"). ..
六、请求体(Request Body)的设置
// 作用于POST, PUT and DELETE 请求
given().body("some body"). ..
//更明确的 (可选择)
given().request().body("some body"). ..
// 作用于POST, PUT and DELETE请求
given().body(new byte[]{42}). ..
//更明确的(可选择)
given().request().body(new byte[]{42}). ..
我们也可以序列化一个Java对象为JSON 或 XML,具体参考对象映射。