https://www.ibm.com/developerworks/cn/java/j-lo-rest-assured2/index.html
REST API 的測試要點(diǎn)
隨著 Web 時代的發(fā)展融撞,無論是互聯(lián)網(wǎng)網(wǎng)站還是企業(yè)應(yīng)用草穆,都開始或者已經(jīng)公布了自己的 REST API,API 的應(yīng)用的與集成也越來越廣泛,因此 API 的測試也越來越受到重視鲤看。各種針對 REST API 的測試工具也應(yīng)運(yùn)而生,《使用 Rest-Assured 測試 REST API》已進(jìn)行了初步的介紹狠角。
REST API 的測試有其自己的特點(diǎn)绒瘦,雖然測試執(zhí)行很快,很適合自動化測試朴爬,但是通常參數(shù)特別多即寒,請求體和返回體有時也很復(fù)雜。從本質(zhì)上說,REST API 的測試主要是測試 HTTP 的 GET/POST/DELETE/PUT 這幾個方法母赵。其中逸爵,最復(fù)雜的主要是 GET 和 POST/PUT 兩種情況。GET 方法主要測試返回的 xml 或 JSON 返回體凹嘲。返回體的屬性及內(nèi)容越多师倔,測試就越復(fù)雜。
POST/PUT 方法主要測試發(fā)送過去的請求體是否能通過驗(yàn)證施绎,并且是否根據(jù)請求體創(chuàng)建或修改相應(yīng)的內(nèi)容溯革。這里的難點(diǎn)是請求體的復(fù)雜性,以及需要測試請求體中 property 的各種參數(shù)組合谷醉。這時候致稀,使用 JSON scheme 來驗(yàn)證返回體能大大簡化測試代碼。
REST-assured 的測試實(shí)踐
REST-assured 是一套測試框架俱尼,本質(zhì)上就是一組 Jar 包抖单,測試人員可以使用其中的各種 API 來實(shí)現(xiàn)自己的測試目的。它的安裝和簡單的使用本文就不再贅述遇八,請參考《使用 Rest-Assured 測試 REST API》矛绘。
我們首先看前面提到的第一個復(fù)雜點(diǎn)--驗(yàn)證返回體。JSON 返回體因?yàn)槠浣Y(jié)構(gòu)簡單刃永,非常常用货矮。在返回體中可能有著十幾或者幾十個 property,每個 property 的類型不同斯够,取值范圍也不同囚玫。
Rest-Assured 可以直接在 GET 的時候,同時進(jìn)行驗(yàn)證读规。如下例子:
Get(url).then().body(“server.name”,equalTo(“apache”));
如果有很多個屬性都需要驗(yàn)證抓督,則可以使用 from(body) 方法來從返回體中獲取到具體某個屬性,之后進(jìn)行格式和內(nèi)容的驗(yàn)證束亏。如:
assertEquals(from(body).getInt("errorCode"),400);
from 使用相當(dāng)靈活铃在,既可以做驗(yàn)證,也可以用來獲取 body 中的某一些值做為中間值來計算碍遍,或者用來做后續(xù)的驗(yàn)證定铜。
如果返回體是一個數(shù)組,還可以用 from 來獲取數(shù)組中的每一個對象來分別做驗(yàn)證雀久。
例如下面這段代碼:
List<``HashMap``> aList = from(body).getList("", HashMap.class);
將返回體中的數(shù)組轉(zhuǎn)型成 hashmap 組成的一個列表宿稀。每一個 JSON 對象都成為了一個 hashmap 對象,我們就可以方便地在循環(huán)中獲得其中具體的值做驗(yàn)證赖捌。
JSON Schema
然而祝沸,如果返回體非常龐大矮烹,屬性非常多,這樣的話罩锐,一個個參數(shù)的去驗(yàn)證奉狈,測試用例會非常多,代碼也會很冗長涩惑。
這時候如果我們使用 JSON schema 去驗(yàn)證的話仁期,就會大大減少用例和代碼數(shù)量。
JSON schema 描述了 JSON 的數(shù)據(jù)格式竭恬,是一種元數(shù)據(jù)跛蛋,它非常簡單易讀,我們先來看一個例子:
{
"type": "object",
“required”: true,
"properties": {
"name": {
"type": "string"
“required”: true,
},
"badgeNumber": {
"type": "string"
"pattern": "^[0-9].*$",
“required”: true,
},
“isActive”: {
“type”:“string”,
"enum": [ "false","true" ],
“required”: true
}
"age": {
"description": "Age in years",
"type": "integer",
"minimum": 1
}
},
}
從這個例子我們可以看出痊硕,JSON schema 本身就是 JSON 格式的赊级。
它所描述的這個 JSON 對象,有 4 個屬性岔绸,name, badgeNumber,isActive 和 age理逊。另外 type 還描述了每一個屬性的類型,除了 age 為整數(shù)型盒揉,其余均為字符串型晋被。required 表示該屬性是否是必須的。這個例子中刚盈,除了 age 外羡洛,其他屬性是必須的。
對于整數(shù)型藕漱,我們還可以限制其取值范圍翘县,例如在上面這個例子中,我們使用 minimum=1谴分,將 age 的最小值限制為為 1。
對于字符串類型镀脂,我們更可以用正則表達(dá)式來做更具體的描述牺蹄。
例如上例中的 badgeNumber,我們限定了這個字符串必須以數(shù)字開頭薄翅。
在 isActive 屬性中我們用枚舉的方式沙兰,限定了取值只能為 false 或者 true。
生成 JSON Schema
對于簡單的 JSON 返回體翘魄,我們可以根據(jù)需求來自己創(chuàng)建 JSNO Schema鼎天,但是對于復(fù)雜的返回體,這個過程也挺累人的暑竟。為了方便起見斋射,我可以用 JSON Schema 生成工具。例如:http://JSONschema.net/#/home。
通常我們可以先用任何方式(如測試代碼或者 REST Client 等插件)得到一個需要測試的返回體罗岖,然后用自動生成工具生成一個 schema 模板涧至。
一般來說,生成的 schema 模板會列出所有的屬性及其類型桑包。
然后在這個 schema 基礎(chǔ)上我們來分析每個屬性南蓬,根據(jù)不同的類型加上必要的限制條件。每種限制條件都相當(dāng)于測試用例中的一個驗(yàn)證點(diǎn)哑了。像上面這個例子中的 badgeNumber赘方,如果在返回體中這個屬性的值如果是整數(shù)型,就能使測試失敗弱左,如果這個屬性的值以字母開頭窄陡,同樣會使測試失敗。
使用 REST-Assured 驗(yàn)證 JSON Schema
首先我們需要安裝 JSON-schema-validator科贬,在 https://github.com/fge/JSON-schema-validator 上下載 JSON-schema-validator 的 lib 包泳梆,將其添加到我們的 classpath 中。
其次我們還需要將之前生成的 JSON schema 文件添加到我們的 classpath 中榜掌。
然后优妙,我們就能在測試代碼中僅用一句代碼驗(yàn)證返回體是否符合指定的 JSON Schema
例如:
expect().statusCode(200).given().auth().preemptive().basic(user, user).
headers("Accept","application/JSON").when().get("http://xyz.com/abc/").
then().assertThat().body(matchesJSONSchemaInClasspath("abc.JSON"));
其中 abc.JSON 文件就是我們準(zhǔn)備 JSON schema 文件。
REST API 其他測試技巧
1. REST API 測試中經(jīng)常需要對于返回體中的部分元素進(jìn)行驗(yàn)證憎账。我們可以利用 org.hamcrest.MatcherAssert 提供的各種斷言來幫助簡化測試代碼套硼。REST-assured 可以與 org.hamcrest.MatcherAssert 一起使用,進(jìn)行很多方便而有意思的驗(yàn)證胞皱。
如下例子:
//驗(yàn)證 index 的值不大于 20
given().auth().preemptive().basic(user, user).headers("Accept","application/json").
get("http://xyz.com/abc/").then().assertThat().body("index",lessThanOrEqualTo(20));
//驗(yàn)證 data.items 數(shù)組的 size 為 3
given().auth().preemptive().basic(user, user).headers("Accept","application/json").
get("http://xyz.com/abc/").then().assertThat().body("data.items",hasSize(3));
//驗(yàn)證 data.items 中每個元素的 id 屬性值都大于 5
given().auth().preemptive().basic(user, user).headers("Accept","application/json").
get("http://xyz.com/abc/").then().assertThat().body("data.items.id", everyItem(greaterThan(5)));
2. REST-assured 也支持類似于 Ruby block 的方來進(jìn)行搜索驗(yàn)證某些屬性邪意。
例如:
getInt("data.transferQualities.find {it.status=='SUCCESS'}.count");
在這段代碼中,data.transferQualities 是一個 array反砌,這段代碼可以在其中找尋某元素雾鬼,它的 status 的屬性為 success,然后得到它的 count 屬性宴树。
3. 在測試 POST/PUT 方法時策菜,最麻煩的地方是請求體中 property 非常多,而且各自有不同的限制條件酒贬。為了測試非法的輸入能正確被系統(tǒng)識別出來又憨,要測試很多參數(shù)組合。我們可以使用 Combinatorial Testing(又稱 All-pairs testing)的方法來得到參數(shù)組合锭吨,然后使用 Rest-Assured 進(jìn)行測試蠢莺。如果需要了解關(guān)于 Combinatorial Testing 的更詳細(xì)信息,可以從維基百科上的資料開始了解零如。
小結(jié):
本文介紹了如何使用 Rest-Assured 和 JSON Schema 測試 REST API 的方法及其他技巧躏将。由于筆者水平有限锄弱,如果文章中存在錯誤,歡迎讀者聯(lián)系并進(jìn)行指正耸携,也歡迎讀者一起分享經(jīng)驗(yàn)與想法棵癣。
相關(guān)主題
- REST-assured 官方網(wǎng)站,由此下載最新版本的 REST-assured夺衍。
- 使用 Rest-Assured 測試 REST API狈谊,介紹 REST-assured 的基本用法。
- JSON-Schema-validator 官方網(wǎng)站沟沙,由此下載最新版本的 JSON-schema-validator河劝。
- Java Hamcrest 的官方網(wǎng)站,由此下載最新版本的 Java Hamcrest矛紫。
- developerWorks Java 技術(shù)專區(qū):這里有數(shù)百篇關(guān)于 Java 編程各個方面的文章赎瞎。