REST Assured API 自动化测试教程(示例)
什么是 Rest Assured?
放心 使您能够使用 Java 库测试 REST API,并与 Maven 很好地集成。它具有非常高效的匹配技术,因此断言您的预期结果也非常简单。无论 JSON 结构有多复杂,Rest Assured 都有方法从请求和响应的几乎每个部分获取数据。
对于测试社区来说,API 自动化测试仍然是新兴且小众的。JSON 的复杂性使得 API 测试尚未得到探索。但这并不会降低它在测试过程中的重要性。Rest Assured.io 框架使用核心 Java 基础知识使其变得非常简单,使其成为非常值得学习的东西。
为什么需要 Rest-Assured?
想象一下,你打开谷歌地图视图并寻找你想去的地方,你立即看到附近的餐馆,你看到通勤的选择;来自一些领先的旅游提供商,你指尖就能看到这么多的选择。我们都知道它们不是谷歌产品,那么谷歌是如何展示它的呢?他们使用这些提供商公开的 API。现在,如果你被要求测试这种设置,即使在 UI 构建或开发之前,测试 API 也变得非常重要,并且使用不同的数据组合反复测试它们,使其成为非常适合自动化的情况。
之前我们都是使用动态语言比如groovy,ruby来实现这个,难度比较大,所以API测试并没有通过功能测试来进行探索。
但是,如果一个人具有基本的 Java 背景,那么使用 Rest Assured 进行 API 的自动化测试、发送具有用户友好自定义的简单 https 请求就很简单了。需要了解 API 测试和集成测试,但发布自动化 Rest Assured 可以对后端提供非常好的信心,而前端测试可以只关注 UI 和客户端操作。Rest Assured 是一个开源软件,它添加了许多附加方法和库,使其成为 API 自动化的绝佳选择。
如何设置 Rest Assured.io Eclipse
步骤 1) 安装 Java。参考这个 指南
步骤 2)下载 IDE 并开始: 蚀
步骤 3) 安装 Maven 并设置你的 eclipse。参考 点击这里.
安心设置
- 在您的 IDE 中创建一个 Maven 项目。我们使用的是 Intellij,但您在使用的任何 IDE 上都会获得类似的结构。
- 打开你的 POM.xml
对于 Rest Assured.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>
对于 Rest Assured.io : 对于 Java 版本 9+ 用户:
<dependency> <groupId>io.rest-assured</groupId> <artifactId>rest-assured-all</artifactId> <version>4.2.0</version> <scope>test</scope> </dependency>
故障排除:
如果你看到错误,并且不确定依赖项是否已下载完毕,
- 执行 maven build 来导入所有依赖项,同样,您还会在 guru99 上找到有关 Maven 设置的帮助。
- 尽管如此,您仍然会看到错误,然后执行 maven clean,然后执行 maven install,它应该会顺利构建。
- 您可以在 java 类中添加以下几行,并且不会看到任何编译错误。
import io.restassured.RestAssured.*; import io.restassured.matcher.RestAssuredMatchers.*; import org.hamcrest.Matchers.*;
第一个简单的 Rest Assured 脚本
语法:
Rest Assured.io 的语法是最漂亮的部分,因为它非常像 BDD 并且易于理解。
Given(). param("x", "y"). header("z", "w"). when(). Method(). Then(). statusCode(XXX). body("x, ”y", equalTo("z"));
说明:
代码 | 说明 |
---|---|
给定() | 'Given' 关键字,让您设置背景,在这里,您可以传递请求标头、查询和路径参数、正文、cookie。如果请求中不需要这些项目,则这是可选的 |
什么时候() | “when”关键字标记了场景的前提。例如,“当”你获取/发布/放置某物时,做其他事。 |
方法() | 用任何 CRUD 操作(get/post/put/delete)替代它 |
然后() | 您的断言和匹配条件放在这里 |
现在您已完成设置并掌握了一些语法背景,让我们来创建第一个简单测试。如果到目前为止,该结构对您来说似乎很陌生,那也没关系,随着您进一步解释每一行代码,您就会掌握它。
你要去拿什么?
打开浏览器并点击 – http://demo.guru99.com/V4/sinkministatement.php?CUSTOMER_ID=68195&PASSWORD=1234!&Account_No=1
. 确保您看到如下所示的内容。
如果您在尝试获取请求的响应时浏览器出现错误,
- 看看你是否使用过Https或Http。你的浏览器可能设置不打开不安全的网站。
- 查看是否有任何代理或防火墙阻止您的浏览器打开网站。
*备注 – 您在这里没有使用任何标头、正文和 cookie。这是一个 URL,而且您从 API 获取内容,而不是发布或更新任何现有内容,因此这是一个 GET 调用。记住这一点,以便更好地理解我们的第一个测试。
测试目标:
该脚本的目标是在您的 IDE 控制台上打印与您通过 Rest Assured 在浏览器上收到的内容相同的输出。
让我们按照以下步骤进行编码:
获取响应主体
步骤1) 创建一个名为“myFirstRestAssuredClass”的类
步骤2) 创建一个名为“getResponseBody”的方法
步骤3) 与前面学习的 given、when 和 then 结构类似,输入下面的代码
given()。-> 不需要标题,不需要查询或路径参数。
when()。-> 没有特定条件设置
得到('http://demo.guru99.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 个查询参数,它们是
- 客户ID
- 密码
- 户口号码
Rest Assured 帮助我们分别传递每个部分(查询、路径、标头参数),使代码更易读且易于维护。此外,我们可以根据需要从外部文件参数化数据。
对于使用查询参数,我们回到语法的定义,并看到所有它们都作为给定的一部分传递。
public static void getResponseBody(){ given().queryParam("CUSTOMER_ID","68195") .queryParam("PASSWORD","1234!") .queryParam("Account_No","1") .when().get("http://demo.guru99.com/V4/sinkministatement.php").then().log() .body(); }
**请注意,我们使用“body”而不是“all”;这有助于我们仅提取响应的主体。
输出:
获取响应状态码
我们编写的下一个方法将是获取状态代码并提出断言来验证它。
步骤1) 创建一个名为 getResponseStatus() 的方法
步骤2) 使用与上面相同的请求结构。复制并粘贴。
步骤3) 我们不记录它,而是使用 Rest Assured 的内置方法“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); }
输出:
业务需求
自动化的基本规则之一是我们必须设置检查点,以便只有满足所有必需条件时测试才会继续。在 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://demo.guru99.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://demo.guru99.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://demo.guru99.com/V4/sinkministatement.php").getStatusCode(); System.out.println("The response status is "+statusCode); given().when().get(url).then().assertThat().statusCode(200); } }
*注意:
- 对于这种情况,200 是成功响应。有时,您也需要请求失败,那么您可能会使用 4XX 或 5XX。请尝试通过提供无效参数并检查来更改状态代码。
- 当我们断言一个条件时,除非出现错误,否则控制台上不会打印任何内容。
用于获取响应不同部分的脚本
上文已经介绍了如何获取响应主体和响应状态码。值得注意的是,要获取响应的不同部分,关键字“extract”非常重要。
标题
Rest Assured 是一种非常简单的语言,获取标头也同样简单。方法名称为 headers()。与之前一样,我们将创建一个独立方法来执行相同操作。
public static void getResponseHeaders(){ System.out.println("The headers in the response "+ get(url).then().extract() .headers()); }
请注意,这里跳过了 'given().when()',代码行从 get() 开始,这是因为这里没有先决条件或验证来命中请求并获得响应。在这种情况下,可以选择使用相同的方法。
输出:
业务需求:
很多时候,您需要使用授权令牌或会话 cookie 来进行后续请求,并且大多数情况下,这些详细信息会作为响应的标头返回。
响应时间
为了获取从后端或其他下游系统获取响应所需的时间,Rest Assured 提供了一种名为“timeIn”的方法,并使用合适的 timeUnit 来获取返回响应所需的时间。
public static void getResponseTime(){ System.out.println("The time taken to fetch the response "+get(url) .timeIn(TimeUnit.MILLISECONDS) + " milliseconds"); }
输出:
业务需求:
测试 API 的一个非常重要的特征是其响应时间,以衡量应用程序的性能。请注意,您的调用所花费的时间可能会更长或更短,具体取决于您的互联网速度、当时 API 的性能、服务器负载以及影响时间的其他因素。
内容类型
您可以使用“contentType()”方法获取返回的响应的content-Type。
public static void getResponseContentType(){ System.out.println("The content type of response "+ get(url).then().extract() .contentType()); }
输出
业务需求:
有时获取内容类型对于确保不存在任何跨域威胁的安全漏洞或只是确保传递的内容符合 API 的标准至关重要。
获取单个 JSON 元素
根据给定的响应,要求您计算总金额,您需要获取每个金额并将其加起来。
步骤:
步骤1) 金额字段位于键为“statements”的数组中,而该数组又位于键为“result”的列表中
步骤2) Rest Assured 提供了一种使用“路径”获取 API 中值的机制
步骤3) 达到金额的路径是“result.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); }
注意:由于金额值是字符串数据类型,我们将其转换为整数并用它来进行求和。
输出:
总结
- Rest Assured 是一组 Java 库,它使我们能够自动化 Rest API 测试
- 放心是 Java以及核心知识 Java 足以学习它
- 它有助于从复杂的 JSON 结构中获取请求和响应的值
- 这款 API 请求可以通过各种标头、查询、路径参数以及任何要设置的会话或 cookie 进行定制。
- 它有助于设置断言语句和条件。
- 当响应为 JSON 类型时,Rest Assured 非常有用,但如果内容类型为 HTML 或纯文本,其方法可能无法无缝运行。