构建高质量软件:持续集成与持续交付系统实践
上QQ阅读APP看书,第一时间看更新

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将被忽略。

056-01

图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做个简单测试。

057-01

图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的文章的方法,以及服务器端返回的数据结构。

058-01

图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的请求结果执行断言操作。