
2.4 REST-Assured的使用
REST-Assured是一个专门用于测试RESTful API的工具,它与Hamcrest深度集成,为开发者提供了诸多测试RESTful API的便利方法,下面就来具体讲解该工具的使用方法。
首先,在项目工程中引入对REST-Assured的依赖,具体配置如下所示。
Maven的引入方式:
<dependency> <groupId>io.rest-assured</groupId> <artifactId>rest-assured</artifactId> <version>4.3.1</version> <scope>test</scope> </dependency>
Gradle的引入方式:
testImplementation 'io.rest-assured:rest-assured:4.3.1'
成功引入对REST-Assured的依赖后,接下来就是检查REST-Assured对其他第三方类库的依赖情况。从图2-9中我们可以看到,REST-Assured依赖了很多与编码、HTTP、JSON、XML等相关的第三方类库,这是因为REST-Assured需要具备HTTP的访问能力,以及JSON、XML等报文格式的解析能力。同样,我们还会发现它对Hamcrest的依赖,由于在pom文件中,我们显式地指定了其对Hamcrest的依赖,因此REST-Assured所依赖的Hamcrest将被忽略。

图2-9 REST-Assured使用Hamcrest的对象匹配器
REST-Assured主要用于测试RESTful API,限于篇幅,本书不会为此专门开发一个RESTful API以演示如何使用REST-Assured,幸运的是如今互联网上有很多RESTful的站点可以达到相同的目的,我们可以基于jsonplaceholder提供的RESTful在线API进行演示。
1)http://jsonplaceholder.typicode.com:80/posts/:列出所有文章列表。
在正式测试该接口之前,我们需要大致熟悉一下该接口的访问方法,以及返回的数据结构(如图2-10所示)。通常情况下,获取数据列表都会使用HTTP的GET请求。下面通过Postman做个简单测试。

图2-10 posts resource的访问方法和返回的数据结构
@Test public void testRequestHttpStatus_OK() { //当通过GET方法请求“/posts”时,HTTP的状态码为200。 when().request("GET", "/posts").then().statusCode(is(200)); } @Test public void testListPosts() { //“/posts”返回的文章数据列表超过10个。 get("/posts").then().assertThat().body("size()", greaterThan(10)); }
2)http://jsonplaceholder.typicode.com:80/posts/{ID}:获取某篇指定文章。
“/posts/{ID}”用于获取指定文章的详细信息,返回结果同样为JSON结构,包含title、body、id等字段,图2-11所示的是获取id为1的文章的方法,以及服务器端返回的数据结构。

图2-11 获取指定文章的详细信息
@Test public void testRequestSpecPost() { //通过get方法访问 URI“/posts/1”,然后对结果进行断言。 get("/posts/1").then().assertThat() //从body中获得title属性,REST_Assured可以自动解析出title属性。 .body("title", is(equalTo("sunt aut facere repellat provident occaecati excepturi optio reprehenderit"))); }
运行上面的单元测试,不出意外的话肯定能够成功运行(除非测试数据被删除,导致单元测试运行失败)。第1章曾提到,单元测试应该尽可能全面地覆盖各种情况,如果所访问的文章不存在,那么根据RESTful规范,需要响应404这样的HTTP状态码,这一切都可以交给REST-Assured来完成。
@Test public void testRequestPostNotExist() { //get方法请求path: /posts/12345。 //期望返回404这样的HTTP状态码。 get("/posts/12345").then().statusCode(is(404)); }
限于篇幅,关于REST-Assured的介绍就到这里,大家如想进一步深入了解,可以通过阅读其官方资料获取更多帮助。程序代码2-8所示的是通过REST-Assured测试RESTful API的完整代码。
程序代码2-8 REST_AssuredTest.java
package com.wangwenjun.cicd.chapter02; import io.restassured.RestAssured; import org.junit.After; import org.junit.Before; import org.junit.Test; import static io.restassured.RestAssured.get; import static io.restassured.RestAssured.when; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.Matchers.*; public class REST_AssuredTest { @Before public void setup() { //指定base URI。 RestAssured.baseURI = "http://jsonplaceholder.typicode.com"; //指定端口。 RestAssured.port = 80; } @Test public void testRequestHttpStatus_OK() { //通过get方法请求“/posts”时,HTTP得到状态码为200。 when().request("GET", "/posts").then().statusCode(is(200)); } @Test public void testListPosts() { //“/posts”返回的文章数据列表超过10个。 get("/posts").then().assertThat().body("size()", greaterThan(10)); } @Test public void testRequestSpecPost() { get("/posts/1").then().assertThat().body("title", is(equalTo("sunt aut facere repellat provident occaecati excepturi optio reprehenderit"))); } @Test public void testRequestPostNotExist() { get("/posts/12345").then().statusCode(is(404)); } @After public void tearDown() { RestAssured.reset(); } }
在对RESTful API进行单元测试时,REST-Assured不仅可用于屏蔽HTTP的访问细节,而且在其内部还可以针对不同的返回类型进行解析(比如JSON、XML等),因此我们可以非常方便地使用Hamcrest的各种对象匹配器,对HTTP的请求结果执行断言操作。