使用 Rest-Assured 和 TestNG 进行购物车功能的 API 自动化测试

这段代码使用了 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 字段。

  • 步骤

    1. 使用 given() 设置请求头和请求体。
    2. 使用 when() 发送 POST 请求。
    3. 使用 then() 打印响应并提取响应内容(使用 jsonPath() 方法获取 userId 字段)。
    4. 打印提取到的 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 列表。

  • 步骤

    1. 使用 given() 设置查询参数。
    2. 发送 GET 请求并提取 JSON 响应。
    3. 使用 jsonPath() 提取 records.prodId 列表。
    4. 打印提取到的产品 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 标签内容。

  • 步骤

    1. 发送 GET 请求到百度首页。
    2. 使用 htmlPath() 提取 HTML 内容中的 title 标签。
    3. 打印提取到的 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 格式的响应数据,并提取特定元素值。

  • 步骤

    1. 发送 GET 请求获取 XML 响应。
    2. 使用 xmlPath() 提取 slideshow.slide[1].item[0] 元素。
    3. 打印提取到的值。
用途

展示了如何从 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

  • 步骤

    1. 发送 POST 请求进行登录,获取响应。
    2. 提取响应的状态码和 nickName 字段。
    3. 使用 Assert.assertEquals() 断言状态码和 nickName 是否符合预期。
    4. 打印 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 时的数据提取和断言验证模板,帮助我们更高效地进行接口测试。





明白了,你的目标是想要一份完整的解释文档,包括:

  1. 每段代码的作用是什么(功能解释)
  2. 为什么要这么写(逻辑思维)

我现在按你的代码顺序,把每一步代码段 + 详细解释 + 编码逻辑原因组合起来,便于你理解、讲解或做笔记。


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_tokentoken_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();

解释:

  • 正式下单
  • 使用上一步生成的 uuidshopId 提交订单

逻辑原因:

  • 提交订单必须是“已确认”的商品
  • 如果缺少 uuid 或 shopId,接口会报错或拒绝下单

✅总结(整段逻辑一图看清)

1. 登录 -> 拿 token
2. 搜索商品 -> 拿 prodId
3. 商品详情 -> 拿 shopId + skuId
4. 添加购物车 -> 传 token + 商品信息
5. 查询购物车 -> 拿 basketId
6. 确认订单 -> 拿 uuid
7. 提交订单 -> 用 uuid + shopId 正式下单

每一步都有前置依赖,必须按顺序执行,任何步骤跳过都将导致下一步失败。


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值