这段代码使用了 Rest-Assured 进行 API 测试,结合 TestNG 框架执行多个 HTTP 请求并进行断言验证。以下是对每个测试方法的详细解释,包括代码逻辑和测试目的。
1. test01() 方法 - 提取响应数据
@Test
public void test01() {
String jsonData = "{\"principal\":\"lemon_auto\",\"credentials\":\"lemon123456\",\"appType\":3,\"loginType\":0}";
Response response =
given().
header("Content-Type", "application/json; charset=UTF-8").
body(jsonData).
when().
post("http://mall.lemonban.com:8107/login").
then().
log().all().
extract().response();
// 提取响应数据
String tokenValue = response.jsonPath().get("userId");
System.out.println(tokenValue);
}
代码逻辑:
-
目标:该测试发送一个 POST 请求进行登录,并从响应中提取
userId字段。 -
步骤:
- 使用
given()设置请求头和请求体。 - 使用
when()发送 POST 请求。 - 使用
then()打印响应并提取响应内容(使用jsonPath()方法获取userId字段)。 - 打印提取到的
userId。
- 使用
用途:
测试如何从 JSON 响应中提取字段(如 userId)。适用于需要从响应中提取数据的情况。
2. test_json() 方法 - 提取 JSON 响应中的数据
@Test
public void test_json() {
String jsonData = "{\"principal\":\"lemon_auto\",\"credentials\":\"lemon123456\",\"appType\":3,\"loginType\":0}";
Response response = given()
.log().all()
.queryParam("prodName", "测试")
.queryParam("sort", 0)
.queryParam("orderBy", 0)
.queryParam("current", 1)
.when()
.get("http://mall.lemonban.com:8107/search/searchProdPage")
.then()
.log().all()
.extract().response();
// 提取响应数据中的产品ID列表
List<Object> list = response.jsonPath().getList("records.prodId");
System.out.println(list);
}
代码逻辑:
-
目标:该测试发送一个 GET 请求,获取产品信息,并提取产品 ID 列表。
-
步骤:
- 使用
given()设置查询参数。 - 发送 GET 请求并提取 JSON 响应。
- 使用
jsonPath()提取records.prodId列表。 - 打印提取到的产品 ID 列表。
- 使用
用途:
该方法展示了如何提取 JSON 响应中的数组数据。可以用于从响应体中提取多个相同类型的元素(如产品 ID)。
3. test_html() 方法 - 提取 HTML 响应中的数据
@Test
public void test_html() {
String jsonData = "{\"principal\":\"lemon_auto\",\"credentials\":\"lemon123456\",\"appType\":3,\"loginType\":0}";
Response response =
given()
.log().all()
.queryParam("prodName", "测试")
.queryParam("sort", 0)
.queryParam("orderBy", 0)
.queryParam("current", 1)
.when()
.get("https://www.baidu.com/")
.then()
.log().all()
.extract().response();
Object value = response.htmlPath().get("html.head.title");
System.out.println(value);
}
代码逻辑:
-
目标:该测试发送一个 GET 请求获取百度首页,并提取 HTML 响应中的
title标签内容。 -
步骤:
- 发送 GET 请求到百度首页。
- 使用
htmlPath()提取 HTML 内容中的title标签。 - 打印提取到的
title内容。
用途:
该方法展示了如何提取 HTML 响应中的元素,常用于测试网页内容(如标题、元数据等)。
4. test_xml() 方法 - 提取 XML 响应中的数据
@Test
public void test_xml() {
Response response =
given()
.log().all()
.header("Content-Type","application/json; charset=UTF-8")
.when()
.get("http://httpbin.org/xml")
.then()
.log().all()
.extract().response();
Object value = response.xmlPath().get("slideshow.slide[1].item[0]");
System.out.println("\n打印结果为:" + value);
}
代码逻辑:
-
目标:该测试发送一个 GET 请求,获取 XML 格式的响应数据,并提取特定元素值。
-
步骤:
- 发送 GET 请求获取 XML 响应。
- 使用
xmlPath()提取slideshow.slide[1].item[0]元素。 - 打印提取到的值。
用途:
展示了如何从 XML 响应中提取数据,适用于解析 XML 格式的响应。
5. test_assert() 方法 - 使用断言验证响应
@Test
public void test_assert() {
String jsonData = "{\"principal\":\"lemon_auto\",\"credentials\":\"lemon123456\",\"appType\":3,\"loginType\":0}";
Response response =
given()
.header("Content-Type","application/json; charset=UTF-8")
.body(jsonData)
.when()
.post("http://mall.lemonban.com:8107/login")
.then()
.log().all()
.extract().response();
int statusCode = response.statusCode();
Object actualvalue = response.jsonPath().get("nickName");
Assert.assertEquals(statusCode, 200);
Assert.assertEquals(actualvalue, "lemon_auto");
System.out.println("打印结果为:" + actualvalue);
}
代码逻辑:
-
目标:发送 POST 请求进行登录,断言响应的状态码为 200,并验证
nickName字段的值是否为lemon_auto。 -
步骤:
- 发送 POST 请求进行登录,获取响应。
- 提取响应的状态码和
nickName字段。 - 使用
Assert.assertEquals()断言状态码和nickName是否符合预期。 - 打印
nickName的值。
用途:
该方法展示了如何使用 TestNG 的断言功能进行验证,确保接口返回正确的状态码和数据。适用于验证 API 响应的正确性。
总结
这段代码展示了如何使用 Rest-Assured 提取和验证不同格式的响应数据(JSON、HTML、XML),以及如何使用 TestNG 进行断言验证。每个方法展示了不同的功能和用例,适用于不同类型的 API 测试。
test01():提取 JSON 响应中的userId字段。test_json():提取 JSON 响应中的列表数据。test_html():提取 HTML 响应中的title标签内容。test_xml():提取 XML 响应中的指定元素。test_assert():通过断言验证响应的状态码和字段值。
这些方法可以作为测试 RESTful API 时的数据提取和断言验证模板,帮助我们更高效地进行接口测试。
明白了,你的目标是想要一份完整的解释文档,包括:
- 每段代码的作用是什么(功能解释)
- 为什么要这么写(逻辑思维)
我现在按你的代码顺序,把每一步代码段 + 详细解释 + 编码逻辑原因组合起来,便于你理解、讲解或做笔记。
Mall 商城接口测试代码逐步解析(含逻辑与原因)
第 1 步:用户登录
String jsonData = "{\"principal\":\"lemon_auto\",\"credentials\":\"lemon123456\",\"appType\":3,\"loginType\":0}";
Map<String, Object> map = new HashMap<>();
map.put("Content-Type", "application/json; charset=UTF-8");
Response response1 = request("post", "http://mall.lemonban.com:8107/login", map, jsonData);
String token = response1.jsonPath().get("access_token");
String token_type = response1.jsonPath().get("token_type");
String tokenValue = token_type + token;
解释:
- 构造 JSON 登录请求体
- 调用登录接口获取
access_token和token_type - 拼接成完整的认证信息
Authorization头使用(如Bearer abc123...)
逻辑原因:
- 所有后续操作都必须用户登录后进行
- 拼接 token 是因为服务器要求
Authorization格式是token_type + access_token
第 2 步:搜索商品,获取 prodId
Response response2 = request("get", "http://mall.lemonban.com:8107/search/searchProdPage", map, null);
Object prodId = response2.jsonPath().get("records.prodId[0]");
解释:
- 调用商品搜索接口,获取商品列表
- 提取第一个商品的
prodId(商品 ID)
逻辑原因:
- 添加购物车必须提供 prodId,不能写死
- 搜索是获取有效商品 ID 的唯一办法,确保数据是存在的
第 3 步:商品详情页,获取 shopId 和 skuId
Response response3 = given()
.log().all()
.queryParam("prodId", prodId)
.when()
.get("http://shop.lemonban.com:8107/prod/prodInfo?prodId=5826")
.then()
.log().all().extract().response();
int shopId = response3.jsonPath().get("shopId");
int skuId = response3.jsonPath().get("skuList.skuId[0]");
解释:
- 通过
prodId获取商品详细信息 - 提取店铺 ID(shopId)和商品规格 ID(skuId)
逻辑原因:
shopId是订单所属店铺编号skuId是规格 ID,例如颜色、尺寸,必须传入添加购物车接口
第 4 步:构造请求体并添加商品到购物车
int basketId = 0;
String jsonData4 = String.format(
"{\"basketId\":%d,\"count\":1,\"prodId\":\"%s\",\"shopId\":%d,\"skuId\":%d}",
basketId, prodId, shopId, skuId
);
Response response4 = given()
.log().all()
.header("Content-Type", "application/json; charset=UTF-8")
.header("Authorization", tokenValue)
.body(jsonData4)
.when()
.post("http://shop.lemonban.com:8107/p/shopCart/changeItem")
.then()
.log().all().extract().response();
解释:
- 构造添加购物车请求体
- 调用接口将商品加入购物车(
basketId=0表示新增)
逻辑原因:
- 添加购物车必须传 token、商品 ID、skuId、shopId
- 使用
String.format拼接参数,提高代码清晰度和可维护性
第 5 步:查询购物车,获取 basketId
String jsonData5 = "[]";
Response response5 = given()
.log().all()
.header("Content-Type", "application/json; charset=UTF-8")
.header("Authorization", tokenValue)
.body(jsonData5)
.when()
.post("http://shop.lemonban.com:8107/p/shopCart/info")
.then()
.log().all().extract().response();
Object basket_id = response5.jsonPath().get("shopCartItemDiscounts[0].shopCartItems[0].basketId");
解释:
- 查询当前购物车所有条目
- 提取刚刚加入的商品对应的
basketId
逻辑原因:
- 后续下单接口并不使用 prodId,而是基于 basketId 提交商品项
第 6 步:确认订单,生成 uuid
String jsonData6 = "{\"addrId\":0,\"basketIds\":[" + basket_id + "],\"couponIds\":[],\"isScorePay\":0,\"userChangeCoupon\":0,\"userUseScore\":0,\"uuid\":\"4ce81ad2-bb8b-4f3a-9d78-bd964638ee33\"}";
Response response6 = given()
.log().all()
.header("Content-Type", "application/json; charset=UTF-8")
.header("Authorization", tokenValue)
.body(jsonData6)
.when()
.post("http://shop.lemonban.com:8107/p/order/confirm HTTP/1.1")
.then()
.log().all().extract().response();
解释:
- 提交购物车商品,用于确认订单信息
uuid是订单临时标识,必须保留用于下一步提交
逻辑原因:
- 订单系统需要先做库存校验、地址匹配,生成确认订单内容
uuid是防重复、防篡改机制,必须通过确认接口生成
第 7 步:提交订单
String jsonData7 = "{\"orderShopParam\":[{\"remarks\":\"\",\"shopId\":1}],\"uuid\":\"6c205fc4-7ff8-4130-843b-2c2a32f19ff5\"}";
Response response7 = given()
.log().all()
.header("Content-Type", "application/json; charset=UTF-8")
.header("Authorization", tokenValue)
.body(jsonData7)
.when()
.post("http://shop.lemonban.com:8107/p/order/submit HTTP/1.1")
.then()
.log().all().extract().response();
解释:
- 正式下单
- 使用上一步生成的
uuid和shopId提交订单
逻辑原因:
- 提交订单必须是“已确认”的商品
- 如果缺少 uuid 或 shopId,接口会报错或拒绝下单
✅总结(整段逻辑一图看清)
1. 登录 -> 拿 token
2. 搜索商品 -> 拿 prodId
3. 商品详情 -> 拿 shopId + skuId
4. 添加购物车 -> 传 token + 商品信息
5. 查询购物车 -> 拿 basketId
6. 确认订单 -> 拿 uuid
7. 提交订单 -> 用 uuid + shopId 正式下单
每一步都有前置依赖,必须按顺序执行,任何步骤跳过都将导致下一步失败。
731

被折叠的 条评论
为什么被折叠?



