前文:
rest-assured接口測試學習(一)
rest-assured接口測試學習(二)
補充知識
一、全局封裝
1.全局RestAssured對象
-
RestAssured.XXX
全局變量 - BaseURI
2.spec方法通用的斷言
每個請求都會共用的參數(shù):比如URI 位仁、cookies,或者每個接口都有的斷言statusCode是200……可以使用specification
public class Baidu {
public static RequestSpecification requestSpecification;
public static ResponseSpecification responseSpecification;
@Before
public void gen(){
//通用請求
requestSpecification=new RequestSpecBuilder().build();
requestSpecification.port(80);
requestSpecification.cookie("s_id","leitianxiao");
requestSpecification.header("User-Agent","Andriod");
//通用斷言
responseSpecification=new ResponseSpecBuilder().build();
responseSpecification.statusCode(200);
responseSpecification.body(hasItems("0","1"));
//其他用例里使用
@Test
public void testGetHtml(){
given().
//請求使用
spec(requestSpecification);
get("http://www.baidu.com").
then().
//斷言使用
spec(responseSpecification);
}
}
3.filter方法進行加解密封裝(利用filter機制實現(xiàn)自動解密)
(這里沒大懂~~)
- filter可以用于全局請求
- request處理
記錄所有的request數(shù)據(jù)
自動填充token - response處理
重新構(gòu)建新的response
filter((req,res,ctx)->{//重新生成response})
new ResponseBuilder().clone(originalResponse)
————————————
filter相當于過濾器剃毒、攔截器樊拓,在請求之前可以改掉請求信息餐塘,如URL妥衣,然后傳給ctx調(diào)用鏈,調(diào)用鏈發(fā)送篡改后的請求戒傻,調(diào)用鏈獲得response税手,可以進行篡改,篡改之后才會返回response
順序:
//code
//filter request
//real response
//filter response
//return response
//then斷言
解密原理是在得到real response進行解密需纳,通過filter response把解密的response返回芦倒。
tips:
這里maven構(gòu)建時報錯-source 1.5 中不支持 lambda 表達式
,filter((req,res,ctx)->{//重新生成response})
是jdk8的 lambda 表達式不翩,Maven Compiler 插件默認會加 -source 1.5 及 -target 1.5 參數(shù)來編譯(估計是為了兼容一些比較老的 Linux 服務(wù)器操作系統(tǒng)兵扬,它們通常只有 JDK 5)麻裳,而我們的代碼里使用了 JDK 7/8 的語法。
解決:pom.xml文件<project>下添加:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
————————————
- 修改request
可以修改請求文件(自動帶上cookie)
通用的請求數(shù)據(jù)記錄(記錄所有的請求和響應(yīng))
public void testUserInfo(){
given().log().all().proxy("127.0.0.1").//設(shè)置代理抓包
filter((req,res,ctx)->{
//自行給請求頭加上id=tester字段
req.header("id","tester");
//把請求發(fā)出去
Response resOrigin=ctx.next(req,res);
//把響應(yīng)返回
return resOrigin;
}).
when().
get("/data/userinfo").
then().log().all().
spec(responseSpecification);
}
通過charles可以看到周霉,請求頭里有了id=tester字段,但是用log().all()
打印沒有亚皂,這說明在真實請求發(fā)起時俱箱,并不知道有id這個字段,通過filter后灭必,在真實對外發(fā)送時增加了這個字段狞谱。
應(yīng)用:
全局的filter,所有請求加一個通用的請求信息(比如cookie)放在@Before,可以通過if判斷禁漓。
RestAssured.filter((req,res,ctx)->{
//如果URI里包含xueqiu.com跟衅,請求頭上加上cookie信息
if (req.getURI().contains("xueqiu.com")){
//自行給請求頭加上id=tester字段
req.header("cookie","……");
//把請求發(fā)出去
Response resOrigin=ctx.next(req,res);
//把響應(yīng)返回
return resOrigin;
} }).
——————————
- 修改response
示例:
given().filter((req,res,ctx)->{
//把請求發(fā)出去
Response resOrigin=ctx.next(req,res);
//克隆原來的response
ResponseBuilder responseBuilder=new ResponseBuilder().clone(resOrigin);
//setbody是修改把返回來的body
responseBuilder.setBody("hello world");
//新的response
Response resNew =responseBuilder.build();
//返回新的response
return resNew;
})
應(yīng)用:
{
"q": "sogo",
"page": 1,
"size": 3,
"stocks": [{
"code": "SOGO",
"name": "搜狗",
"enName": "",
"hasexist": "false",
"flag": null,
"type": 0,
"stock_id": 1029472,
"ind_id": 0,
"ind_name": "通訊業(yè)務(wù)",
"ind_color": null,
"_source": "sc_1:1:sogo"
}]
}
響應(yīng)原本是這種json格式,我們的斷言是
then().
statusCode(200).
body("stocks.name",equalTo("搜狗"));
可能因為某些原因播歼,響應(yīng)需要加密(以base64加密為例)伶跷,返回的是加密的響應(yīng),這個時候你使用業(yè)務(wù)斷言是會報錯的:
ewoJInEiOiAic29nbyIsCgkicGFnZSI6IDEsCgkic2l6ZSI6IDMsCgkic3RvY2tzIjogW3sKCQkiY29kZSI6ICJTT0dPIiwKCQkibmFtZSI6ICLmkJzni5ciLAoJCSJlbk5hbWUiOiAiIiwKCQkiaGFzZXhpc3QiOiAiZmFsc2UiLAoJCSJmbGFnIjogbnVsbCwKCQkidHlwZSI6IDAsCgkJInN0b2NrX2lkIjogMTAyOTQ3MiwKCQkiaW5kX2lkIjogMCwKCQkiaW5kX25hbWUiOiAi6YCa6K6v5Lia5YqhIiwKCQkiaW5kX2NvbG9yIjogbnVsbCwKCQkiX3NvdXJjZSI6ICJzY18xOjE6c29nbyIKCX1dCn0=
tips:
base64
命令可以直接將響應(yīng)轉(zhuǎn)為base64加密形式
用python快速生成一個本地8000端口的小網(wǎng)站來演示這種情況:
vim base64.json
//把加密了的json內(nèi)容寫入base64.json中
python -m CGIHTTPServer
@Test
public void testBase64(){
given().
get("http://127.0.0.1:8000/base64.json").prettyPeek().
then().
statusCode(200).
body("stocks.name",hasItems("搜狗"));
}
把上文的示例中responseBuilder.setBody("hello world");
的“hello world”改為解密后的響應(yīng)body即可秘狞。
代碼如下:
@Test
public void testBase64(){
given().filter((req,res,ctx)->{
//把請求發(fā)出去
Response resOrigin=ctx.next(req,res);
//克隆原來的response
ResponseBuilder responseBuilder=new ResponseBuilder().clone(resOrigin);
//使用Base64的庫
//Base64.getDecoder().decode()對resOrigin的body進行解碼
//轉(zhuǎn)為string格式叭莫,trim()去掉字符串兩端多余空格。
String decode=new String(
Base64.getDecoder().decode(
resOrigin.body().asString().trim()
)
);
//setbody是修改把返回來的body
responseBuilder.setBody(decode);
//新的response
Response resNew =responseBuilder.build();
//返回新的response
return resNew;
}).
get("http://127.0.0.1:8000/base64.json").prettyPeek().
then().
statusCode(200).
body("stocks.name",hasItems("搜狗"));
}
}
解密之后可以正常使用我們的業(yè)務(wù)斷言
二烁试、對接口時間進行斷言
when().
get("/lotto").
then().
time(lessThan(2000L));//響應(yīng)時間不超過2000毫秒
除了進行功能測試雇初,對響應(yīng)時間有個基本的要求
三、schema自動校驗
RestAssured有一套自己的schema自動校驗機制
- schema的生成借助于在線服務(wù)
- 使用schema api斷言
schema自動生成方法
(需要很深的算法功底减响,自己寫工具靖诗,自動掃描公司接口,自動生成對應(yīng)的schema文件)
- 每次運行的時候自動保存當前的schema
- 下次運行對比上次的schema如果發(fā)現(xiàn)變更就報錯
- saveSchema+diffSchema
實踐
官網(wǎng):JSON Schema
作用:JSON Schema可以對JSON進行注釋和校驗支示,我們對一個接口的斷言最多寫10個左右刊橘,對其余大量的數(shù)據(jù)的response沒有校驗,JSON Schema就是對大量數(shù)據(jù)的Json進行一個數(shù)據(jù)格式的驗證颂鸿,包括字段的數(shù)據(jù)類型伤为、范圍、長度据途。
-
生成schema文件:Json Schema Tool
$schema
關(guān)鍵字指出此架構(gòu)是根據(jù)標準的特定草稿編寫的绞愚,"$schema": "http://json-schema.org/draft-07/schema#"
表示根據(jù)draft-07草案編寫。
該$id
關(guān)鍵字定義模式的URI颖医,并解析模式中其他URI引用的基URI位衩。
$title
和$description
注釋關(guān)鍵字僅是描述性的。它們不會對要驗證的數(shù)據(jù)添加約束熔萧。使用這兩個關(guān)鍵字說明了模式的意圖糖驴。
type
驗證關(guān)鍵字定義我們的JSON數(shù)據(jù)的第一個約束僚祷,在這種情況下,它必須是一個JSON對象贮缕。"type": "object"
驗證類型是object,"type": "array"
驗證類型是數(shù)組,"type": "boolean"
驗證類型是布爾類型辙谜。
$required
驗證key字段的列表。
properties
驗證關(guān)鍵字感昼。 -
手工編輯增強
例:String斷言装哆,對所有type為String的進行斷言,長度在5-10之間
所以可以通過手動添加這個字段來約束JSON數(shù)據(jù)定嗓。 如何在RestAssured使用
- 導(dǎo)入依賴
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>json-schema-validator</artifactId>
<version>3.0.1</version>
</dependency>
-
一般Schema的文件比較大蜕琴,使用時,通常存成一個的文件宵溅。
調(diào)用matchesJsonSchemaClasspath等系列方法
靜態(tài)導(dǎo)入:import static io.restassured.module.jsv.JsonSchemaValidator.*;
常用斷言方式一:assertThat().body(matchesJsonSchemaInClasspath("data/userInfo-schema.json"));
常用斷言方式二:assertThat().body(matchesJsonSchema(new File("data/userInfo-schema.json")));
故意寫錯一個驗證類型看看效果凌简,把本應(yīng)該是string類型的改為boolean。
warning可以先不管恃逻,找到error~可以看出說實例類型是string雏搂,而被允許的類型是boolean。
四寇损、https請求
useRelaxedHTTPSValidation();
//信任https請求