Files
smart-management-auto-test/dulizhan/test_case/TestCase/接口/JoyHub/Joyhub_user.py

535 lines
26 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.
# -*- coding: utf-8 -*-
# 作者 周琦 2026/04/28
import allure
import logging
import requests
import json
from dulizhan.library.BusinessKw.JoyHub.UserManage import UserManage
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
@allure.feature('管理后台 - 用户模块')
class TestUserManage(object):
test_case = UserManage()
token_set = False
@classmethod
def setup_class(cls):
"""在整个测试类开始时登录一次所有测试用例共享token"""
logging.info("=============================================")
logging.info("=========== 开始登录获取Token ============")
logging.info("=============================================")
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)))
logging.info("=============================================")
logging.info("=========== 登录完成 ============")
logging.info("=============================================")
def setup_method(self):
"""每个测试用例执行前的准备工作"""
if not self.token_set:
logging.warning("Token未设置可能影响后续接口调用")
logging.info("-----------------------------Test Start-------------------------------")
def teardown_method(self):
logging.info("-----------------------------Test End-------------------------------")
@allure.story("验证用户登录")
def test_joyhub_login_post(self):
"""登录测试用例验证登录接口是否正常token已在setup_class中设置"""
with allure.step("准备登录参数"):
username = "joytest"
password = "Zhou1599"
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'}
allure.attach(json.dumps(payload, ensure_ascii=False, indent=2), "请求参数", attachment_type=allure.attachment_type.JSON)
logging.info("准备登录请求,用户名: {}".format(username))
with allure.step("发送登录请求"):
response = requests.post(url, json=payload, headers=headers, verify=False, timeout=10)
response_data = response.json()
allure.attach(json.dumps(response_data, ensure_ascii=False, indent=2), "响应数据", attachment_type=allure.attachment_type.JSON)
logging.info("登录请求响应状态码: {}".format(response.status_code))
with allure.step("验证响应数据结构"):
assert response_data is not None, "响应数据不能为空"
logging.info("断言: 响应数据不为空 ")
assert 'code' in response_data, "响应数据中缺少code字段"
logging.info("断言: 响应数据包含code字段 ")
assert response_data['code'] == 0, "接口调用失败code: {}, msg: {}".format(
response_data.get('code'), response_data.get('msg', '未知错误'))
logging.info("断言: 接口调用成功code=0 ")
with allure.step("验证返回数据"):
assert 'data' in response_data, "响应数据中缺少data字段"
logging.info("断言: 响应数据包含data字段 ")
assert response_data['data'] is not None, "响应数据中的data字段不能为空"
logging.info("断言: data字段不为空 ")
data = response_data.get('data', {})
assert 'accessToken' in data, "响应数据中缺少accessToken字段"
logging.info("断言: data包含accessToken字段 ")
assert 'userId' in data, "响应数据中缺少userId字段"
logging.info("断言: data包含userId字段 ")
assert data.get('accessToken'), "accessToken不能为空"
logging.info("断言: accessToken不为空 ")
logging.info("用户登录成功userId: {}, token: {}...".format(
data.get('userId'), data.get('accessToken', '')[:20]))
logging.info("注意: Token已在setup_class中统一设置此用例仅验证登录功能")
@allure.story("验证获得用户分页列表")
def test_joyhub_user_page_get(self):
with allure.step("准备查询参数"):
page_no = 1
page_size = 10
params = {"pageNo": page_no, "pageSize": page_size}
allure.attach(json.dumps(params, ensure_ascii=False, indent=2), "请求参数", attachment_type=allure.attachment_type.JSON)
logging.info("查询用户分页列表pageNo: {}, pageSize: {}".format(page_no, page_size))
with allure.step("调用查询接口"):
response_data = self.test_case.kw_joyhub_user_page_get(
note="获得用户分页列表",
pageNo=page_no,
pageSize=page_size
)
allure.attach(json.dumps(response_data, ensure_ascii=False, indent=2), "响应数据", attachment_type=allure.attachment_type.JSON)
with allure.step("验证响应数据"):
assert response_data is not None, "响应数据不能为空"
logging.info("断言: 响应数据不为空 ✓")
assert 'code' in response_data, "响应数据中缺少code字段"
logging.info("断言: 响应数据包含code字段 ✓")
assert response_data['code'] == 0, "接口调用失败code: {}, msg: {}".format(
response_data.get('code'), response_data.get('msg', '未知错误'))
logging.info("断言: 接口调用成功code=0 ✓")
assert 'data' in response_data, "响应数据中缺少data字段"
logging.info("断言: 响应数据包含data字段 ✓")
assert response_data['data'] is not None, "响应数据中的data字段不能为空"
logging.info("断言: data字段不为空 ✓")
data = response_data.get('data', {})
assert isinstance(data, dict), "data字段应为字典类型"
logging.info("断言: data字段为字典类型 ✓")
if 'records' in data:
assert isinstance(data['records'], list), "records字段应为列表类型"
logging.info("断言: records字段为列表类型 ✓,记录数: {}".format(len(data['records'])))
logging.info("✓ 用户分页列表查询成功")
@allure.story("验证获取用户精简信息列表")
def test_joyhub_user_simple_list_get(self):
with allure.step("调用查询接口"):
response_data = self.test_case.kw_joyhub_user_simple_list_get(
note="获取用户精简信息列表"
)
allure.attach(json.dumps(response_data, ensure_ascii=False, indent=2), "响应数据", attachment_type=allure.attachment_type.JSON)
logging.info("获取用户精简信息列表")
with allure.step("验证响应数据"):
assert response_data is not None, "响应数据不能为空"
logging.info("断言: 响应数据不为空 ✓")
assert 'code' in response_data, "响应数据中缺少code字段"
logging.info("断言: 响应数据包含code字段 ✓")
assert response_data['code'] == 0, "接口调用失败code: {}, msg: {}".format(
response_data.get('code'), response_data.get('msg', '未知错误'))
logging.info("断言: 接口调用成功code=0 ✓")
assert 'data' in response_data, "响应数据中缺少data字段"
logging.info("断言: 响应数据包含data字段 ✓")
assert isinstance(response_data['data'], list), "data字段应为列表类型"
logging.info("断言: data字段为列表类型 ✓,记录数: {}".format(len(response_data['data'])))
logging.info("✓ 用户精简信息列表查询成功")
@allure.story("验证新增用户")
def test_joyhub_user_create_post(self):
import random
with allure.step("准备新增用户参数"):
username = "testuser{}".format(random.randint(100000, 999999))
nickname = "测试用户{}".format(random.randint(1000, 9999))
password = "123456"
mobile = "138{}{}{}{}{}{}{}{}".format(random.randint(0,9), random.randint(0,9), random.randint(0,9),
random.randint(0,9), random.randint(0,9), random.randint(0,9),
random.randint(0,9), random.randint(0,9))
payload = {
"username": username,
"nickname": nickname,
"password": password,
"email": "{}@test.com".format(username),
"mobile": mobile,
"sex": 1,
"remark": "测试用户"
}
allure.attach(json.dumps(payload, ensure_ascii=False, indent=2), "请求参数", attachment_type=allure.attachment_type.JSON)
logging.info("准备新增用户: {}".format(username))
with allure.step("调用新增用户接口"):
response_data = self.test_case.kw_joyhub_user_create_post(
note="新增用户",
**payload
)
allure.attach(json.dumps(response_data, ensure_ascii=False, indent=2), "响应数据", attachment_type=allure.attachment_type.JSON)
with allure.step("验证响应数据"):
assert response_data is not None, "响应数据不能为空"
logging.info("断言: 响应数据不为空 ✓")
assert 'code' in response_data, "响应数据中缺少code字段"
logging.info("断言: 响应数据包含code字段 ✓")
assert response_data['code'] == 0, "接口调用失败code: {}, msg: {}".format(
response_data.get('code'), response_data.get('msg', '未知错误'))
logging.info("断言: 接口调用成功code=0 ✓")
assert 'data' in response_data, "响应数据中缺少data字段"
logging.info("断言: 响应数据包含data字段 ✓")
assert response_data['data'] is not None, "响应数据中的data字段不能为空"
logging.info("断言: data字段不为空 ✓")
logging.info("✓ 新增用户成功用户ID: {}".format(response_data['data']))
self.created_user_id = response_data['data']
@allure.story("验证获得用户详情")
def test_joyhub_user_get_get(self):
import random
with allure.step("创建测试用户"):
username = "testuserget{}".format(random.randint(100000, 999999))
nickname = "测试用户详情{}".format(random.randint(1000, 9999))
create_resp = self.test_case.kw_joyhub_user_create_post(
note="创建测试用户",
username=username,
nickname=nickname,
password="123456"
)
user_id = create_resp.get('data')
logging.info("创建测试用户成功用户ID: {}".format(user_id))
with allure.step("调用查询用户详情接口"):
params = {"id": user_id}
allure.attach(json.dumps(params, ensure_ascii=False, indent=2), "请求参数", attachment_type=allure.attachment_type.JSON)
response_data = self.test_case.kw_joyhub_user_get_get(
note="获得用户详情",
id=user_id
)
allure.attach(json.dumps(response_data, ensure_ascii=False, indent=2), "响应数据", attachment_type=allure.attachment_type.JSON)
with allure.step("验证响应数据"):
assert response_data is not None, "响应数据不能为空"
logging.info("断言: 响应数据不为空 ✓")
assert 'code' in response_data, "响应数据中缺少code字段"
logging.info("断言: 响应数据包含code字段 ✓")
assert response_data['code'] == 0, "接口调用失败code: {}, msg: {}".format(
response_data.get('code'), response_data.get('msg', '未知错误'))
logging.info("断言: 接口调用成功code=0 ✓")
assert 'data' in response_data, "响应数据中缺少data字段"
logging.info("断言: 响应数据包含data字段 ✓")
assert response_data['data'] is not None, "响应数据中的data字段不能为空"
logging.info("断言: data字段不为空 ✓")
data = response_data.get('data', {})
assert 'id' in data, "用户详情中缺少id字段"
logging.info("断言: 用户详情包含id字段 ✓")
assert data['id'] == user_id, "返回的用户ID与请求不一致"
logging.info("断言: 返回的用户ID与请求一致 ✓")
assert 'username' in data, "用户详情中缺少username字段"
logging.info("断言: 用户详情包含username字段 ✓")
assert data['username'] == username, "返回的用户名与创建时不一致"
logging.info("断言: 返回的用户名与创建时一致 ✓")
logging.info("✓ 用户详情查询成功")
@allure.story("验证修改用户")
def test_joyhub_user_update_put(self):
import random
with allure.step("创建测试用户"):
username = "testuserupdate{}".format(random.randint(100000, 999999))
nickname = "测试用户更新{}".format(random.randint(1000, 9999))
create_resp = self.test_case.kw_joyhub_user_create_post(
note="创建测试用户",
username=username,
nickname=nickname,
password="123456"
)
user_id = create_resp.get('data')
logging.info("创建测试用户成功用户ID: {}".format(user_id))
with allure.step("准备修改参数"):
new_nickname = "修改后的昵称{}".format(random.randint(1000, 9999))
payload = {
"id": user_id,
"username": username,
"nickname": new_nickname,
"remark": "修改后的备注"
}
allure.attach(json.dumps(payload, ensure_ascii=False, indent=2), "请求参数", attachment_type=allure.attachment_type.JSON)
logging.info("准备修改用户,新昵称: {}".format(new_nickname))
with allure.step("调用修改用户接口"):
response_data = self.test_case.kw_joyhub_user_update_put(
note="修改用户",
**payload
)
allure.attach(json.dumps(response_data, ensure_ascii=False, indent=2), "响应数据", attachment_type=allure.attachment_type.JSON)
with allure.step("验证响应数据"):
assert response_data is not None, "响应数据不能为空"
logging.info("断言: 响应数据不为空 ✓")
assert 'code' in response_data, "响应数据中缺少code字段"
logging.info("断言: 响应数据包含code字段 ✓")
assert response_data['code'] == 0, "接口调用失败code: {}, msg: {}".format(
response_data.get('code'), response_data.get('msg', '未知错误'))
logging.info("断言: 接口调用成功code=0 ✓")
assert 'data' in response_data, "响应数据中缺少data字段"
logging.info("断言: 响应数据包含data字段 ✓")
assert response_data['data'] is True, "用户修改失败"
logging.info("断言: 用户修改成功 ✓")
logging.info("✓ 修改用户成功")
@allure.story("验证重置用户密码")
def test_joyhub_user_update_password_put(self):
import random
with allure.step("创建测试用户"):
username = "testuserpwd{}".format(random.randint(100000, 999999))
create_resp = self.test_case.kw_joyhub_user_create_post(
note="创建测试用户",
username=username,
nickname="测试密码用户",
password="123456"
)
user_id = create_resp.get('data')
logging.info("创建测试用户成功用户ID: {}".format(user_id))
with allure.step("准备重置密码参数"):
payload = {"id": user_id, "password": "654321"}
allure.attach(json.dumps(payload, ensure_ascii=False, indent=2), "请求参数", attachment_type=allure.attachment_type.JSON)
logging.info("准备重置用户密码")
with allure.step("调用重置密码接口"):
response_data = self.test_case.kw_joyhub_user_update_password_put(
note="重置用户密码",
**payload
)
allure.attach(json.dumps(response_data, ensure_ascii=False, indent=2), "响应数据", attachment_type=allure.attachment_type.JSON)
with allure.step("验证响应数据"):
assert response_data is not None, "响应数据不能为空"
logging.info("断言: 响应数据不为空 ✓")
assert 'code' in response_data, "响应数据中缺少code字段"
logging.info("断言: 响应数据包含code字段 ✓")
assert response_data['code'] == 0, "接口调用失败code: {}, msg: {}".format(
response_data.get('code'), response_data.get('msg', '未知错误'))
logging.info("断言: 接口调用成功code=0 ✓")
assert 'data' in response_data, "响应数据中缺少data字段"
logging.info("断言: 响应数据包含data字段 ✓")
assert response_data['data'] is True, "密码重置失败"
logging.info("断言: 密码重置成功 ✓")
logging.info("✓ 重置用户密码成功")
@allure.story("验证修改用户状态")
def test_joyhub_user_update_status_put(self):
import random
with allure.step("创建测试用户"):
username = "testuserstatus{}".format(random.randint(100000, 999999))
create_resp = self.test_case.kw_joyhub_user_create_post(
note="创建测试用户",
username=username,
nickname="测试状态用户",
password="123456"
)
user_id = create_resp.get('data')
logging.info("创建测试用户成功用户ID: {}".format(user_id))
with allure.step("准备修改状态参数"):
payload = {"id": user_id, "status": 0}
allure.attach(json.dumps(payload, ensure_ascii=False, indent=2), "请求参数", attachment_type=allure.attachment_type.JSON)
logging.info("准备修改用户状态为: {}".format(0))
with allure.step("调用修改状态接口"):
response_data = self.test_case.kw_joyhub_user_update_status_put(
note="修改用户状态",
**payload
)
allure.attach(json.dumps(response_data, ensure_ascii=False, indent=2), "响应数据", attachment_type=allure.attachment_type.JSON)
with allure.step("验证响应数据"):
assert response_data is not None, "响应数据不能为空"
logging.info("断言: 响应数据不为空 ✓")
assert 'code' in response_data, "响应数据中缺少code字段"
logging.info("断言: 响应数据包含code字段 ✓")
assert response_data['code'] == 0, "接口调用失败code: {}, msg: {}".format(
response_data.get('code'), response_data.get('msg', '未知错误'))
logging.info("断言: 接口调用成功code=0 ✓")
assert 'data' in response_data, "响应数据中缺少data字段"
logging.info("断言: 响应数据包含data字段 ✓")
assert response_data['data'] is True, "用户状态修改失败"
logging.info("断言: 用户状态修改成功 ✓")
logging.info("✓ 修改用户状态成功")
@allure.story("验证删除用户")
def test_joyhub_user_delete_post(self):
import random
with allure.step("创建测试用户"):
username = "testuserdelete{}".format(random.randint(100000, 999999))
create_resp = self.test_case.kw_joyhub_user_create_post(
note="创建测试用户",
username=username,
nickname="测试删除用户",
password="123456"
)
user_id = create_resp.get('data')
logging.info("创建测试用户成功用户ID: {}".format(user_id))
with allure.step("准备删除参数"):
payload = {"id": user_id}
allure.attach(json.dumps(payload, ensure_ascii=False, indent=2), "请求参数", attachment_type=allure.attachment_type.JSON)
logging.info("准备删除用户用户ID: {}".format(user_id))
with allure.step("调用删除接口"):
response_data = self.test_case.kw_joyhub_user_delete_post(
note="删除用户",
id=user_id
)
allure.attach(json.dumps(response_data, ensure_ascii=False, indent=2), "响应数据", attachment_type=allure.attachment_type.JSON)
with allure.step("验证响应数据"):
assert response_data is not None, "响应数据不能为空"
logging.info("断言: 响应数据不为空 ✓")
assert 'code' in response_data, "响应数据中缺少code字段"
logging.info("断言: 响应数据包含code字段 ✓")
assert response_data['code'] == 0, "接口调用失败code: {}, msg: {}".format(
response_data.get('code'), response_data.get('msg', '未知错误'))
logging.info("断言: 接口调用成功code=0 ✓")
assert 'data' in response_data, "响应数据中缺少data字段"
logging.info("断言: 响应数据包含data字段 ✓")
assert response_data['data'] is True, "用户删除失败"
logging.info("断言: 用户删除成功 ✓")
logging.info("✓ 删除用户成功")
@allure.story("验证批量删除用户")
def test_joyhub_user_delete_list_post(self):
import random
with allure.step("创建测试用户"):
user_ids = []
for i in range(2):
username = "testuserbatch{}{}".format(random.randint(100000, 999999), i)
create_resp = self.test_case.kw_joyhub_user_create_post(
note="创建测试用户{}".format(i),
username=username,
nickname="测试批量删除用户{}".format(i),
password="123456"
)
user_ids.append(create_resp.get('data'))
logging.info("创建测试用户成功用户ID列表: {}".format(user_ids))
with allure.step("准备批量删除参数"):
payload = {"ids": user_ids}
allure.attach(json.dumps(payload, ensure_ascii=False, indent=2), "请求参数", attachment_type=allure.attachment_type.JSON)
logging.info("准备批量删除用户")
with allure.step("调用批量删除接口"):
response_data = self.test_case.kw_joyhub_user_delete_list_post(
note="批量删除用户",
ids=user_ids
)
allure.attach(json.dumps(response_data, ensure_ascii=False, indent=2), "响应数据", attachment_type=allure.attachment_type.JSON)
with allure.step("验证响应数据"):
assert response_data is not None, "响应数据不能为空"
logging.info("断言: 响应数据不为空 ✓")
assert 'code' in response_data, "响应数据中缺少code字段"
logging.info("断言: 响应数据包含code字段 ✓")
assert response_data['code'] == 0, "接口调用失败code: {}, msg: {}".format(
response_data.get('code'), response_data.get('msg', '未知错误'))
logging.info("断言: 接口调用成功code=0 ✓")
assert 'data' in response_data, "响应数据中缺少data字段"
logging.info("断言: 响应数据包含data字段 ✓")
assert response_data['data'] is True, "批量删除失败"
logging.info("断言: 批量删除成功 ✓")
logging.info("✓ 批量删除用户成功")