REST Assured进行测试API测试

REST Assured支持使用java库测试REST API,并且与Maven API集成良好。无论JSON结构多么复杂,它都非常有效地保证REST拥有从求和响应的几乎每个部分获取数据的方法。

对于测试来说,API自动化测试仍然是一个新的市场。使用核心的Java基础知识,RESTAssured.io框架让它变得非常简单,也是一件非常值得学习的事情。

在本教程中,将了解

  • 为什么需要REST Assured?
  • RESTAssured.io设置分步指南
  • 简单的REST Assured脚本
  • 获取响应的不同部分的脚本

为什么需要REST-Assured?

假设打开百度地图并查找想去的地方,会立即看到附近的餐厅,会看到通勤选项;现在,如果要测试这种设置,甚至在UI构建或正在开发之前,测试API就变得极其重要,并且使用不同的数据组合反复测试使其成为非常适合自动化的情况。

早些时候,我们使用Groovy、Ruby等动态语言来实现,很有挑战性。因此,功能测试并不涉及API测试。

但是,如果有Java的基本背景,使用RESTAssured进行API的自动化测试,发送简单HTTPS请求是很简单的。理解应用编程接口测试是必要的,而集成测试RESTAssured是一个开源的,添加了很多额外的方法和库,是应用编程接口自动化的一个很好的选择。

RESTAssured.io设置分步指南

步骤1) 安装Java。参阅本指南

步骤2) 下载IDE开始:Eclipse

步骤3) 安装Maven并设置Eclipse。

设置RESTAssured

  1. 在IDE中创建一个Maven项目。使用的是IntelliJ,但是在可能使用的任何IDE上都会得到类似的结构。
  2. 打开POM.xml

项目结构

对于RESTAssured.io:对于JAVA版本小于9的用户:

将以下依赖项添加到POM.xml:

 <dependency>
<groupId>io.rest-assured</groupId>
<artifactId>json-path</artifactId>
<version>4.2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>xml-path</artifactId>
<version>4.2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>json-schema-validator</artifactId>
<version>4.2.0</version>
<scope>test</scope>
</dependency>
 

对于RESTAssured.io:对于JAVA版本9+的用户:

 <dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured-all</artifactId>
<version>4.2.0</version>
<scope>test</scope>
</dependency>
 

错误应对:

如果看到错误并且不确定依赖项是否下载好,

  1. 执行maven构建以导入所有依赖项。
  2. 如果还是会看到错误,然后执行maven清理,然后执行maven安装,构建时应该没有任何错误。
  3. 可以在java类中添加以下行,并且可以看到没有出现编译错误。
 import io.restassured.RestAssured.*;
import io.restassured.matcher.RestAssuredMatchers.*;
import org.hamcrest.Matchers.*;
 

简单的RESTAssured脚本

语法:

RESTAssured.io的语法是最漂亮的部分,因为非常类似于bdd并且易于理解。

Given().
param("x", "y").
header("z", "w").
when().
Method().
Then().
statusCode(XXX).
body("x, ”y", equalTo("z"));

说明:

代码 解释
Given() Given(),可以让设置背景,在这里,可以传递请求头、查询和路径参数、正文、cookie。此选项可选
when() when()标志着场景的前提。例如,‘When’you get/post/put某事,做另一件事。
Method() 方法CRUD operations(get/post/put/delete)
Then() 断言和匹配器条件放在这里

现在已经有了设置和语法的一些背景知识,来创建一个简单测试。

获取数据

打开浏览器并点击-http://www.itxiaonv.com/V4/sinkministatement.php?CUSTOMER_ID=68195&PASSWORD=1234!&Account_No=1。确保看到的内容如下所示。

如果在尝试获取请求的响应时浏览器出现错误,

  1. 查看是否使用过https或http。浏览器可能设置为不打开不安全的网站。
  2. 查看是否有任何代理或防火墙阻止浏览器打开网站。

注意-在这里没有使用任何Header,Body,也没有Cookie。这是一个URL,而且将从API中获取内容,而不是发布。记住这一点,以便更好地理解测试。

测试的目标是:

该脚本的目标是在集成开发环境控制台上打印与通过REST Assured在浏览器上收到的输出相同的输出。

让我们用以下步骤对其进行编码:

获取响应正文

步骤1) 创建名为“myFirstRestAssuredClass”的类

步骤2) 创建名为“getResponseBody”的方法

步骤3) 与前面学习的结构类似,当然后输入以下代码

given() .->不需要Header,不需要查询或路径参数。

when() .->未设置具体条件

Get(‘http://www.itxiaonv.com/V4/sinkministatement.php?CUSTOMER_ID=68195&PASSWORD=1234!&Account_No=1’)。->只需提供url

then() .->不需要特定断言

log() . all() ->获取所有响应后,记录响应、标头,基本上记录求返回给所有内容。

public static void getResponseBody()
{
    given().when().get("http://demo.guru99.com/V4/sinkministatement.php?CUSTOMER_ID=68195&PASSWORD=1234!&Account_No=1").then().log()
    .all();
}

现在注意,使用的URL很长,可读性较差,如果仔细观察,会注意到使用了3个查询参数,它们是

  1. Customer_ID
  2. PASSWORD
  3. Account_No

REST Assured,可以帮助单独传递每个 part(query, path, header param) ,使代码更具可读性,也更易于维护。此外,还可以根据需要参数化外部文件中的数据。

为了使用查询参数,回到语法的定义,并看到所有它们都作为给定的一部分传递。

 public static void getResponseBody()
{
    given().queryParam("CUSTOMER_ID","68195")
    .queryParam("PASSWORD","1234!")
    .queryParam("Account_No","1")
    .when().get("http://www.itxiaonv.com/V4/sinkministatement.php").then().log()
    .body();
}
 

注意,我们使用了“body”而不是“all”;这有助于我们仅提取响应的正文。

输出:

getResponseBody的输出

获取响应状态代码

编写的下一个方法将是获取状态代码,并放置一个断言来验证它。

步骤1) 创建名为 getResponseStatus() 的方法

步骤2) 使用上面使用的相同求结构。复制并粘贴它。

步骤3) 不做日志记录,而是使用RESTAssured内置的‘getStatusCode’方法获取状态码值

步骤4) 为了断言状态代码是200,使用关键字-assertThat() .statusCode(expectedCode)

注意-URL是为简单起见而使用的变量。URL包含整个API求URL

 public static void getResponseStatus()
{
    int statusCode= given().queryParam("CUSTOMER_ID","68195")
                    .queryParam("PASSWORD","1234!")
                    .queryParam("Account_No","1") .when().get("http://demo.guru99.com/V4/sinkministatement.php").getStatusCode();
    System.out.println("The response status is "+statusCode);
    given().when().get(url).then().assertThat().statusCode(200) ;
}
 

getResponseStatus的输出 :

业务需求

自动化的基本规则之一是,必须设置检查点,以便只有在满足所有必需条件的情况下才能进行测试。在API测试中,最基本的验证是检查求的状态码是否为2XX格式。

到目前为止,完整的代码如下:

 import java.util.ArrayList;
import static io.restassured.RestAssured.*;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
public class myFirstRestAssuredClass
{
    final static String url="http://www.itxiaonv.com/V4/sinkministatement.php?CUSTOMER_ID=68195&PASSWORD=1234!&Account_No=1";
    public static void main(String args[])
    {
        getResponseBody();
        getResponseStatus();
        ;
    }
//This will fetch the response body as is and log it. given and when are optional here
    public static void getResponseBody()
    {
        given().when().get(url).then().log()
        .all();
        given().queryParam("CUSTOMER_ID","68195")
        .queryParam("PASSWORD","1234!")
        .queryParam("Account_No","1") .when().get("http://www.itxiaonv.com/V4/sinkministatement.php").then().log().body();
    }
    public static void getResponseStatus()
    {
        int statusCode= given().queryParam("CUSTOMER_ID","68195")
                        .queryParam("PASSWORD","1234!")
                        .queryParam("Account_No","1")
                        .when().get("http://www.itxiaonv.com/V4/sinkministatement.php").getStatusCode();
        System.out.println("The response status is "+statusCode);
        given().when().get(url).then().assertThat().statusCode(200) ;
    }
}
 

注:

  1. 200 是对此场景的成功响应。有时,需要求失败,尝试通过提供无效参数和检查来更改状态代码。
  2. 当断言一个条件时,控制台上将不会打印,除非出现错误。

获取响应的不同部分的脚本

拉取响应正文和响应状态码已经在上面的段落中介绍过了。值得注意的是,要获取响应的不同部分,关键字‘Extract’非常重要。

标题

REST Assured是一种非常简单的语言,获取报头也同样简单。与前面一样,创建一个独立的方法来执行相同的操作。

 public static void getResponseHeaders()
{
    System.out.println("The headers in the response "+
                       get(url).then().extract()
                       .headers());
}
 

注意,这里跳过了‘Given()’,并且代码行从Get()开始,这是因为这里没有进行前置条件或验证来命中求并获得响应。在这种情况下,可以选择使用相同的。

getResponseHeader输出:

业务需求:

很多时候,需要为后续求使用授权令牌或会话cookie,并且大多数情况下,这些详细信息作为响应的头部返回。

响应时间

为了获得从后端或其他下游系统获取响应所需的时间,RESTAssured提供了一个名为“timein”的方法,并提供了一个合适的timeUnit来获取返回响应时间。

 public static void getResponseTime()
{
    System.out.println("The time taken to fetch the response "+get(url)
                       .timeIn(TimeUnit.MILLISECONDS) + " milliseconds");
}
 

getResponseTime的输出:

业务需求:

测试API的一个非常重要的特性是它们的响应时间,以衡量应用程序的性能。注意,根据网速、当时API的性能、服务器负载以及其他影响时间的因素,响应时间可能会增加或减少。

内容-类型

可以通过方法为“contentType()”获取返回的Content-Type。

 public static void getResponseContentType()
{
    System.out.println("The content type of response "+
                       get(url).then().extract()
                       .contentType());
}
 

getContentType的输出

业务需求:

有时,获取内容类型对于确保没有任何跨源威胁的安全漏洞,或者仅仅是为了确保传递的内容符合API的标准,是非常重要的。

获取单个JSON元素

根据给定的响应,系统会要求计算总金额,需要提取每个金额并将其相加。

步骤:

步骤1) AMOUNT字段位于关键字为“Statements”的数组中,该数组依次位于关键字为“Result”的列表中

步骤2) REST Assured提供使用Path到达接口中值的机制

步骤3) 到达AMOUNT的路径是“result t.statements.AMOUNT”。可以将其视为Selenium中的XPath。

步骤4) 获取集合中的所有金额,然后对所有值进行循环以计算总和

 public static void getSpecificPartOfResponseBody()
{
    ArrayList<String> amounts = when().get(url).then().extract().path("result.statements.AMOUNT") ;
    int sumOfAll=0;
    for(String a:amounts)
    {
        System.out.println("The amount value fetched is "+a);
        sumOfAll=sumOfAll+Integer.valueOf(a);
    }
    System.out.println("The total amount is "+sumOfAll);
}
 

注意:由于AMOUNT为字符串数据类型,因此我们将其转换为整数并将其用于求和。

getSpecificPartOfResponse的输出:

总结:

  • REST Assured 是一组java库,能够自动执行REST api测试。
  • REST Assured 是基于JAVA的,学习JAVA知识就足够了
  • 帮助从复杂的JSON结构中获取求值和响应值
  • 可以使用各种header、query、path参数以及要设置任何会话或cookie来自定义API求。
  • 有助于设置Assert语句和条件。
  • 虽然REST Assured在响应为JSON类型时非常有用,但如果内容类型为id HTML或纯文本,可能无法无缝工作。

IT赶路人

专注IT知识分享