我們除了可以為一個請求指定請求參數之外,還可以指定請求頭(header)、cookies、請求體(body)以及請求內容類型(content-type)等,下面我們就來一一介紹一下:
一、請求HTTP資源
我們通常在 request specification 中可以調用任何 HTTP方法 來執行一個請求,比如:
1 when().get("/x"). ..;
上面的例子中,get 就是HTTP請求方法。
從rest-assured的3.0.0版本開始,我們可以通過下面的方法在HTTP請求當中使用HTTP動詞來發送請求:
1 when(). 2 request("CONNECT", "/somewhere"). 3 then(). 4 statusCode(200);
上面的例子中,rest-assured就會發送一個 connect 請求到服務端。
擴展:對於資源的具體操作類型,由HTTP動詞表示。常見的HTTP動詞包括下面五個動詞(括號里是對應的SQL命令):
- GET(SELECT):從服務器取出資源(一項或多項)。
- POST(CREATE):在服務器新建一個資源。
- PUT(UPDATE):在服務器更新資源(客戶端提供改變后的完整資源)
- PATCH(UPDATE):在服務器更新資源(客戶端提供改變的屬性)。
- DELETE(DELETE):從服務器刪除資源。
二、請求參數
通常我們是通過下面的方式來指定請求參數:
1 given(). 2 param("param1", "value1"). 3 param("param2", "value2"). 4 when(). 5 get("/something");
上面的例子中,rest-assured將會根據HTTP的請求方法自動判斷使用哪一種參數類型(query or form ,查詢類型或者表單類型),如果是 GET 請求方法,那么將使用查詢類型(query parameters)請求參數;如果是 POST 請求方法,那么將會使用 form 表單參數。在有些測試用例(PUT 或者是 POST)當中,將表單參數和查詢參數分開是非常重要的。那么我們就可以這么做:
1 given(). 2 formParam("formParamName", "value1"). 3 queryParam("queryParamName", "value2"). 4 when(). 5 post("/something");
請求參數也可以直接設置在URL上面:
1 ..when().get("/name?firstName=John&lastName=Doe");
對於 multi-part parameters 下面再介紹。
1.多值的請求參數設置(Multi-value parameter)
多值請求參數的意思就是每一個參數名稱對應於一個或者多個值(也就是說,一個參數名稱的值是一個list集合),我們可以使用 var-args 的形式來表示:
1 given().param("myList", "value1", "value2"). ..
也可以使用list集合的形式來表示多值參數:
1 List<String> values = new ArrayList<String>(); 2 values.add("value1"); 3 values.add("value2"); 4 5 given().param("myList", values). ..
2.無值請求參數(No-value parameter)
我們可以指定一個沒有值的查詢參數、表單參數以及請求等:
1 given().param("paramName"). ..
3.路徑參數(Path parameters)
在我們的請求當中,我們也可以指定路徑請求參數:
1 post("/reserve/{hotelId}/{roomNumber}", "My Hotel", 23);
在rest-assured中這些類型的路徑請求參數都被稱之為“未命名路徑參數”,因為它們是基於索引的(hoteId 將會等於"My Hotel",因為它是第一個占位符)。
我們也可以使用已命名的路徑參數:
1 given(). 2 pathParam("hotelId", "My Hotel"). 3 pathParam("roomNumber", 23). 4 when(). 5 post("/reserve/{hotelId}/{roomNumber}"). 6 then(). 7 ..
路徑請求參數使用請求的URL更易讀,同時也使得請求路徑在很多需要不同參數值的測試用例當中更加容易重復使用。
rest-assured的2.8.0版本以后,我們還可以混合使用 未命名路徑參數和命名路徑參數:
1 given(). 2 pathParam("hotelId", "My Hotel"). 3 when(). 4 post("/reserve/{hotelId}/{roomNumber}", 23). 5 then(). 6 ..
在這里 roomNumber 的值等於23.
需要注意的是,指定過少或過多的請求將會導致錯誤信息的出現。我們可以使用過濾器來實現更加高級的測試用例,比如新增(add)、更改(change)、刪除(remove,一些冗余的路徑參數)。
4.Multi-part 表單數據
當我們傳送大容量的數據到服務端時,我們通常使用 multipart 表單數據技術。rest-assured提供了一個叫做 multiPart 的方法可以讓我們指定文件(file)、字節數組(byte-array)、輸入流或者是上傳文件。在最簡單的表單中,我們可以通過下面的方法來上傳文件:
1 given(). 2 multiPart(new File("/path/to/file")). 3 when(). 4 post("/upload");
它將會承擔一個叫做"file"的控制器。在HTML中,這個控制器的名字就是input標簽的屬性名。讓我們來看一下下面的HTML表單:
1 <form id="uploadForm" action="/upload" method="post" enctype="multipart/form-data"> 2 <input type="file" name="file" size="40"> 3 <input type=submit value="Upload!"> 4 </form>
在這個例子當中,控制器的名字就是一個名為"file"的input標簽。如果我們有不一樣的控制器名稱,我們需要指定它:
1 given(). 2 multiPart("controlName", new File("/path/to/file")). 3 when(). 4 post("/upload");
當然也可以在一個請求當中提供多個"multi-part"實體:
1 byte[] someData = .. 2 given(). 3 multiPart("controlName1", new File("/path/to/file")). 4 multiPart("controlName2", "my_file_name.txt", someData). 5 multiPart("controlName3", someJavaObject, "application/json"). 6 when(). 7 post("/upload");
我們還可以使用 MultiPartSpecBuilder 來使用一些更高級的用法:
1 Greeting greeting = new Greeting(); 2 greeting.setFirstName("John"); 3 greeting.setLastName("Doe"); 4 5 given(). 6 multiPart(new MultiPartSpecBuilder(greeting, ObjectMapperType.JACKSON_2) 7 .fileName("greeting.json") 8 .controlName("text") 9 .mimeType("application/vnd.custom+json").build()). 10 when(). 11 post("/multipart/json"). 12 then(). 13 statusCode(200);
我們還可以通過使用 MultiPartConfig 來指定默認的 control-name 和 文件名,比如:
1 given().config(config().multiPartConfig(multiPartConfig().defaultControlName("something-else"))). ..
這將會配置控制器的名字為"something-else",而不是" file "。
三、cookies設置:
在最簡單的form表單中我們可以指定cookies,這樣做:
1 given().cookie("username", "John").when().get("/cookie").then().body(equalTo("username"));
我們也可以指定一個多值的cookie,如下:
1 given().cookie("cookieName", "value1", "value2"). ..
上面的寫法將會創建兩個cookies,cookieName=value1 和 cookieName=value2 。
我們還可以通過下面的方式來指定一個詳細的cookie :
1 Cookie someCookie = new Cookie.Builder("some_cookie", "some_value").setSecured(true).setComment("some comment").build(); 2 given().cookie(someCookie).when().get("/cookie").then().assertThat().body(equalTo("x"));
或者是同時指定多個具有詳細信息的cookies :
1 Cookie cookie1 = Cookie.Builder("username", "John").setComment("comment 1").build(); 2 Cookie cookie2 = Cookie.Builder("token", 1234).setComment("comment 2").build(); 3 Cookies cookies = new Cookies(cookie1, cookie2); 4 given().cookies(cookies).when().get("/cookie").then().body(equalTo("username, token"));
四、請求頭設置
1 given().header("MyHeader", "Something").and(). .. 2 given().headers("MyHeader", "Something", "MyOtherHeader", "SomethingElse").and(). ..
同樣,我們也可以指定多值的header :
1 given().header("headerName", "value1", "value2"). ..
這里也會創建兩個headers,headerName=value1 和 headerName=value2 .
1.頭部合並/覆蓋
默認情況下,頭部是會被合並(merged)的,所以假如你這樣寫:
1 given().header("x", "1").header("x", "2"). ..
請求將會包含兩個頭部,"x:1" 和 "x:2"。我們也可以在 HeaderConfig 的基礎上修改它為一個 header :
1 given(). 2 config(RestAssuredConfig.config().headerConfig(headerConfig().overwriteHeadersWithName("x"))). 3 header("x", "1"). 4 header("x", "2"). 5 when(). 6 get("/something"). 7 ...
這樣的話,就只有一個 header,"x:2"會被發送到服務端。
五、Content-Type的設置
1 given().contentType(ContentType.TEXT). .. 2 given().contentType("application/json"). ..
六、請求體(Request Body)的設置
1 // 作用於POST, PUT and DELETE 請求 2 given().body("some body"). .. 3 //更明確的 (可選擇) 4 given().request().body("some body"). ..
1 // 作用於POST, PUT and DELETE請求 2 given().body(new byte[]{42}). .. 3 //更明確的(可選擇) 4 given().request().body(new byte[]{42}). ..
我們也可以序列化一個Java對象為JSON 或 XML,具體參考對象映射。