Ohhnews

分类导航

$ cd ..
DZone Java原文

如何在REST-Assured Java中进行API测试响应验证:第2部分

#rest assured#hamcrest#api测试#响应验证#java

API 测试是现代软件开发中不可或缺的一部分。虽然发送请求和接收响应很简单,但 API 自动化的真正价值来自响应验证。只有当测试验证 API 返回了正确的数据、结构、状态码和业务规则时,它才有意义。在基于 Java 的 API 自动化中,REST Assured 与 Hamcrest Matchers 结合,提供了一种干净且富有表现力的方式来验证 API 响应。这些匹配器帮助测试人员编写可读的断言,以最少的代码验证数字、字符串、数组、JSON 对象和集合。

本教程解释如何使用以下 Hamcrest Matchers 在 REST Assured 中执行响应验证:

  • 数值
  • 字符串
  • 集合
  • JSON 对象验证
  • 负向验证

读完本文后,你将能够在自动化测试中编写强大且可维护的 API 断言。

如果你还没有看过,点击这里阅读本博客文章的第 1 部分。

响应验证 是验证服务器返回的 API 响应的过程。这包括检查状态码、响应体值、JSON 结构、响应头、数据类型、数组、对象以及业务验证。验证包括检查:

  • API 响应是否返回 200 OK 状态码?
  • 响应是否包含字段的预期值?
  • 列表大小是否大于零?
  • 每个对象是否都包含特定键?

如果没有断言,API 测试只是发送请求和接收响应,而没有真正检查 API 是否行为正确。

如何在 REST-Assured Java 中使用 Hamcrest Matchers 和 Rest-Assured 进行响应验证

Hamcrest Matchers 提高了可读性,并使断言更具表现力。要使用 Hamcrest,应在 Maven 项目的 pom.xml 中添加以下依赖:

$ xml
<dependency>
    <groupId>org.hamcrest</groupId>
    <artifactId>hamcrest</artifactId>
    <version>3.0</version>
    <scope>test</scope>
</dependency>

数值匹配器

本节中,我们将学习在 Rest-Assured 测试中使用数值匹配器,包括 greaterThan()greaterThanOrEqualTo()lessThan()lessThanOrEqualTo()。这些断言有助于验证 API 响应中返回的数值。

使用 greaterThan() 和 greaterThanOrEqualTo()

greaterThan() 匹配器验证数值大于预期值。同样,greaterThanOrEqualTo() 匹配器验证该值大于或等于预期数字。

$ java
@Test
public void testGreaterThanAssertions () {
 given ().when ()
 .get ("https://api.restful-api.dev/objects")
 .then ()
 .statusCode (200)
 .and ()
 .assertThat ()
 .body ("[2].data['capacity GB']", greaterThan (500))
 .body ("[5].data['price']", greaterThanOrEqualTo (120));
}

在这个测试中,来自 Hamcrest 库的 greaterThan() 方法验证第三个 JSON 对象中的 capacity GB 值大于 500greaterThanOrEqualTo 匹配器检查第六个对象中的 price 值是否大于或等于 120。这些断言有助于验证 API 返回的数值,而不依赖精确匹配。数值匹配器对于测试价格、计数、容量和响应时间等值非常有用。

使用 lessThan() 和 lessThanOrEqualTo()

lessThan() 匹配器验证值低于预期数字。同样,lessThanOrEqualTo() 匹配器验证数字小于或等于预期值。

$ java
@Test
public void testLessThanAssertions () {
 given ().when ()
 .log ()
 .all ()
 .get ("https://api.restful-api.dev/objects")
 .then ()
 .log ()
 .all ()
 .statusCode (200)
 .and ()
 .assertThat ()
 .body ("[4].data['price']", lessThan (700f))
 .body ("[6].data['year']", lessThanOrEqualTo (2019));
}

在这个测试中,来自 Hamcrest 库的 lessThan() 方法验证第五个 JSON 对象中的 price 值小于 700,而 lessThanOrEqualTo() 检查第七个对象中的 year 值是否小于或等于 2019。值 700f 带有 "f" 后缀,是因为 API 将价格返回为 float,使用 "f" 可确保预期值在比较时也被视为 float。这些断言有助于确保 API 返回的数值保持在预期范围内。

字符串匹配器

本节中,我们将学习在 Rest-Assured 测试中使用字符串匹配器,包括 equalToIgnoringCase()containsString()startsWith()endsWith()equalToCompressingWhiteSpace()。这些断言可用于验证 API 响应中返回的文本值。

$ java
@Test
public void testStringAssertion() {
 given ().when ()
 .log ()
 .all ()
 .queryParam ("id", 3)
 .get ("https://api.restful-api.dev/objects")
 .then ()
 .log ()
 .all ()
 .statusCode (200)
 .and ()
 .assertThat ()
 .body ("[0].name", equalTo ("Apple iPhone 12 Pro Max"))
 .body ("[0].name", equalToIgnoringCase ("ApPLE IPhone 12 pro MAX"))
 .body ("[0].data.color", containsString ("White"))
 .body ("[0].name", startsWith ("A"))
 .body ("[0].name", endsWith ("x"))
 .body ("[0].name", equalToCompressingWhiteSpace (" Apple iPhone 12 Pro Max "));
}

testStringAssertion() 方法演示了使用 REST Assured 和 Hamcrest 匹配器验证 API 响应中字符串值的不同方式:

  • body("[0].name", equalTo ("Apple iPhone 12 Pro Max")):验证 name 字段与预期字符串完全匹配,包括字母大小写和空格。
  • body("[0].name", equalToIgnoringCase("ApPLE IPhone 12 pro MAX")):在忽略大小写差异的情况下验证字符串值。
  • body("[0].data.color", containsString("White")):验证 color 字段是否在字符串任意位置包含文本 White
  • body("[0].name", startsWith("A")):验证 name 字段以字母 "A" 开头。
  • body("[0].name", endsWith("x")):验证 name 字段以字母 "x" 结尾。
  • body("[0].name", equalToCompressingWhiteSpace(" Apple iPhone 12 Pro Max ")):在删除多余空格并将多个空白字符压缩为单个空格后比较字符串值,使断言对格式差异更灵活。

这些匹配器有助于验证精确文本、部分文本、前缀、后缀、大小写敏感性和空白格式。

集合匹配器

本节中,我们将学习在 Rest-Assured 测试中使用集合匹配器,包括 hasSize()hasItem()hasKey()everyItem(hasKey())。这些断言有助于验证 API 响应中返回的数组和集合,例如验证项目数量、检查特定值,以及确保所需键存在。

使用 hasSize() 和 hasItem() 匹配器

$ java
@Test
public void testHasSizeAndHasItem () {
 given ().when ()
 .queryParam ("id", 3)
 .queryParam ("id", 5)
 .get ("https://api.restful-api.dev/objects")
 .then ()
 .statusCode (200)
 .and ()
 .assertThat ()
 .body ("$", hasSize (2))
 .body ("name", hasItem ("Apple iPhone 12 Pro Max"));
}

testHasSizeAndHasItem() 方法演示了如何使用 REST Assured 中的 Hamcrest 匹配器验证 API 响应中返回的集合和数组。它使用 Hamcrest 匹配器中的 hasSize()hasItem() 方法来验证响应集合的大小以及其中是否存在特定项目。

  • body("$", hasSize(2))hasSize() 匹配器验证响应数组正好包含 "2" 个对象。由于请求发送了两个查询参数(id=3 和 id=5),API 预期返回两条匹配记录。
  • body("name", hasItem("Apple iPhone 12 Pro Max"))hasItem() 匹配器检查响应中的 name 集合是否包含值 "Apple iPhone 12 Pro Max"。此断言有助于验证返回响应中存在特定项目。

使用 hasKey() 和 everyItem(hasKey()) 匹配器

$ java
@Test
public void testHasKeyAssertions () {
 given ().when ()
 .log ()
 .all ()
 .queryParam ("id", 3)
 .get ("https://api.restful-api.dev/objects")
 .then ()
 .log ()
 .all ()
 .statusCode (200)
 .and ()
 .assertThat ()
 .body ("$", everyItem (hasKey ("id")))
 .body ("[0].data", hasKey ("capacity GB"))
 .body ("$", everyItem (hasKey ("name")));
}

testHasKeyAssertions() 方法展示了如何验证 API 响应返回的 JSON 对象中是否存在键。hasKey() 匹配器通常用于确保响应中存在必需字段。

  • body("$", everyItem(hasKey("id")))everyItem(hasKey()) 断言验证响应数组中的每个对象都包含 "id" 键。这有助于确保所有返回对象的一致性。
  • body("[0].data", hasKey("capacity GB"))hasKey() 匹配器检查第一个响应项的 data 对象是否包含键 "capacity GB"。此断言验证嵌套 JSON 对象中特定字段的存在。
  • body("$", everyItem(hasKey("name"))):此断言验证响应数组中的所有对象都包含 name 键。它确保 API 响应中每条返回记录都包含预期字段。

负向验证

Rest-Assured 中的负向验证通常使用 Hamcrest 的 not() 否定匹配器来执行,以验证 API 响应不包含某些值或条件。使用 not() 匹配器可以反转条件,从而相应地断言 API 响应中不存在指定值或条件。

$ java
@Test
public void testNotAssertions () {
 given ().when ()
 .log ()
 .all ()
 .queryParam ("id", 3)
 .get ("https://api.restful-api.dev/objects")
 .then ()
 .log ()
 .all ()
 .statusCode (200)
 .and ()
 .assertThat ()
 .body ("$", not (emptyArray ()))
 .body ("[0].id", notNullValue ())
 .body ("[0].name", not (equalTo ("Samsung")))
 .body ("[0].data['capacity GB']", not (greaterThan (550)));
}

testNotAssertions() 方法演示了如何使用 not() 匹配器及相关断言在 Rest-Assured 中执行负向验证。

  • body("$", not(emptyArray())):此断言验证响应数组不为空,并且至少包含一个对象。
  • body("[0].id", notNullValue())notNullValue() 匹配器验证第一个响应对象中的 "id" 字段不为 null。
  • body("[0].name", not (equalTo ("Samsung"))):此断言验证 name 字段不等于 "Samsung"
  • body("[0].data['capacity GB']", not(greaterThan(550)))not(greaterThan()) 断言验证 "capacity GB" 值不大于 550。这意味着该值应小于或等于 550。

[LOADING...]

总结

响应验证将 API 测试从仅仅发送请求转变为真正验证应用程序行为。在本教程中,我们探索了 REST Assured 和 Hamcrest Matchers 如何通过验证数字、字符串、数组、JSON 键和响应结构,使断言更可读、更强大。根据我的经验,学习这些匹配器可以显著提高 API 自动化框架的质量和可维护性。数值、字符串、集合和负向匹配器在实际测试中尤其有用,因为它们有助于创建既灵活又易于理解的验证,从而使调试和测试维护随着时间的推移变得更加简单。测试愉快!!