2019-05-31 使用 REST-Assured 測試 REST API 的進(jìn)階技巧和最佳實(shí)踐

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)主題

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市颊咬,隨后出現(xiàn)的幾起案子务甥,更是在濱河造成了極大的恐慌,老刑警劉巖喳篇,帶你破解...
    沈念sama閱讀 211,348評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件敞临,死亡現(xiàn)場離奇詭異,居然都是意外死亡麸澜,警方通過查閱死者的電腦和手機(jī)挺尿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來炊邦,“玉大人编矾,你說我怎么就攤上這事∧俸Γ” “怎么了窄俏?”我有些...
    開封第一講書人閱讀 156,936評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長碘菜。 經(jīng)常有香客問我裆操,道長,這世上最難降的妖魔是什么炉媒? 我笑而不...
    開封第一講書人閱讀 56,427評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮昆烁,結(jié)果婚禮上吊骤,老公的妹妹穿的比我還像新娘。我一直安慰自己静尼,他們只是感情好白粉,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,467評論 6 385
  • 文/花漫 我一把揭開白布传泊。 她就那樣靜靜地躺著,像睡著了一般鸭巴。 火紅的嫁衣襯著肌膚如雪眷细。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,785評論 1 290
  • 那天鹃祖,我揣著相機(jī)與錄音溪椎,去河邊找鬼。 笑死恬口,一個胖子當(dāng)著我的面吹牛校读,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播祖能,決...
    沈念sama閱讀 38,931評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼歉秫,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了养铸?” 一聲冷哼從身側(cè)響起雁芙,我...
    開封第一講書人閱讀 37,696評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎钞螟,沒想到半個月后兔甘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,141評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡筛圆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,483評論 2 327
  • 正文 我和宋清朗相戀三年裂明,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片太援。...
    茶點(diǎn)故事閱讀 38,625評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡闽晦,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出提岔,到底是詐尸還是另有隱情仙蛉,我是刑警寧澤,帶...
    沈念sama閱讀 34,291評論 4 329
  • 正文 年R本政府宣布碱蒙,位于F島的核電站荠瘪,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏赛惩。R本人自食惡果不足惜哀墓,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,892評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望喷兼。 院中可真熱鬧篮绰,春花似錦、人聲如沸季惯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至贾漏,卻和暖如春候学,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背纵散。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工梳码, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人困食。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓边翁,卻偏偏與公主長得像,于是被迫代替她去往敵國和親硕盹。 傳聞我的和親對象是個殘疾皇子符匾,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,492評論 2 348

推薦閱讀更多精彩內(nèi)容