Files
smart-management-auto-test/dulizhan/test_case/TestCase/接口/JoyHub/Joyhub_AfterSalesPolicy.py
zhouqi 32fd51380c feat: 新增售后政策管理接口测试用例
- 新增售后政策管理接口方法到 Dlizhan_interface.py
- 新增 AfterSalesPolicyManage.py 业务关键字层
- 新增 Joyhub_AfterSalesPolicy.py 测试用例文件
- 修复 Jenkins Allure 报告路径配置问题
2026-05-06 17:16:01 +08:00

552 lines
28 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import pytest
import allure
import logging
import requests
import json
import time
from dulizhan.library.BusinessKw.JoyHub.AfterSalesPolicyManage import AfterSalesPolicyManage
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
@allure.feature("管理后台 - 售后政策管理模块")
class TestAfterSalesPolicyManage:
policy_id = None
token_set = False
@classmethod
def setup_class(cls):
"""在整个测试类开始时登录一次所有测试用例共享token"""
logging.info("=============================================")
logging.info("=========== 开始登录获取Token ============")
logging.info("=============================================")
cls.test_case = AfterSalesPolicyManage()
username = "joytest"
password = "Zhou1599"
cls.test_case._clear_user_fingerprint(username)
url = "https://joyhub-website-manager-api-test.best-envision.com/admin-api/system/auth/login-dev"
payload = {"username": username, "password": password}
headers = {'Content-Type': 'application/json', 'tenant-id': '126'}
try:
response = requests.post(url, json=payload, headers=headers, verify=False, timeout=10)
login_response = response.json()
if login_response and login_response.get('code') == 0:
token = login_response.get('data', {}).get('accessToken', '')
if token:
cls.test_case.set_joyhub_token(token)
cls.token_set = True
logging.info("登录成功获取到Token: {}...".format(token[:20]))
else:
logging.warning("登录成功但未获取到Token")
else:
logging.error("登录失败: {}".format(login_response))
except Exception as e:
logging.error("登录异常: {}".format(str(e)))
@allure.story("验证登录")
@allure.title("测试登录接口")
def test_joyhub_login_post(self):
"""测试登录接口"""
assert self.token_set is True, "登录失败Token未设置"
logging.info("登录验证通过Token已设置")
@allure.story("验证获得售后政策分页")
@allure.title("测试获得售后政策分页接口")
def test_joyhub_after_sales_policy_page_get(self):
"""测试获得售后政策分页接口"""
with allure.step("1. 准备请求参数"):
params = {
"page_no": 1,
"page_size": 10,
"title": "",
"content": "",
"status": ""
}
allure.attach(json.dumps(params, ensure_ascii=False), name="请求参数", attachment_type=allure.attachment_type.TEXT)
with allure.step("2. 调用接口"):
resp = self.test_case.kw_joyhub_after_sales_policy_page_get(**params)
allure.attach(json.dumps(resp, ensure_ascii=False, indent=2), name="响应数据", attachment_type=allure.attachment_type.JSON)
with allure.step("3. 验证响应"):
assert resp is not None, "响应为空"
assert "code" in resp, "响应中缺少code字段"
assert resp["code"] == 0, f"请求失败code={resp.get('code')}"
assert "data" in resp, "响应中缺少data字段"
assert "list" in resp["data"], "响应中缺少list字段"
assert "total" in resp["data"], "响应中缺少total字段"
assert isinstance(resp["data"]["list"], list), "list字段不是列表类型"
assert isinstance(resp["data"]["total"], int), "total字段不是整数类型"
logging.info("获得售后政策分页列表验证通过")
@allure.story("验证创建和更新售后政策")
@allure.title("测试创建和更新售后政策接口")
def test_joyhub_after_sales_policy_create_and_update(self):
"""测试创建和更新售后政策接口"""
with allure.step("1. 先创建一个新品牌供售后政策使用"):
timestamp = int(time.time())
create_brand_resp = self.test_case.kw_joyhub_after_sales_brand_create_post(
brand_name=f"测试品牌_售后政策_{timestamp}",
after_sales_policy_id=0,
status=1
)
if create_brand_resp and create_brand_resp.get("code") == 0:
brand_id = create_brand_resp.get("data")
logging.info(f"创建测试品牌成功品牌ID: {brand_id}")
else:
pytest.skip(f"创建测试品牌失败: {create_brand_resp}")
allure.attach(json.dumps({"brand_id": brand_id}, ensure_ascii=False), name="品牌ID", attachment_type=allure.attachment_type.TEXT)
with allure.step("2. 准备创建请求参数"):
params = {
"title": f"测试售后政策_{timestamp}",
"content": f"这是测试售后政策内容_{timestamp}",
"lang": "de",
"brand_id": brand_id,
"status": 1
}
allure.attach(json.dumps(params, ensure_ascii=False), name="创建请求参数", attachment_type=allure.attachment_type.TEXT)
with allure.step("3. 调用创建接口"):
resp = self.test_case.kw_joyhub_after_sales_policy_create_post(**params)
allure.attach(json.dumps(resp, ensure_ascii=False, indent=2), name="创建响应数据", attachment_type=allure.attachment_type.JSON)
with allure.step("4. 验证创建响应"):
assert resp is not None, "响应为空"
assert "code" in resp, "响应中缺少code字段"
assert resp["code"] == 0, f"请求失败code={resp.get('code')}"
assert "data" in resp, "响应中缺少data字段"
assert isinstance(resp["data"], int), "data字段不是整数类型"
policy_id = resp["data"]
TestAfterSalesPolicyManage.policy_id = policy_id
logging.info(f"创建售后政策成功售后政策ID: {policy_id}")
with allure.step("5. 调用更新接口"):
update_timestamp = int(time.time())
update_params = {
"policy_id": policy_id,
"title": f"已更新售后政策_{update_timestamp}",
"content": f"已更新售后政策内容_{update_timestamp}",
"lang": "ja",
"brand_id": brand_id,
"status": 2
}
allure.attach(json.dumps(update_params, ensure_ascii=False), name="更新请求参数", attachment_type=allure.attachment_type.TEXT)
update_resp = self.test_case.kw_joyhub_after_sales_policy_update_put(**update_params)
allure.attach(json.dumps(update_resp, ensure_ascii=False, indent=2), name="更新响应数据", attachment_type=allure.attachment_type.JSON)
with allure.step("6. 验证更新响应"):
assert update_resp is not None, "响应为空"
assert "code" in update_resp, "响应中缺少code字段"
assert update_resp["code"] == 0, f"请求失败code={update_resp.get('code')}"
assert "data" in update_resp, "响应中缺少data字段"
assert update_resp["data"] is True, "更新售后政策失败"
logging.info("更新售后政策验证通过")
@allure.story("验证获得售后政策详情")
@allure.title("测试获得售后政策详情接口")
def test_joyhub_after_sales_policy_get_get(self):
"""测试获得售后政策详情接口"""
with allure.step("1. 先创建一个售后政策"):
timestamp = int(time.time())
create_resp = self.test_case.kw_joyhub_after_sales_policy_create_post(
title=f"详情测试售后政策_{timestamp}",
content=f"详情测试售后政策内容_{timestamp}",
lang="ja",
brand_id=12,
status=2
)
policy_id = create_resp.get("data") if create_resp and create_resp.get("code") == 0 else None
if not policy_id:
pytest.skip("创建测试售后政策失败,跳过详情测试")
allure.attach(json.dumps({"id": policy_id}, ensure_ascii=False), name="售后政策ID", attachment_type=allure.attachment_type.TEXT)
with allure.step("2. 调用获得详情接口"):
resp = self.test_case.kw_joyhub_after_sales_policy_get_get(policy_id=policy_id)
allure.attach(json.dumps(resp, ensure_ascii=False, indent=2), name="响应数据", attachment_type=allure.attachment_type.JSON)
with allure.step("3. 验证响应"):
assert resp is not None, "响应为空"
assert "code" in resp, "响应中缺少code字段"
assert resp["code"] == 0, f"请求失败code={resp.get('code')}"
assert "data" in resp, "响应中缺少data字段"
assert isinstance(resp["data"], dict), "data字段不是字典类型"
assert "id" in resp["data"], "响应中缺少id字段"
assert resp["data"]["id"] == policy_id, "返回的ID与请求的不一致"
logging.info("获得售后政策详情验证通过")
@allure.story("验证删除售后政策")
@allure.title("测试删除售后政策接口")
def test_joyhub_after_sales_policy_delete_delete(self):
"""测试删除售后政策接口"""
with allure.step("1. 先创建一个测试售后政策"):
timestamp = int(time.time())
create_resp = self.test_case.kw_joyhub_after_sales_policy_create_post(
title=f"待删除售后政策_{timestamp}",
content=f"待删除售后政策内容_{timestamp}",
lang="en",
brand_id=12,
status=2
)
policy_id = create_resp.get("data") if create_resp and create_resp.get("code") == 0 else None
if not policy_id:
pytest.skip("创建测试售后政策失败,跳过删除测试")
allure.attach(json.dumps({"id": policy_id}, ensure_ascii=False), name="待删除售后政策ID", attachment_type=allure.attachment_type.TEXT)
with allure.step("2. 调用删除接口"):
resp = self.test_case.kw_joyhub_after_sales_policy_delete_delete(policy_id=policy_id)
allure.attach(json.dumps(resp, ensure_ascii=False, indent=2), name="响应数据", attachment_type=allure.attachment_type.JSON)
with allure.step("3. 验证响应"):
assert resp is not None, "响应为空"
assert "code" in resp, "响应中缺少code字段"
assert resp["code"] == 0, f"请求失败code={resp.get('code')}"
assert "data" in resp, "响应中缺少data字段"
assert resp["data"] is True, "删除售后政策失败"
logging.info("删除售后政策验证通过")
@allure.story("验证批量删除售后政策")
@allure.title("测试批量删除售后政策接口")
def test_joyhub_after_sales_policy_delete_list_delete(self):
"""测试批量删除售后政策接口"""
with allure.step("1. 先创建两个测试售后政策"):
timestamp = int(time.time())
resp1 = self.test_case.kw_joyhub_after_sales_policy_create_post(
title=f"批量删除售后政策1_{timestamp}",
content=f"批量删除售后政策内容1_{timestamp}",
lang="de",
brand_id=12,
status=2
)
resp2 = self.test_case.kw_joyhub_after_sales_policy_create_post(
title=f"批量删除售后政策2_{timestamp}",
content=f"批量删除售后政策内容2_{timestamp}",
lang="ja",
brand_id=12,
status=2
)
policy_id1 = resp1.get("data") if resp1 and resp1.get("code") == 0 else None
policy_id2 = resp2.get("data") if resp2 and resp2.get("code") == 0 else None
if not policy_id1 or not policy_id2:
pytest.skip("创建测试售后政策失败,跳过批量删除测试")
policy_ids = [policy_id1, policy_id2]
allure.attach(json.dumps({"ids": policy_ids}, ensure_ascii=False), name="待删除售后政策IDs", attachment_type=allure.attachment_type.TEXT)
with allure.step("2. 调用批量删除接口"):
resp = self.test_case.kw_joyhub_after_sales_policy_delete_list_delete(policy_ids=policy_ids)
allure.attach(json.dumps(resp, ensure_ascii=False, indent=2), name="响应数据", attachment_type=allure.attachment_type.JSON)
with allure.step("3. 验证响应"):
assert resp is not None, "响应为空"
assert "code" in resp, "响应中缺少code字段"
assert resp["code"] == 0, f"请求失败code={resp.get('code')}"
assert "data" in resp, "响应中缺少data字段"
assert resp["data"] is True, "批量删除售后政策失败"
logging.info("批量删除售后政策验证通过")
@allure.feature("管理后台 - 售后政策-品牌管理模块")
class TestAfterSalesBrandManage:
brand_id = None
policy_id = None
token_set = False
@classmethod
def setup_class(cls):
"""在整个测试类开始时登录一次所有测试用例共享token"""
logging.info("=============================================")
logging.info("=========== 开始登录获取Token ============")
logging.info("=============================================")
cls.test_case = AfterSalesPolicyManage()
username = "joytest"
password = "Zhou1599"
cls.test_case._clear_user_fingerprint(username)
url = "https://joyhub-website-manager-api-test.best-envision.com/admin-api/system/auth/login-dev"
payload = {"username": username, "password": password}
headers = {'Content-Type': 'application/json', 'tenant-id': '126'}
try:
response = requests.post(url, json=payload, headers=headers, verify=False, timeout=10)
login_response = response.json()
if login_response and login_response.get('code') == 0:
token = login_response.get('data', {}).get('accessToken', '')
if token:
cls.test_case.set_joyhub_token(token)
cls.token_set = True
logging.info("登录成功获取到Token: {}...".format(token[:20]))
else:
logging.warning("登录成功但未获取到Token")
else:
logging.error("登录失败: {}".format(login_response))
except Exception as e:
logging.error("登录异常: {}".format(str(e)))
# 创建一个售后政策供品牌测试使用
if cls.token_set:
timestamp = int(time.time())
# 先创建一个新品牌,确保没有活跃的售后政策
create_brand_resp = cls.test_case.kw_joyhub_after_sales_brand_create_post(
brand_name=f"品牌测试专用_{timestamp}",
after_sales_policy_id=0,
status=1
)
if create_brand_resp and create_brand_resp.get("code") == 0:
brand_id = create_brand_resp.get("data")
logging.info(f"创建测试品牌成功品牌ID: {brand_id}")
# 使用新创建的品牌创建售后政策
create_resp = cls.test_case.kw_joyhub_after_sales_policy_create_post(
title=f"品牌测试售后政策_{timestamp}",
content=f"品牌测试售后政策内容_{timestamp}",
lang="en",
brand_id=brand_id,
status=1
)
if create_resp and create_resp.get("code") == 0:
cls.policy_id = create_resp.get("data")
logging.info(f"创建测试售后政策成功ID: {cls.policy_id}")
else:
logging.warning(f"创建售后政策失败: {create_resp}")
else:
logging.warning(f"创建测试品牌失败: {create_brand_resp}")
@allure.story("验证获得售后政策-品牌分页")
@allure.title("测试获得售后政策-品牌分页接口")
def test_joyhub_after_sales_brand_page_get(self):
"""测试获得售后政策-品牌分页接口"""
with allure.step("1. 准备请求参数"):
params = {
"page_no": 1,
"page_size": 10,
"brand_name": "",
"after_sales_policy_id": "",
"status": ""
}
allure.attach(json.dumps(params, ensure_ascii=False), name="请求参数", attachment_type=allure.attachment_type.TEXT)
with allure.step("2. 调用接口"):
resp = self.test_case.kw_joyhub_after_sales_brand_page_get(**params)
allure.attach(json.dumps(resp, ensure_ascii=False, indent=2), name="响应数据", attachment_type=allure.attachment_type.JSON)
with allure.step("3. 验证响应"):
assert resp is not None, "响应为空"
assert "code" in resp, "响应中缺少code字段"
assert resp["code"] == 0, f"请求失败code={resp.get('code')}"
assert "data" in resp, "响应中缺少data字段"
assert "list" in resp["data"], "响应中缺少list字段"
assert "total" in resp["data"], "响应中缺少total字段"
assert isinstance(resp["data"]["list"], list), "list字段不是列表类型"
assert isinstance(resp["data"]["total"], int), "total字段不是整数类型"
logging.info("获得售后政策-品牌分页列表验证通过")
@allure.story("验证创建售后政策-品牌")
@allure.title("测试创建售后政策-品牌接口")
def test_joyhub_after_sales_brand_create_post(self):
"""测试创建售后政策-品牌接口"""
if not self.policy_id:
pytest.skip("未创建测试售后政策,跳过品牌创建测试")
with allure.step("1. 准备请求参数"):
timestamp = int(time.time())
params = {
"brand_name": f"测试品牌_{timestamp}",
"after_sales_policy_id": self.policy_id,
"status": 1
}
allure.attach(json.dumps(params, ensure_ascii=False), name="请求参数", attachment_type=allure.attachment_type.TEXT)
with allure.step("2. 调用接口"):
resp = self.test_case.kw_joyhub_after_sales_brand_create_post(**params)
allure.attach(json.dumps(resp, ensure_ascii=False, indent=2), name="响应数据", attachment_type=allure.attachment_type.JSON)
with allure.step("3. 验证响应"):
assert resp is not None, "响应为空"
assert "code" in resp, "响应中缺少code字段"
assert resp["code"] == 0, f"请求失败code={resp.get('code')}"
assert "data" in resp, "响应中缺少data字段"
assert isinstance(resp["data"], int), "data字段不是整数类型"
TestAfterSalesBrandManage.brand_id = resp["data"]
logging.info(f"创建售后政策-品牌成功品牌ID: {TestAfterSalesBrandManage.brand_id}")
@allure.story("验证获得售后政策-品牌详情")
@allure.title("测试获得售后政策-品牌详情接口")
def test_joyhub_after_sales_brand_get_get(self):
"""测试获得售后政策-品牌详情接口"""
if not self.policy_id:
pytest.skip("未创建测试售后政策,跳过品牌详情测试")
with allure.step("1. 先创建一个售后政策-品牌"):
timestamp = int(time.time())
create_resp = self.test_case.kw_joyhub_after_sales_brand_create_post(
brand_name=f"详情测试品牌_{timestamp}",
after_sales_policy_id=self.policy_id,
status=2
)
brand_id = create_resp.get("data") if create_resp and create_resp.get("code") == 0 else None
if not brand_id:
pytest.skip("创建测试品牌失败,跳过详情测试")
allure.attach(json.dumps({"id": brand_id}, ensure_ascii=False), name="售后政策-品牌ID", attachment_type=allure.attachment_type.TEXT)
with allure.step("2. 调用获得详情接口"):
resp = self.test_case.kw_joyhub_after_sales_brand_get_get(brand_id=brand_id)
allure.attach(json.dumps(resp, ensure_ascii=False, indent=2), name="响应数据", attachment_type=allure.attachment_type.JSON)
with allure.step("3. 验证响应"):
assert resp is not None, "响应为空"
assert "code" in resp, "响应中缺少code字段"
assert resp["code"] == 0, f"请求失败code={resp.get('code')}"
assert "data" in resp, "响应中缺少data字段"
assert isinstance(resp["data"], dict), "data字段不是字典类型"
assert "id" in resp["data"], "响应中缺少id字段"
assert resp["data"]["id"] == brand_id, "返回的ID与请求的不一致"
logging.info("获得售后政策-品牌详情验证通过")
@allure.story("验证更新售后政策-品牌")
@allure.title("测试更新售后政策-品牌接口")
def test_joyhub_after_sales_brand_update_put(self):
"""测试更新售后政策-品牌接口"""
if not self.policy_id:
pytest.skip("未创建测试售后政策,跳过品牌更新测试")
with allure.step("1. 先创建一个售后政策-品牌"):
timestamp = int(time.time())
create_resp = self.test_case.kw_joyhub_after_sales_brand_create_post(
brand_name=f"待更新品牌_{timestamp}",
after_sales_policy_id=self.policy_id,
status=1
)
brand_id = create_resp.get("data") if create_resp and create_resp.get("code") == 0 else None
if not brand_id:
pytest.skip("创建测试品牌失败,跳过更新测试")
allure.attach(json.dumps({"id": brand_id}, ensure_ascii=False), name="售后政策-品牌ID", attachment_type=allure.attachment_type.TEXT)
with allure.step("2. 调用更新接口"):
timestamp = int(time.time())
update_params = {
"brand_id": brand_id,
"brand_name": f"已更新品牌_{timestamp}",
"after_sales_policy_id": self.policy_id,
"status": 2
}
resp = self.test_case.kw_joyhub_after_sales_brand_update_put(**update_params)
allure.attach(json.dumps(resp, ensure_ascii=False, indent=2), name="响应数据", attachment_type=allure.attachment_type.JSON)
with allure.step("3. 验证响应"):
assert resp is not None, "响应为空"
assert "code" in resp, "响应中缺少code字段"
assert resp["code"] == 0, f"请求失败code={resp.get('code')}"
assert "data" in resp, "响应中缺少data字段"
assert resp["data"] is True, "更新售后政策-品牌失败"
logging.info("更新售后政策-品牌验证通过")
@allure.story("验证删除售后政策-品牌")
@allure.title("测试删除售后政策-品牌接口")
def test_joyhub_after_sales_brand_delete_delete(self):
"""测试删除售后政策-品牌接口"""
if not self.policy_id:
pytest.skip("未创建测试售后政策,跳过品牌删除测试")
with allure.step("1. 先创建一个测试售后政策-品牌"):
timestamp = int(time.time())
create_resp = self.test_case.kw_joyhub_after_sales_brand_create_post(
brand_name=f"待删除品牌_{timestamp}",
after_sales_policy_id=self.policy_id,
status=2
)
brand_id = create_resp.get("data") if create_resp and create_resp.get("code") == 0 else None
if not brand_id:
pytest.skip("创建测试品牌失败,跳过删除测试")
allure.attach(json.dumps({"id": brand_id}, ensure_ascii=False), name="待删除品牌ID", attachment_type=allure.attachment_type.TEXT)
with allure.step("2. 调用删除接口"):
resp = self.test_case.kw_joyhub_after_sales_brand_delete_delete(brand_id=brand_id)
allure.attach(json.dumps(resp, ensure_ascii=False, indent=2), name="响应数据", attachment_type=allure.attachment_type.JSON)
with allure.step("3. 验证响应"):
assert resp is not None, "响应为空"
assert "code" in resp, "响应中缺少code字段"
assert resp["code"] == 0, f"请求失败code={resp.get('code')}"
assert "data" in resp, "响应中缺少data字段"
assert resp["data"] is True, "删除售后政策-品牌失败"
logging.info("删除售后政策-品牌验证通过")
@allure.story("验证批量删除售后政策-品牌")
@allure.title("测试批量删除售后政策-品牌接口")
def test_joyhub_after_sales_brand_delete_list_delete(self):
"""测试批量删除售后政策-品牌接口"""
if not self.policy_id:
pytest.skip("未创建测试售后政策,跳过批量删除品牌测试")
with allure.step("1. 先创建两个测试售后政策-品牌"):
timestamp = int(time.time())
resp1 = self.test_case.kw_joyhub_after_sales_brand_create_post(
brand_name=f"批量删除品牌1_{timestamp}",
after_sales_policy_id=self.policy_id,
status=2
)
resp2 = self.test_case.kw_joyhub_after_sales_brand_create_post(
brand_name=f"批量删除品牌2_{timestamp}",
after_sales_policy_id=self.policy_id,
status=2
)
brand_id1 = resp1.get("data") if resp1 and resp1.get("code") == 0 else None
brand_id2 = resp2.get("data") if resp2 and resp2.get("code") == 0 else None
if not brand_id1 or not brand_id2:
pytest.skip("创建测试品牌失败,跳过批量删除测试")
brand_ids = [brand_id1, brand_id2]
allure.attach(json.dumps({"ids": brand_ids}, ensure_ascii=False), name="待删除品牌IDs", attachment_type=allure.attachment_type.TEXT)
with allure.step("2. 调用批量删除接口"):
resp = self.test_case.kw_joyhub_after_sales_brand_delete_list_delete(brand_ids=brand_ids)
allure.attach(json.dumps(resp, ensure_ascii=False, indent=2), name="响应数据", attachment_type=allure.attachment_type.JSON)
with allure.step("3. 验证响应"):
assert resp is not None, "响应为空"
assert "code" in resp, "响应中缺少code字段"
assert resp["code"] == 0, f"请求失败code={resp.get('code')}"
assert "data" in resp, "响应中缺少data字段"
assert resp["data"] is True, "批量删除售后政策-品牌失败"
logging.info("批量删除售后政策-品牌验证通过")
@allure.story("验证获得可用的品牌列表")
@allure.title("测试获得可用的品牌列表接口")
def test_joyhub_after_sales_brand_list_available_get(self):
"""测试获得可用的品牌列表接口"""
with allure.step("1. 调用接口"):
resp = self.test_case.kw_joyhub_after_sales_brand_list_available_get()
allure.attach(json.dumps(resp, ensure_ascii=False, indent=2), name="响应数据", attachment_type=allure.attachment_type.JSON)
with allure.step("2. 验证响应"):
assert resp is not None, "响应为空"
assert "code" in resp, "响应中缺少code字段"
assert resp["code"] == 0, f"请求失败code={resp.get('code')}"
assert "data" in resp, "响应中缺少data字段"
assert isinstance(resp["data"], list), "data字段不是列表类型"
logging.info("获得可用的品牌列表验证通过")