Rest Assured 辅助功能
配置功能Config
可以使用RestAssured内建的方法,进行全局的配置,有如下的方法:
1 | RestAssured.baseURI = "https://api.github.com"; |
除了以上的配置,也可以使用RestAssured提供的配置功能进行实现,以下查看RestAssured提供的丰富的配置功能:
我们已经看到RestAssured提供丰富的配置实现,以下我们看下两个具体配置实体
使用headerConfig重写的方法,对header参数进行覆盖处理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23/**
* Header配置实例
*/
void headerConfig() {
// 使用headerConfig重写的方法,对test的header参数进行覆盖处理
RestAssured.config = RestAssured.config().headerConfig(HeaderConfig.headerConfig().overwriteHeadersWithName("test"));
String loginBody = "{\n" +
" \"username\":\"xiaohong\",\n" +
" \"password\":\"123123\"\n" +
"}";
given()
.log().all()
.contentType(ContentType.JSON)
.header("test", "aaa")
.header("test", "bbb")
.body(loginBody)
.when()
.get("/user/login")
.then()
.log()
.body().statusCode(200);
}
使用logConfig的enablePrettyPrinting设置为false,响应返回body则不会进行格式化显示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22/**
* Log配置实例
*/
void logConfig() {
// 使用logConfig的enablePrettyPrinting设置为false,响应返回body则不会进行格式化显示
RestAssured.config = RestAssured.config().logConfig(LogConfig.logConfig().enablePrettyPrinting(false));
String loginBody = "{\n" +
" \"username\":\"xiaohong\",\n" +
" \"password\":\"123123\"\n" +
"}";
given()
.log().all()
.contentType(ContentType.JSON)
.body(loginBody)
.when()
.get("/user/login")
.then()
.log()
.body().statusCode(200);
}
模板功能Specification
我们在写接口测试的时候,在很多情况下我们会针对某些特定的接口写出大量的测试用例,而这些接口的请求和响应判断当中往往会有重复的内容定义,除了使用之前定义的通用配置,也可以使用RestAssured提供的模板功能来定义接口的请求和响应,在多个测试用例中使用,减少重复的测试代码编写。
常用的就是RequestSpecification和ResponseSpecification。
1 | package com.api.demo; |
过滤功能Filter
请求与响应内容的修改
过滤功能是指在请求发出之前,或者响应接收到之前,能够通过Filter过滤器,可以改变请求或者响应的内容。特别是使用了大量的模板功能的时候,需要对个别的用例进行微调,这是就可以通过Filter进行实现。
以下示例进行Request与Response的使用Filter进行修改
1 | package com.api.demo; |
Filter机制
rest-assured的Filter
过滤器会在请求实际发起之前侦测和改变该请求的内容,也可以在响应体实际返回之前拦截并改变。您可以将其理解为AOP中的around advice(译者注:可以自行搜索切片编程)。过滤器也可以用在认证scheme、session管理、日志中。创建一个过滤器需要实现io.restassured.filter.Filter接口。
rest-assured提供了几个过滤器:
- io.restassured.filter.log.RequestLoggingFilter: 可以打印出请求模式的细节。
- io.restassured.filter.log.ResponseLoggingFilter: 可以打印响应信息的细节如果响应体的状态码匹配given方法的参数。
- io.restassured.filter.log.ErrorLoggingFilter: 如果发生了异常(状态码在400和500之间),过滤器将会打印响应的内容。
利用filter机制实现自动解密
- filter可以应用于所有全局请求
- request处理
- 记录所有的request数据
- 自动填充token
- response处理
- 重新构建新的response
filter((req,res,ctx))->{//重新生成response}
new ResponseBuilder().clone(originalResponse)
修改request
- 可以修改请求内容
- 自动带上cookie
- 通用的请求数据记录
- 记录所有的请求和响应
接口加解密处理
以base64加解密过程为例
- 原始内容 -> 加密内容
- 加密内容 -> internet -> response -> client
- client -> filter -> 解密内容
- body正常断言
示例
WireMock模拟一个接口,返回的主体为Base64加密
Filter机制,编写测试代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26/**
* 使用filter处理请求返回body加密的情况
*/
void testEncode() {
given().baseUri("http://localhost:9090")
.log().all()
.filter((request, response, context) -> {
// 发送原始请求,但是返回的Response不具备set方法,无法修改body
Response resOrigin = context.next(request, response);
// 解密过程
String raw = Base64.decodeStr(resOrigin.body().asString());
// 响应构造器,ResponseBuilder的作用主要是在Response的基础上建设出来一个新的可以修改的body对象(克隆出来一个新的)
ResponseBuilder resBuilder = new ResponseBuilder().clone(resOrigin);
//Response无法直接修改body,所有间接的通过ResponseBuilder构建
resBuilder.setBody(raw);
//ResponseBuilder在最后通过build方法直接创建一个用于返回的不可修改的Response
return resBuilder.build();
})
.when()
.get("/api/encryption").prettyPeek()
.then()
.log().all()
.body("books.name[0]", equalTo("西游记"))
.statusCode(200);
}
执行结果
如果是所有接口都需要加解密处理呢?我们可以使用RestAssured配置功能,全局添加
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24/**
* 全局抽出来的filter对象
*/
static void before() {
RestAssured.filters((req, res, ctx) -> {
// 添加过滤接口路径,包含就处理加解密过程,如果不包含就不进行处理
if (req.getURI().contains("/api/encryption")) {
// 返回的Response不具备set方法,无法修改body
Response resOrigin = ctx.next(req, res);
// 解密过程
String raw = Base64.decodeStr(resOrigin.body().asString());
// 响应构造器,ResponseBuilder的作用主要是在Response的基础上建设出来一个新的可以修改的body对象
ResponseBuilder resBuilder = new ResponseBuilder().clone(resOrigin);
//Response无法直接修改body,所有间接的通过ResponseBuilder构建
resBuilder.setBody(raw);
//ResponseBuilder在最后通过build方法直接创建一个用于返回的不可修改的Response
return resBuilder.build();
} else {
return ctx.next(req, res);
}
}
);
}
Session Filter
- sessionIdName
- sessionId
- session filter可以自动从请求中提取sessionId,并在以后的请求中再附带进cookie发送出去
示例
以Jenkins模拟登录,获取Session,请求其他的接口
根据获取到的信息,编写代码
1 |
|