一文搞定 REST Assured 實踐(二):斷言實現


文章來源於霍格沃茲測試學院

在上一篇文章中,我們初步探討了 REST Assured 的應用實踐,還有很多豐富的用法需要慢慢探索研究。而 REST Assured 提供的完整斷言手段,是測試工程師最常用最重要的功能之一。斷言該如何使用呢?

1. Json 斷言

1.1 環境准備

這里以 rest-assured 官方給的一個示例做演示學習

{
"lotto":{
"lottoId":5,
"winning-numbers":[2,45,34,23,7,5,3],
"winners":[{
"winnerId":23,
"numbers":[2,45,34,23,3,5]
},{
"winnerId":54,
"numbers":[52,3,12,11,18,22]
}]
}
}

在本地使用 python -m CGIHTTPServer 臨時搭建起一個服務:

一文搞定 REST Assured 實踐(二):斷言實現

 

1.2 JsonPath(Groovy's GPath)

 

在 Groovy 的官網,雖然並未提及它在 json 中的使用,但實際上只要是樹形的層級關系,無論是 json、xml 或者其他格式,就可以使用這種簡單的語法幫我們去找到其中的值,rest-assured 也已經幫我們實現支持了 GPath 的斷言方式

 

根節點.子節點1)我們可以使用根節點.(點)子節點的方式一層層的找下去,例如我們需要對lottoId等於 5 進行斷言:

一文搞定 REST Assured 實踐(二):斷言實現

 

@Test
void testGPath(){
given().
when().
log().all().get("http://127.0.0.1:8000/restAssured.json").
then().
log().all().body("lotto.lottoId",equalTo(5));
}

2)如果我們想要斷言winners數組下面的winnerId,檢查23和54是否包含其中,可以如下lotto.winners.winnerId寫法

一文搞定 REST Assured 實踐(二):斷言實現

 

@Test
void testGPath(){
given().
when().
log().all().get("http://127.0.0.1:8000/restAssured.json").
then().
log().all()
.body("lotto.winners.winnerId",hasItems(54,23));
}

索引取值1)如果我們想要取某些相同字段中的某一個,可以使用類似索引的方式獲取,例如想要斷言 winners 數組下面的 winnerId 的第一個值是否為23,可以使用 lotto.winners.winnerId[0],寫法如下:

一文搞定 REST Assured 實踐(二):斷言實現

 

@Test
void testGPath(){
given().
when().
log().all().get("http://127.0.0.1:8000/restAssured.json").
then().
log().all()
.body("lotto.winners.winnerId[0]",equalTo(23));
}

2)如果我們想要取某些相同字段中的最后一個,可以使用 -1 作為索引,例如斷言斷言 winners 數組下面的 winnerId 的最后一個的值是否為 54

一文搞定 REST Assured 實踐(二):斷言實現

 

@Test
void testGPath(){
given().
when().
log().all().get("http://127.0.0.1:8000/restAssured.json").
then().
log().all()
.body("lotto.winners.winnerId[-1]",equalTo(54));
}

findAll

有時候我們需要獲取符合某些條件的結果來進行斷言,這里 findAll 可以幫助我們實現,我們可以在 findAll 方法中寫篩選條件,例如我們想取 winnerId 的值在大於或等於 30 小於 60 之間的結果進行斷言,具體寫法如下:

@Test
void testGPath(){
given().
when().
log().all().get("http://127.0.0.1:8000/restAssured.json").
then().
log().all()
.body("lotto.winners.findAll{ winners -> winners.winnerId >= 30 && winners.winnerId < 60}.winnerId[0]",equalTo(54));
}

find

find 的用法與 findAll 基本一致,只是 find 默認取匹配到的第一個:

@Test
void testGPath(){
given().
when().
log().all().get("http://127.0.0.1:8000/restAssured.json").
then().
log().all()
.body("lotto.winners.find{ winners -> winners.winnerId >= 30 && winners.winnerId < 60}.winnerId",equalTo(54));
}

1.3 實操演示

將上述各個斷言語法寫在一起,實際運行校驗結果:

一文搞定 REST Assured 實踐(二):斷言實現

 

2. XML斷言

2.1 環境准備

上面介紹了,GPath 也支持 XML 格式的斷言,這里再以 rest-assured 官方給的一個實例做演示

<shopping>
<category type="groceries">
<item>
<name>Chocolate</name>
<price>10</price>
</item>
<item>
<name>Coffee</name>
<price>20</price>
</item>
</category>
<category type="supplies">
<item>
<name>Paper</name>
<price>5</price>
</item>
<item quantity="4">
<name>Pens</name>
<price>15</price>
</item>
</category>
<category type="present">
<item when="Aug 10">
<name>Kathryn's Birthday</name>
<price>200</price>
</item>
</category>
</shopping>

再次在本地搭起一個臨時服務:

一文搞定 REST Assured 實踐(二):斷言實現

 

2.2 XmlPath斷言語法

若我們要對第二個 name 的值 Coffee 進行斷言,寫法如下:

一文搞定 REST Assured 實踐(二):斷言實現

 

 

@Test
void testXML(){
when().
get("http://127.0.0.1:8000/restAssured.xml").
then().
log().all().
body("shopping.category[0].item[1].name",equalTo("Coffee"));
}

size()

可以利用 size() 方法來獲取對應節點的數量,例如這里要斷言 category 的數量:

@Test
void testXML(){
when().
get("http://127.0.0.1:8000/restAssured.xml").
then().
log().all()
.body("shopping.category.size()",equalTo(3));
}

it.@type、it.price

在 xml中 斷言中,可以利用 it. 屬性或節點的值來作為篩選條件;例如這里要獲取 type 為 supplies 的 category 下的第一個 item 的 name,以及獲取 price 為 10 的商品名 name。

一文搞定 REST Assured 實踐(二):斷言實現

 

@Test
void testXML(){
when().
get("http://127.0.0.1:8000/restAssured.xml").
then().
log().all()
.body("shopping.category.findAll{ it.@type == 'supplies' }.item[0].name",equalTo("Paper"))
.body("shopping.category.item.findAll{ it.price == 10 }.name",equalTo("Chocolate"));
}

**.findAll

對於xml中有一個特別的語法,**.findAll,可以直接忽略前面的節點,直接對篩選條件進行匹配,依然獲取price為10的商品名name,寫法如下:

@Test
void testXML(){
when().
get("http://127.0.0.1:8000/restAssured.xml").
then().
log().all()
.body("**.findAll{ it.price == 10 }.name",equalTo("Chocolate"));
}

2.3 實操演示

將上述各個斷言語法寫在一起,實際運行校驗結果:

一文搞定 REST Assured 實踐(二):斷言實現

 

3. JsonSchema斷言

3.1 需求背景

在實際工作中,對接口返回值進行斷言校驗,除了常用字段的斷言檢測以外,還要對其他字段的類型進行檢測,原因在於:

 

  • 返回字段較多,無法保證每個字段都寫斷言
  • 防止客戶端未做 null 值的校驗判斷,如果因為版本變更或網絡等原因造成某個不能接收 null 值的返回字段為 null,就很有可能造成軟件的崩潰
  • 某些數值是不能為負的
  • 小數點保留位數,對於股票的交易、醫療數據的分析,小數點的精確度都是有其實際價值的

對返回的字段一個個寫斷言顯然是非常耗時的,這個時候就需要一個模板,可以定義好數據類型和匹配條件,除了關鍵參數外,其余可直接通過此模板來斷言,這個就要請出JsonSchema了

3.2 使用方法

先對上述的 json 例子做少許修改,增加一個 String 類型的 winnername 字段,這里可以先你不用疑惑為什么加,后續自有其演示作用

一文搞定 REST Assured 實踐(二):斷言實現

 

JsonSchema模板生成

1)首先要借助於Json schema tool的網站https://www.jsonschema.net/,將返回json字符串復制到頁面左邊,然后點擊INFER SHCEMA,就會自動轉換為schema json文件類型,會將每個地段的返回值類型都設置一個默認類型; 在pattern中也可以寫正則進行匹配

一文搞定 REST Assured 實踐(二):斷言實現

 

2)點擊“設置”按鈕會出現各個類型返回值更詳細的斷言設置,這個就是schema最常用也是最實用的功能,也可以對每種類型的字段最更細化的區間值校驗或者斷言,例如長度,取值范圍等,具體感興趣的話可以從官網學習深入學習;平常對重要字段的校驗我通常會選用其他斷言,比如hamcrest斷言

一文搞定 REST Assured 實踐(二):斷言實現

 

3)選擇復制功能,可以將生成的schema模板保存下來

一文搞定 REST Assured 實踐(二):斷言實現

 

rest-assured結合使用

4)添加maven依賴,在rest-assured完成支持

<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>json-schema-validator</artifactId>
<version>4.0.0</version>
</dependency>

5)使用matchesJsonSchemaInClasspath方法對響應結果進行schema斷言

@Test
void jsonSchemaTest(){
get("http://127.0.0.1:8000/restAssured.json").
then().log().all()
.body(matchesJsonSchemaInClasspath("jsonSchema.json"));
}

運行結果:

一文搞定 REST Assured 實踐(二):斷言實現

 

多類型校驗-Combining schemas

  • String類型的默認值為null,后端很有可能在某個字段無值時返回null,例如我們將之前添加的winnername字段返回null:
一文搞定 REST Assured 實踐(二):斷言實現

 

運行查看斷言結果:

一文搞定 REST Assured 實踐(二):斷言實現

 

很明顯用例執行失敗,當我們定義了winnername為String類型后,返回null就會斷言失敗,這顯然不符合我們的需求,會造成用例執行結果的誤判,這個時候我們需要使winnername即可以為String類型,又可以為null;

這就要用到jsonSchema提供的Combining schemas方法了 Combining schemas提供了如下幾種方式:

  • allOf
  • anyOf
  • oneOf
  • not

這里我們選取anyOf(任何一項滿足即可)來完成上述的舉例,將原來的type換成String和null任何一個都支持的類型:

一文搞定 REST Assured 實踐(二):斷言實現

 

再次運行用例,查看斷言結果:

一文搞定 REST Assured 實踐(二):斷言實現

 

用例完美通過,到此結束~

(文章來源於霍格沃茲測試學院)

更多內容可點擊:https://shimo.im/docs/63w96qK9xpkH96hT/read

同時也可以關注我的公眾號:霍格沃茲測試學院

34g軟件測試開發、自動化資料教程群文件免費下載:Q群145743285


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM