feat: 添加JoyHub运费模板和Banner管理接口用例
This commit is contained in:
190
dulizhan/test_case/JENKINS_SETUP.md
Normal file
190
dulizhan/test_case/JENKINS_SETUP.md
Normal file
@@ -0,0 +1,190 @@
|
||||
# Jenkins + Allure 报告集成配置指南
|
||||
|
||||
## 前置要求
|
||||
|
||||
1. **Jenkins已安装并运行**
|
||||
2. **安装Allure插件**
|
||||
- 进入 Jenkins → Manage Jenkins → Manage Plugins
|
||||
- 搜索并安装 "Allure Plugin"
|
||||
3. **安装Allure命令行工具**
|
||||
- 下载:https://github.com/allure-framework/allure2/releases
|
||||
- 解压并添加到系统PATH环境变量
|
||||
- 或在Jenkins全局工具配置中配置Allure路径
|
||||
|
||||
## Jenkins配置步骤
|
||||
|
||||
### 方式一:使用Jenkinsfile(推荐)
|
||||
|
||||
1. **在Jenkins中创建Pipeline任务**
|
||||
- 新建任务 → 选择 "Pipeline"
|
||||
- 任务名称:例如 "ZZYY_Test_Automation"
|
||||
|
||||
2. **配置Pipeline**
|
||||
- Pipeline definition → Pipeline script from SCM
|
||||
- SCM: Git(或其他版本控制)
|
||||
- Script Path: `zhyy/test_case/Jenkinsfile`
|
||||
- 保存
|
||||
|
||||
3. **运行任务**
|
||||
- 点击 "Build with Parameters"
|
||||
- 选择运行方式(RUN_TYPE)
|
||||
- 填写相应参数
|
||||
- 点击 "Build"
|
||||
|
||||
### 方式二:自由风格项目配置
|
||||
|
||||
1. **创建自由风格项目**
|
||||
- 新建任务 → 选择 "Freestyle project"
|
||||
- 任务名称:例如 "ZZYY_Test_Automation"
|
||||
|
||||
2. **配置源码管理**
|
||||
- Source Code Management → Git
|
||||
- Repository URL: 你的Git仓库地址
|
||||
- Branch: 分支名称
|
||||
|
||||
3. **配置构建步骤**
|
||||
- Build → Add build step → Execute shell(Linux/Mac)或 Execute Windows batch command(Windows)
|
||||
- 命令示例:
|
||||
```bash
|
||||
# Linux/Mac
|
||||
cd ${WORKSPACE}
|
||||
python zhyy/test_case/run_tests.py --all --no-report
|
||||
```
|
||||
```batch
|
||||
# Windows
|
||||
cd %WORKSPACE%
|
||||
python zhyy\test_case\run_tests.py --all --no-report
|
||||
```
|
||||
|
||||
4. **配置Allure报告**
|
||||
- Post-build Actions → Add post-build action → Allure Report
|
||||
- Results path: `zhyy/test_case/reports/allure-results`
|
||||
- Report path: `zhyy/test_case/reports/allure-report`(可选)
|
||||
- 保存
|
||||
|
||||
5. **配置参数化构建(可选)**
|
||||
- This project is parameterized → Add Parameter
|
||||
- 添加Choice Parameter:
|
||||
- Name: `RUN_TYPE`
|
||||
- Choices: `all`, `feature`, `story`, `dir`, `file`, `keyword`, `marker`
|
||||
- 添加String Parameter(根据需要):
|
||||
- `FEATURE_NAME`, `STORY_NAME`, `DIR_PATH`, `FILE_PATH`, `KEYWORD`, `MARKER`
|
||||
|
||||
6. **修改构建命令以使用参数**
|
||||
```bash
|
||||
# Linux/Mac
|
||||
cd ${WORKSPACE}
|
||||
if [ "${RUN_TYPE}" = "all" ]; then
|
||||
python zhyy/test_case/run_tests.py --all --no-report
|
||||
elif [ "${RUN_TYPE}" = "feature" ]; then
|
||||
python zhyy/test_case/run_tests.py --feature "${FEATURE_NAME}" --no-report
|
||||
elif [ "${RUN_TYPE}" = "dir" ]; then
|
||||
python zhyy/test_case/run_tests.py --dir "${DIR_PATH}" --no-report
|
||||
# ... 其他条件
|
||||
fi
|
||||
```
|
||||
|
||||
## Allure插件配置
|
||||
|
||||
### 全局工具配置
|
||||
|
||||
1. **配置Allure命令行工具路径**
|
||||
- Manage Jenkins → Global Tool Configuration
|
||||
- Allure Commandline → Add Allure Commandline
|
||||
- Name: `Allure`(或自定义名称)
|
||||
- Installation directory: Allure安装路径(如:`C:\allure\bin` 或 `/usr/local/allure/bin`)
|
||||
- 保存
|
||||
|
||||
### 项目配置
|
||||
|
||||
1. **在项目配置中添加Allure报告**
|
||||
- Post-build Actions → Allure Report
|
||||
- Results path: `zhyy/test_case/reports/allure-results`
|
||||
- 勾选 "Keep allure results history"
|
||||
|
||||
## 环境变量配置
|
||||
|
||||
### Jenkins全局环境变量
|
||||
|
||||
1. **配置Python路径(如需要)**
|
||||
- Manage Jenkins → Configure System → Global properties
|
||||
- Environment variables → Add
|
||||
- Name: `PYTHONPATH`
|
||||
- Value: `${WORKSPACE}`
|
||||
|
||||
### 项目环境变量
|
||||
|
||||
在Pipeline或构建脚本中设置:
|
||||
```groovy
|
||||
environment {
|
||||
PYTHONPATH = "${WORKSPACE}"
|
||||
ALLURE_RESULTS = "${WORKSPACE}/zhyy/test_case/reports/allure-results"
|
||||
}
|
||||
```
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 运行所有测试
|
||||
```bash
|
||||
python zhyy/test_case/run_tests.py --all --no-report
|
||||
```
|
||||
|
||||
### 按目录运行
|
||||
```bash
|
||||
python zhyy/test_case/run_tests.py --dir "接口/SZPurchase" --no-report
|
||||
```
|
||||
|
||||
### 按Feature标签运行
|
||||
```bash
|
||||
python zhyy/test_case/run_tests.py --feature "深圳采购工作台采购订单页面" --no-report
|
||||
```
|
||||
|
||||
## 报告查看
|
||||
|
||||
1. **在Jenkins中查看**
|
||||
- 构建完成后,在项目页面左侧菜单会出现 "Allure Report" 链接
|
||||
- 点击即可查看详细的测试报告
|
||||
|
||||
2. **报告内容**
|
||||
- 测试用例执行情况
|
||||
- 通过/失败统计
|
||||
- 执行时间
|
||||
- 测试步骤详情
|
||||
- 截图和日志(如果配置了)
|
||||
|
||||
## 常见问题
|
||||
|
||||
### 1. Allure命令未找到
|
||||
- 确保Allure已安装并添加到PATH
|
||||
- 或在Jenkins全局工具配置中指定Allure路径
|
||||
|
||||
### 2. 模块导入错误
|
||||
- 检查PYTHONPATH环境变量
|
||||
- 确保项目根目录在Python路径中
|
||||
|
||||
### 3. 报告未生成
|
||||
- 检查allure-results目录是否存在且包含数据
|
||||
- 检查Jenkins Allure插件配置的路径是否正确
|
||||
|
||||
### 4. 权限问题
|
||||
- 确保Jenkins有权限访问工作空间目录
|
||||
- 确保有权限执行Python和Allure命令
|
||||
|
||||
## 邮件通知配置(可选)
|
||||
|
||||
在Post-build Actions中添加:
|
||||
- Email Notification
|
||||
- 配置收件人、主题等
|
||||
- 可以附加Allure报告链接
|
||||
|
||||
## 定时构建(可选)
|
||||
|
||||
在项目配置中:
|
||||
- Build Triggers → Build periodically
|
||||
- 例如:`H 2 * * *`(每天凌晨2点执行)
|
||||
|
||||
## 多节点执行(可选)
|
||||
|
||||
如果有多台Jenkins节点:
|
||||
- 在Pipeline中配置 `agent { label 'your-node-label' }`
|
||||
- 或在自由风格项目中配置 "Restrict where this project can be run"
|
||||
175
dulizhan/test_case/Jenkinsfile
vendored
Normal file
175
dulizhan/test_case/Jenkinsfile
vendored
Normal file
@@ -0,0 +1,175 @@
|
||||
pipeline {
|
||||
agent any
|
||||
|
||||
options {
|
||||
// 保留最近10次构建
|
||||
buildDiscarder(logRotator(numToKeepStr: '10'))
|
||||
// 超时时间60分钟
|
||||
timeout(time: 60, unit: 'MINUTES')
|
||||
}
|
||||
|
||||
environment {
|
||||
// Python路径
|
||||
PYTHONPATH = "${WORKSPACE}"
|
||||
// Allure结果目录
|
||||
ALLURE_RESULTS = "${WORKSPACE}/zhyy/test_case/reports/allure-results"
|
||||
// Allure报告目录
|
||||
ALLURE_REPORT = "${WORKSPACE}/zhyy/test_case/reports/allure-report"
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Checkout') {
|
||||
steps {
|
||||
echo '检出代码...'
|
||||
checkout scm
|
||||
}
|
||||
}
|
||||
|
||||
stage('环境准备') {
|
||||
steps {
|
||||
echo '准备测试环境...'
|
||||
script {
|
||||
// 确保Python环境
|
||||
sh '''
|
||||
python --version
|
||||
pip --version
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('运行测试') {
|
||||
steps {
|
||||
echo '执行测试用例...'
|
||||
script {
|
||||
// 根据参数选择运行方式
|
||||
def runType = params.RUN_TYPE ?: 'all'
|
||||
def testCommand = ''
|
||||
|
||||
switch(runType) {
|
||||
case 'all':
|
||||
testCommand = 'python zhyy/test_case/run_tests.py --all --no-report'
|
||||
break
|
||||
case 'feature':
|
||||
def feature = params.FEATURE_NAME ?: ''
|
||||
testCommand = "python zhyy/test_case/run_tests.py --feature \"${feature}\" --no-report"
|
||||
break
|
||||
case 'story':
|
||||
def story = params.STORY_NAME ?: ''
|
||||
testCommand = "python zhyy/test_case/run_tests.py --story \"${story}\" --no-report"
|
||||
break
|
||||
case 'dir':
|
||||
def dir = params.DIR_PATH ?: ''
|
||||
testCommand = "python zhyy/test_case/run_tests.py --dir \"${dir}\" --no-report"
|
||||
break
|
||||
case 'file':
|
||||
def file = params.FILE_PATH ?: ''
|
||||
testCommand = "python zhyy/test_case/run_tests.py --file \"${file}\" --no-report"
|
||||
break
|
||||
case 'keyword':
|
||||
def keyword = params.KEYWORD ?: ''
|
||||
testCommand = "python zhyy/test_case/run_tests.py --keyword \"${keyword}\" --no-report"
|
||||
break
|
||||
case 'marker':
|
||||
def marker = params.MARKER ?: ''
|
||||
testCommand = "python zhyy/test_case/run_tests.py --marker \"${marker}\" --no-report"
|
||||
break
|
||||
default:
|
||||
testCommand = 'python zhyy/test_case/run_tests.py --all --no-report'
|
||||
}
|
||||
|
||||
sh """
|
||||
cd ${WORKSPACE}
|
||||
${testCommand}
|
||||
"""
|
||||
}
|
||||
}
|
||||
post {
|
||||
always {
|
||||
// 无论成功失败都收集测试结果
|
||||
echo '收集测试结果...'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('生成Allure报告') {
|
||||
steps {
|
||||
echo '生成Allure报告...'
|
||||
script {
|
||||
sh """
|
||||
cd ${WORKSPACE}
|
||||
allure generate ${ALLURE_RESULTS} -o ${ALLURE_REPORT} --clean || echo "Allure报告生成失败,但继续执行"
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
// 发布Allure报告
|
||||
allure([
|
||||
includeProperties: false,
|
||||
jdk: '',
|
||||
properties: [],
|
||||
reportBuildPolicy: 'ALWAYS',
|
||||
results: [[path: 'zhyy/test_case/reports/allure-results']]
|
||||
])
|
||||
|
||||
// 清理工作空间(可选)
|
||||
// cleanWs()
|
||||
}
|
||||
success {
|
||||
echo '✓ 测试执行成功'
|
||||
// 可以在这里添加成功通知,如发送邮件、钉钉等
|
||||
}
|
||||
failure {
|
||||
echo '✗ 测试执行失败'
|
||||
// 可以在这里添加失败通知
|
||||
}
|
||||
unstable {
|
||||
echo '⚠ 测试执行不稳定'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 参数化构建
|
||||
properties([
|
||||
parameters([
|
||||
choice(
|
||||
name: 'RUN_TYPE',
|
||||
choices: ['all', 'feature', 'story', 'dir', 'file', 'keyword', 'marker'],
|
||||
description: '选择运行方式'
|
||||
),
|
||||
string(
|
||||
name: 'FEATURE_NAME',
|
||||
defaultValue: '',
|
||||
description: 'Feature标签名称(当RUN_TYPE=feature时使用)'
|
||||
),
|
||||
string(
|
||||
name: 'STORY_NAME',
|
||||
defaultValue: '',
|
||||
description: 'Story标签名称(当RUN_TYPE=story时使用)'
|
||||
),
|
||||
string(
|
||||
name: 'DIR_PATH',
|
||||
defaultValue: '接口/SZPurchase',
|
||||
description: '测试目录路径(当RUN_TYPE=dir时使用,相对于TestCase目录)'
|
||||
),
|
||||
string(
|
||||
name: 'FILE_PATH',
|
||||
defaultValue: '接口/SZPurchase/PurchaseOrderManage.py',
|
||||
description: '测试文件路径(当RUN_TYPE=file时使用,相对于TestCase目录)'
|
||||
),
|
||||
string(
|
||||
name: 'KEYWORD',
|
||||
defaultValue: 'purchase',
|
||||
description: '关键字(当RUN_TYPE=keyword时使用)'
|
||||
),
|
||||
string(
|
||||
name: 'MARKER',
|
||||
defaultValue: 'smoke',
|
||||
description: 'Pytest标记(当RUN_TYPE=marker时使用)'
|
||||
)
|
||||
])
|
||||
])
|
||||
84
dulizhan/test_case/README_JENKINS.md
Normal file
84
dulizhan/test_case/README_JENKINS.md
Normal file
@@ -0,0 +1,84 @@
|
||||
# Jenkins + Allure 集成快速参考
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 1. 安装Allure插件
|
||||
- Jenkins → Manage Jenkins → Manage Plugins
|
||||
- 搜索 "Allure Plugin" 并安装
|
||||
|
||||
### 2. 配置Allure工具
|
||||
- Manage Jenkins → Global Tool Configuration
|
||||
- Allure Commandline → 添加Allure安装路径
|
||||
|
||||
### 3. 创建Jenkins任务
|
||||
|
||||
#### 方式A:使用Jenkinsfile(推荐)
|
||||
1. 新建Pipeline任务
|
||||
2. Pipeline script from SCM
|
||||
3. Script Path: `zhyy/test_case/Jenkinsfile`
|
||||
4. 保存并运行
|
||||
|
||||
#### 方式B:自由风格项目
|
||||
1. 新建Freestyle project
|
||||
2. 构建步骤:执行 `jenkins_build.sh` 或 `jenkins_build.bat`
|
||||
3. Post-build Actions → Allure Report
|
||||
4. Results path: `zhyy/test_case/reports/allure-results`
|
||||
|
||||
## 参数化构建
|
||||
|
||||
在Jenkins任务中配置以下参数:
|
||||
|
||||
| 参数名 | 类型 | 说明 | 示例值 |
|
||||
|--------|------|------|--------|
|
||||
| RUN_TYPE | Choice | 运行方式 | all, feature, story, dir, file, keyword, marker |
|
||||
| FEATURE_NAME | String | Feature标签 | 深圳采购工作台采购订单页面 |
|
||||
| STORY_NAME | String | Story标签 | 验证采购工作台采购订单页面列表查询 |
|
||||
| DIR_PATH | String | 目录路径 | 接口/SZPurchase |
|
||||
| FILE_PATH | String | 文件路径 | 接口/SZPurchase/PurchaseOrderManage.py |
|
||||
| KEYWORD | String | 关键字 | purchase |
|
||||
| MARKER | String | Pytest标记 | smoke |
|
||||
|
||||
## 常用命令
|
||||
|
||||
### 本地运行
|
||||
```bash
|
||||
# 运行所有测试
|
||||
python run_tests.py
|
||||
|
||||
# 按目录运行
|
||||
python run_tests.py --dir "接口/SZPurchase"
|
||||
|
||||
# 按文件运行
|
||||
python run_tests.py --file "接口/SZPurchase/PurchaseOrderManage.py"
|
||||
|
||||
# 生成并打开报告
|
||||
python run_tests.py --all --report --open
|
||||
```
|
||||
|
||||
### Jenkins中运行
|
||||
```bash
|
||||
# 使用构建脚本(自动检测参数)
|
||||
bash jenkins_build.sh
|
||||
|
||||
# 或直接使用run_tests.py
|
||||
python run_tests.py --all --no-report
|
||||
```
|
||||
|
||||
## Allure报告路径
|
||||
|
||||
- **结果目录**: `zhyy/test_case/reports/allure-results`
|
||||
- **报告目录**: `zhyy/test_case/reports/allure-report`
|
||||
- **Jenkins中查看**: 构建完成后点击左侧 "Allure Report" 链接
|
||||
|
||||
## 环境变量
|
||||
|
||||
Jenkins会自动设置以下环境变量:
|
||||
- `WORKSPACE`: Jenkins工作空间路径
|
||||
- `BUILD_NUMBER`: 构建编号
|
||||
- `JENKINS_URL`: Jenkins服务器地址
|
||||
|
||||
`run_tests.py` 会自动检测Jenkins环境并调整路径。
|
||||
|
||||
## 详细文档
|
||||
|
||||
更多配置说明请参考:`JENKINS_SETUP.md`
|
||||
96
dulizhan/test_case/README_RUN_TESTS.md
Normal file
96
dulizhan/test_case/README_RUN_TESTS.md
Normal file
@@ -0,0 +1,96 @@
|
||||
# 测试执行说明
|
||||
|
||||
## 统一测试执行工具
|
||||
|
||||
使用 `run_tests.py` 可以方便地执行各种测试用例。
|
||||
|
||||
## 安装依赖
|
||||
|
||||
```bash
|
||||
pip install pytest
|
||||
pip install pytest-allure-adaptor # 或 allure-pytest
|
||||
pip install allure-python-commons
|
||||
```
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 1. 运行所有测试用例
|
||||
|
||||
```bash
|
||||
python run_tests.py --all
|
||||
```
|
||||
|
||||
### 2. 按 Allure Feature 标签运行
|
||||
|
||||
```bash
|
||||
python run_tests.py --feature "深圳采购工作台采购订单页面"
|
||||
```
|
||||
|
||||
### 3. 按 Allure Story 标签运行
|
||||
|
||||
```bash
|
||||
python run_tests.py --story "验证采购工作台采购订单页面列表查询"
|
||||
```
|
||||
|
||||
### 4. 按目录运行
|
||||
|
||||
```bash
|
||||
python run_tests.py --dir "接口/SZPurchase"
|
||||
```
|
||||
|
||||
### 5. 按文件运行
|
||||
|
||||
```bash
|
||||
python run_tests.py --file "接口/SZPurchase/PurchaseOrderManage.py"
|
||||
```
|
||||
|
||||
### 6. 按关键字运行(匹配文件名或类名)
|
||||
|
||||
```bash
|
||||
python run_tests.py --keyword "purchase"
|
||||
```
|
||||
|
||||
### 7. 按 pytest 标记运行
|
||||
|
||||
```bash
|
||||
python run_tests.py --marker "smoke"
|
||||
```
|
||||
|
||||
### 8. 生成并打开 Allure 报告
|
||||
|
||||
```bash
|
||||
python run_tests.py --all --report --open
|
||||
```
|
||||
|
||||
## 快捷方式(Windows)
|
||||
|
||||
- `run_all.bat` - 运行所有测试用例
|
||||
- `run_purchase.bat` - 运行采购相关测试用例
|
||||
|
||||
## 参数说明
|
||||
|
||||
- `--all`: 运行所有测试用例
|
||||
- `--feature <name>`: 按allure feature标签运行
|
||||
- `--story <name>`: 按allure story标签运行
|
||||
- `--dir <path>`: 按目录运行(相对于TestCase目录)
|
||||
- `--file <path>`: 按文件运行(相对于TestCase目录)
|
||||
- `--keyword <keyword>`: 按关键字运行
|
||||
- `--marker <marker>`: 按pytest标记运行
|
||||
- `--report`: 生成Allure报告
|
||||
- `--open`: 打开Allure报告
|
||||
- `--no-report`: 不生成Allure报告
|
||||
|
||||
## 报告位置
|
||||
|
||||
- Allure结果: `reports/allure-results/`
|
||||
- Allure报告: `reports/allure-report/`
|
||||
|
||||
## 查看报告
|
||||
|
||||
生成报告后,可以使用以下命令打开:
|
||||
|
||||
```bash
|
||||
allure open reports/allure-report
|
||||
```
|
||||
|
||||
或者直接使用 `--open` 参数自动打开。
|
||||
31
dulizhan/test_case/Resource/AdapterKws/hh-qa.robot
Normal file
31
dulizhan/test_case/Resource/AdapterKws/hh-qa.robot
Normal file
@@ -0,0 +1,31 @@
|
||||
*** Settings ***
|
||||
*** Variables ***
|
||||
|
||||
|
||||
|
||||
# ============ JoyHub 管理后台 - 用户模块 参数 ============
|
||||
# 登录参数
|
||||
${joyhub_login_username} joytest # JoyHub管理后台登录用户名
|
||||
${joyhub_login_password} Zhou1599 # JoyHub管理后台登录密码
|
||||
${joyhub_login_token} # JoyHub管理后台登录Token
|
||||
${joyhub_login_max_retries} 3 # 登录最大重试次数
|
||||
${joyhub_login_retry_delay} 2 # 登录重试间隔(秒)
|
||||
|
||||
# 分页参数
|
||||
${joyhub_page_no} 1 # 默认页码
|
||||
${joyhub_page_size} 10 # 默认每页条数
|
||||
|
||||
# 用户状态参数
|
||||
${joyhub_user_status_enable} 1 # 用户状态-启用
|
||||
${joyhub_user_status_disable} 0 # 用户状态-禁用
|
||||
|
||||
# 用户性别参数
|
||||
${joyhub_user_sex_male} 1 # 用户性别-男
|
||||
${joyhub_user_sex_female} 2 # 用户性别-女
|
||||
${joyhub_user_sex_unknown} 0 # 用户性别-未知
|
||||
|
||||
# 测试用户数据前缀
|
||||
${joyhub_test_user_prefix} testuser_ # 测试用户账号前缀
|
||||
${joyhub_test_nickname_prefix} 测试用户 # 测试用户昵称前缀
|
||||
|
||||
|
||||
0
dulizhan/test_case/TestCase/__init__.py
Normal file
0
dulizhan/test_case/TestCase/__init__.py
Normal file
292
dulizhan/test_case/TestCase/接口/JoyHub/Joyhub_Banner.py
Normal file
292
dulizhan/test_case/TestCase/接口/JoyHub/Joyhub_Banner.py
Normal file
@@ -0,0 +1,292 @@
|
||||
import pytest
|
||||
import allure
|
||||
import logging
|
||||
import requests
|
||||
import json
|
||||
import time
|
||||
from dulizhan.library.BusinessKw.JoyHub.BannerManage import BannerManage
|
||||
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||
|
||||
|
||||
@allure.feature("管理后台 - Banner管理模块")
|
||||
class TestBannerManage:
|
||||
banner_id = None
|
||||
token_set = False
|
||||
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
"""在整个测试类开始时登录一次,所有测试用例共享token"""
|
||||
logging.info("=============================================")
|
||||
logging.info("=========== 开始登录,获取Token ============")
|
||||
logging.info("=============================================")
|
||||
|
||||
cls.test_case = BannerManage()
|
||||
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("验证获得Banner分页")
|
||||
@allure.title("测试获得Banner管理分页接口")
|
||||
def test_joyhub_banner_page_get(self):
|
||||
"""测试获得Banner管理分页接口"""
|
||||
with allure.step("1. 准备请求参数"):
|
||||
params = {
|
||||
"page_no": 1,
|
||||
"page_size": 10,
|
||||
"position": "",
|
||||
"title": "",
|
||||
"platform": "",
|
||||
"lang": "",
|
||||
"banner_type": "",
|
||||
"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_banner_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("获得Banner分页列表验证通过")
|
||||
|
||||
@allure.story("验证创建Banner")
|
||||
@allure.title("测试创建Banner管理接口")
|
||||
def test_joyhub_banner_create_post(self):
|
||||
"""测试创建Banner管理接口"""
|
||||
with allure.step("1. 准备请求参数"):
|
||||
timestamp = int(time.time())
|
||||
params = {
|
||||
"position": f"home_{timestamp}",
|
||||
"platform": 1,
|
||||
"lang": "en",
|
||||
"rank_num": timestamp % 1000,
|
||||
"banner_type": "promotion",
|
||||
"status": 1,
|
||||
"interval_time": 5,
|
||||
"title": f"测试Banner_{timestamp}",
|
||||
"sub_title": "测试副标题",
|
||||
"image": {'url': 'https://www.toendi.com/static/image/cd94c191561c4a37a04c78fca2913851.webp', 'name': 'Test Banner', 'mime_type': 'image/webp'},
|
||||
"link": "https://example.com"
|
||||
}
|
||||
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_banner_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字段不是整数类型"
|
||||
TestBannerManage.banner_id = resp["data"]
|
||||
logging.info(f"创建Banner成功,Banner ID: {TestBannerManage.banner_id}")
|
||||
|
||||
@allure.story("验证获得Banner详情")
|
||||
@allure.title("测试获得Banner详情接口")
|
||||
def test_joyhub_banner_get_get(self):
|
||||
"""测试获得Banner详情接口"""
|
||||
with allure.step("1. 先创建一个Banner"):
|
||||
timestamp = int(time.time())
|
||||
create_resp = self.test_case.kw_joyhub_banner_create_post(
|
||||
position=f"detail_test_{timestamp}",
|
||||
platform=1,
|
||||
lang="en",
|
||||
rank_num=timestamp % 1000,
|
||||
banner_type="promotion",
|
||||
status=1,
|
||||
interval_time=5,
|
||||
title=f"详情测试Banner_{timestamp}"
|
||||
)
|
||||
banner_id = create_resp.get("data") if create_resp and create_resp.get("code") == 0 else None
|
||||
|
||||
if not banner_id:
|
||||
pytest.skip("创建测试Banner失败,跳过详情测试")
|
||||
|
||||
allure.attach(json.dumps({"id": banner_id}, ensure_ascii=False), name="Banner ID", attachment_type=allure.attachment_type.TEXT)
|
||||
|
||||
with allure.step("2. 调用获得详情接口"):
|
||||
resp = self.test_case.kw_joyhub_banner_get_get(banner_id=banner_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"] == banner_id, "返回的ID与请求的不一致"
|
||||
logging.info("获得Banner详情验证通过")
|
||||
|
||||
@allure.story("验证更新Banner")
|
||||
@allure.title("测试更新Banner管理接口")
|
||||
def test_joyhub_banner_update_put(self):
|
||||
"""测试更新Banner管理接口"""
|
||||
with allure.step("1. 先创建一个Banner"):
|
||||
timestamp = int(time.time())
|
||||
create_resp = self.test_case.kw_joyhub_banner_create_post(
|
||||
position=f"update_test_{timestamp}",
|
||||
platform=1,
|
||||
lang="en",
|
||||
rank_num=timestamp % 1000,
|
||||
banner_type="promotion",
|
||||
status=1,
|
||||
interval_time=5,
|
||||
title=f"待更新Banner_{timestamp}"
|
||||
)
|
||||
banner_id = create_resp.get("data") if create_resp and create_resp.get("code") == 0 else None
|
||||
|
||||
if not banner_id:
|
||||
pytest.skip("创建测试Banner失败,跳过更新测试")
|
||||
|
||||
allure.attach(json.dumps({"id": banner_id}, ensure_ascii=False), name="Banner ID", attachment_type=allure.attachment_type.TEXT)
|
||||
|
||||
with allure.step("2. 调用更新接口"):
|
||||
timestamp = int(time.time())
|
||||
update_params = {
|
||||
"banner_id": banner_id,
|
||||
"position": f"updated_position_{timestamp}",
|
||||
"platform": 2,
|
||||
"lang": "de",
|
||||
"rank_num": (timestamp % 1000) + 1,
|
||||
"banner_type": "updated_type",
|
||||
"status": 2,
|
||||
"interval_time": 10,
|
||||
"title": f"已更新Banner_{timestamp}",
|
||||
"sub_title": "已更新副标题",
|
||||
"image": {'url': 'https://www.toendi.com/static/image/updated.webp', 'name': 'Updated Banner', 'mime_type': 'image/webp'},
|
||||
"link": "https://updated-example.com"
|
||||
}
|
||||
resp = self.test_case.kw_joyhub_banner_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, "更新Banner失败"
|
||||
logging.info("更新Banner验证通过")
|
||||
|
||||
@allure.story("验证删除Banner")
|
||||
@allure.title("测试删除Banner管理接口")
|
||||
def test_joyhub_banner_delete_delete(self):
|
||||
"""测试删除Banner管理接口"""
|
||||
with allure.step("1. 先创建一个测试Banner"):
|
||||
timestamp = int(time.time())
|
||||
create_resp = self.test_case.kw_joyhub_banner_create_post(
|
||||
position=f"delete_test_{timestamp}",
|
||||
platform=1,
|
||||
lang="en",
|
||||
rank_num=timestamp % 1000,
|
||||
banner_type="promotion",
|
||||
status=2,
|
||||
interval_time=5,
|
||||
title=f"待删除Banner_{timestamp}"
|
||||
)
|
||||
banner_id = create_resp.get("data") if create_resp and create_resp.get("code") == 0 else None
|
||||
|
||||
if not banner_id:
|
||||
pytest.skip("创建测试Banner失败,跳过删除测试")
|
||||
|
||||
allure.attach(json.dumps({"id": banner_id}, ensure_ascii=False), name="待删除Banner ID", attachment_type=allure.attachment_type.TEXT)
|
||||
|
||||
with allure.step("2. 调用删除接口"):
|
||||
resp = self.test_case.kw_joyhub_banner_delete_delete(banner_id=banner_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, "删除Banner失败"
|
||||
logging.info("删除Banner验证通过")
|
||||
|
||||
@allure.story("验证批量删除Banner")
|
||||
@allure.title("测试批量删除Banner管理接口")
|
||||
def test_joyhub_banner_delete_list_delete(self):
|
||||
"""测试批量删除Banner管理接口"""
|
||||
with allure.step("1. 先创建两个测试Banner"):
|
||||
timestamp = int(time.time())
|
||||
resp1 = self.test_case.kw_joyhub_banner_create_post(
|
||||
position=f"batch_delete_1_{timestamp}",
|
||||
platform=1,
|
||||
lang="en",
|
||||
rank_num=timestamp % 1000,
|
||||
banner_type="promotion",
|
||||
status=2,
|
||||
interval_time=5,
|
||||
title=f"批量删除Banner1_{timestamp}"
|
||||
)
|
||||
resp2 = self.test_case.kw_joyhub_banner_create_post(
|
||||
position=f"batch_delete_2_{timestamp}",
|
||||
platform=1,
|
||||
lang="en",
|
||||
rank_num=timestamp % 1000 + 1,
|
||||
banner_type="promotion",
|
||||
status=2,
|
||||
interval_time=5,
|
||||
title=f"批量删除Banner2_{timestamp}"
|
||||
)
|
||||
|
||||
banner_id1 = resp1.get("data") if resp1 and resp1.get("code") == 0 else None
|
||||
banner_id2 = resp2.get("data") if resp2 and resp2.get("code") == 0 else None
|
||||
|
||||
if not banner_id1 or not banner_id2:
|
||||
pytest.skip("创建测试Banner失败,跳过批量删除测试")
|
||||
|
||||
banner_ids = [banner_id1, banner_id2]
|
||||
allure.attach(json.dumps({"ids": banner_ids}, ensure_ascii=False), name="待删除Banner IDs", attachment_type=allure.attachment_type.TEXT)
|
||||
|
||||
with allure.step("2. 调用批量删除接口"):
|
||||
resp = self.test_case.kw_joyhub_banner_delete_list_delete(banner_ids=banner_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, "批量删除Banner失败"
|
||||
logging.info("批量删除Banner验证通过")
|
||||
260
dulizhan/test_case/TestCase/接口/JoyHub/Joyhub_Dept.py
Normal file
260
dulizhan/test_case/TestCase/接口/JoyHub/Joyhub_Dept.py
Normal file
@@ -0,0 +1,260 @@
|
||||
import pytest
|
||||
import allure
|
||||
import logging
|
||||
import requests
|
||||
import json
|
||||
import time
|
||||
from dulizhan.library.BusinessKw.JoyHub.DeptManage import DeptManage
|
||||
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||
|
||||
|
||||
@allure.feature("管理后台 - 部门管理模块")
|
||||
class TestDeptManage:
|
||||
token_set = False
|
||||
dept_id = None
|
||||
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
"""在整个测试类开始时登录一次,所有测试用例共享token"""
|
||||
logging.info("=============================================")
|
||||
logging.info("=========== 开始登录,获取Token ============")
|
||||
logging.info("=============================================")
|
||||
|
||||
cls.test_case = DeptManage()
|
||||
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))
|
||||
logging.warning("如果是指纹锁问题,请联系管理员解除设备限制")
|
||||
except Exception as e:
|
||||
logging.error("登录异常: {}".format(str(e)))
|
||||
|
||||
def setup_method(self):
|
||||
"""每个测试方法执行前检查token"""
|
||||
if not self.token_set:
|
||||
pytest.skip("Token未设置,跳过测试")
|
||||
|
||||
@allure.story("验证登录接口")
|
||||
@allure.title("测试登录接口")
|
||||
def test_joyhub_login_post(self):
|
||||
"""测试登录接口"""
|
||||
assert self.token_set, "登录失败"
|
||||
logging.info("登录接口验证通过")
|
||||
|
||||
@allure.story("验证获取部门列表")
|
||||
@allure.title("测试获取部门列表接口")
|
||||
def test_joyhub_dept_list_get(self):
|
||||
"""测试获取部门列表接口"""
|
||||
with allure.step("1. 调用接口"):
|
||||
resp = self.test_case.kw_joyhub_dept_list_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("获取部门列表接口验证通过")
|
||||
|
||||
@allure.story("验证创建部门")
|
||||
@allure.title("测试创建部门接口")
|
||||
def test_joyhub_dept_create_post(self):
|
||||
"""测试创建部门接口"""
|
||||
with allure.step("1. 准备请求参数"):
|
||||
timestamp = int(time.time())
|
||||
params = {
|
||||
"name": f"测试部门_{timestamp}",
|
||||
"code": f"test_dept_{timestamp}",
|
||||
"sort": timestamp,
|
||||
"status": 1,
|
||||
"phone": "13900139000",
|
||||
"email": f"test_dept_{timestamp}@example.com"
|
||||
}
|
||||
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_dept_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字段应为整数类型(部门ID)"
|
||||
TestDeptManage.dept_id = resp["data"]
|
||||
logging.info(f"创建部门接口验证通过,部门ID: {TestDeptManage.dept_id}")
|
||||
|
||||
@allure.story("验证获得部门信息")
|
||||
@allure.title("测试获得部门信息接口")
|
||||
def test_joyhub_dept_get_get(self):
|
||||
"""测试获得部门信息接口"""
|
||||
if not TestDeptManage.dept_id:
|
||||
pytest.skip("没有可用的部门ID,跳过测试")
|
||||
|
||||
with allure.step("1. 调用接口"):
|
||||
resp = self.test_case.kw_joyhub_dept_get_get(dept_id=TestDeptManage.dept_id)
|
||||
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 "id" in resp["data"], "响应中缺少id字段"
|
||||
assert resp["data"]["id"] == TestDeptManage.dept_id, "返回的部门ID与请求不一致"
|
||||
logging.info("获得部门信息接口验证通过")
|
||||
|
||||
@allure.story("验证更新部门")
|
||||
@allure.title("测试更新部门接口")
|
||||
def test_joyhub_dept_update_put(self):
|
||||
"""测试更新部门接口"""
|
||||
if not TestDeptManage.dept_id:
|
||||
pytest.skip("没有可用的部门ID,跳过测试")
|
||||
|
||||
with allure.step("1. 准备更新参数"):
|
||||
timestamp = int(time.time())
|
||||
params = {
|
||||
"dept_id": TestDeptManage.dept_id,
|
||||
"name": f"测试部门_修改_{timestamp}",
|
||||
"sort": timestamp,
|
||||
"status": 1,
|
||||
"phone": "13900139999",
|
||||
"email": f"test_dept_updated_{timestamp}@example.com"
|
||||
}
|
||||
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_dept_update_put(**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_dept_delete_post(self):
|
||||
"""测试删除部门接口"""
|
||||
with allure.step("1. 先创建一个测试部门"):
|
||||
timestamp = int(time.time())
|
||||
create_resp = self.test_case.kw_joyhub_dept_create_post(
|
||||
name=f"删除测试部门_{timestamp}",
|
||||
sort=999,
|
||||
status=1
|
||||
)
|
||||
dept_id = create_resp.get("data") if create_resp and create_resp.get("code") == 0 else None
|
||||
|
||||
if not dept_id:
|
||||
pytest.skip("创建测试部门失败,跳过删除测试")
|
||||
|
||||
allure.attach(json.dumps({"id": dept_id}, ensure_ascii=False), name="待删除部门ID", attachment_type=allure.attachment_type.TEXT)
|
||||
|
||||
with allure.step("2. 调用删除接口"):
|
||||
resp = self.test_case.kw_joyhub_dept_delete_post(dept_id=dept_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字段"
|
||||
if resp["code"] == 1002005004:
|
||||
logging.warning(f"部门已被引用无法删除,code={resp.get('code')},msg={resp.get('msg')}")
|
||||
pytest.skip("部门已被其他数据引用,跳过删除测试")
|
||||
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_dept_delete_list_post(self):
|
||||
"""测试批量删除部门接口"""
|
||||
with allure.step("1. 先创建两个测试部门"):
|
||||
timestamp = int(time.time())
|
||||
dept_ids = []
|
||||
|
||||
for i in range(2):
|
||||
create_resp = self.test_case.kw_joyhub_dept_create_post(
|
||||
name=f"批量删除测试部门_{timestamp}_{i}",
|
||||
sort=888 + i,
|
||||
status=1
|
||||
)
|
||||
if create_resp and create_resp.get("code") == 0:
|
||||
dept_ids.append(create_resp.get("data"))
|
||||
|
||||
if len(dept_ids) < 2:
|
||||
pytest.skip("创建测试部门失败,跳过批量删除测试")
|
||||
|
||||
allure.attach(json.dumps({"ids": dept_ids}, ensure_ascii=False), name="待删除部门ID列表", attachment_type=allure.attachment_type.TEXT)
|
||||
|
||||
with allure.step("2. 调用批量删除接口"):
|
||||
resp = self.test_case.kw_joyhub_dept_delete_list_post(ids=dept_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字段"
|
||||
if resp["code"] == 1002005004:
|
||||
logging.warning(f"部门已被引用无法删除,code={resp.get('code')},msg={resp.get('msg')}")
|
||||
pytest.skip("部门已被其他数据引用,跳过批量删除测试")
|
||||
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_dept_list_all_simple_get(self):
|
||||
"""测试获取部门精简信息列表接口"""
|
||||
with allure.step("1. 调用接口"):
|
||||
resp = self.test_case.kw_joyhub_dept_list_all_simple_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("获取部门精简信息列表接口验证通过")
|
||||
|
||||
@allure.story("验证获取部门精简信息列表(simple-list)")
|
||||
@allure.title("测试获取部门精简信息列表接口(simple-list)")
|
||||
def test_joyhub_dept_simple_list_get(self):
|
||||
"""测试获取部门精简信息列表接口(simple-list)"""
|
||||
with allure.step("1. 调用接口"):
|
||||
resp = self.test_case.kw_joyhub_dept_simple_list_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("获取部门精简信息列表(simple-list)接口验证通过")
|
||||
305
dulizhan/test_case/TestCase/接口/JoyHub/Joyhub_Post.py
Normal file
305
dulizhan/test_case/TestCase/接口/JoyHub/Joyhub_Post.py
Normal file
@@ -0,0 +1,305 @@
|
||||
import pytest
|
||||
import allure
|
||||
import logging
|
||||
import requests
|
||||
import json
|
||||
import time
|
||||
from dulizhan.library.BusinessKw.JoyHub.PostManage import PostManage
|
||||
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||
|
||||
|
||||
@allure.feature("管理后台 - 岗位模块")
|
||||
class TestPostManage:
|
||||
post_id = None
|
||||
token_set = False
|
||||
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
"""在整个测试类开始时登录一次,所有测试用例共享token"""
|
||||
logging.info("=============================================")
|
||||
logging.info("=========== 开始登录,获取Token ============")
|
||||
logging.info("=============================================")
|
||||
|
||||
cls.test_case = PostManage()
|
||||
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)))
|
||||
|
||||
def setup_method(self):
|
||||
"""每个测试方法执行前检查token"""
|
||||
if not self.token_set:
|
||||
pytest.skip("Token未设置,跳过测试")
|
||||
|
||||
@allure.story("验证登录接口")
|
||||
@allure.title("测试登录接口")
|
||||
def test_joyhub_login_post(self):
|
||||
"""登录测试用例,验证登录接口是否正常"""
|
||||
with allure.step("1. 准备登录参数"):
|
||||
username = "joytest"
|
||||
password = "Zhou1599"
|
||||
allure.attach(f"用户名: {username}, 密码: {password}", name="登录参数", attachment_type=allure.attachment_type.TEXT)
|
||||
|
||||
with allure.step("2. 调用登录接口"):
|
||||
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'}
|
||||
response = requests.post(url, json=payload, headers=headers, verify=False, timeout=10)
|
||||
resp = response.json()
|
||||
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 "accessToken" in resp["data"], "响应中缺少accessToken字段"
|
||||
logging.info("登录接口验证通过")
|
||||
|
||||
@allure.story("验证获得岗位分页列表")
|
||||
@allure.title("测试获得岗位分页列表接口")
|
||||
def test_joyhub_post_page_get(self):
|
||||
"""测试获得岗位分页列表接口"""
|
||||
with allure.step("1. 准备请求参数"):
|
||||
params = {"pageNo": 1, "pageSize": 10}
|
||||
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_post_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 isinstance(resp["data"]["list"], list), "list字段不是数组类型"
|
||||
logging.info("获得岗位分页列表接口验证通过")
|
||||
|
||||
@allure.story("验证创建岗位")
|
||||
@allure.title("测试创建岗位接口")
|
||||
def test_joyhub_post_create_post(self):
|
||||
"""测试创建岗位接口"""
|
||||
with allure.step("1. 准备请求参数"):
|
||||
timestamp = int(time.time())
|
||||
params = {
|
||||
"name": f"测试岗位_{timestamp}",
|
||||
"code": f"test_post_{timestamp}",
|
||||
"sort": timestamp,
|
||||
"status": 1,
|
||||
"remark": "测试岗位备注"
|
||||
}
|
||||
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_post_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字段不是整数类型"
|
||||
TestPostManage.post_id = resp["data"]
|
||||
logging.info(f"创建岗位成功,岗位ID: {TestPostManage.post_id}")
|
||||
|
||||
@allure.story("验证获得岗位信息")
|
||||
@allure.title("测试获得岗位信息接口")
|
||||
def test_joyhub_post_get_get(self):
|
||||
"""测试获得岗位信息接口"""
|
||||
if not TestPostManage.post_id:
|
||||
pytest.skip("没有可用的岗位ID,跳过测试")
|
||||
|
||||
with allure.step("1. 准备请求参数"):
|
||||
params = {"id": TestPostManage.post_id}
|
||||
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_post_get_get(post_id=TestPostManage.post_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 "id" in resp["data"], "响应中缺少id字段"
|
||||
assert resp["data"]["id"] == TestPostManage.post_id, "返回的岗位ID与请求不一致"
|
||||
logging.info("获得岗位信息接口验证通过")
|
||||
|
||||
@allure.story("验证修改岗位")
|
||||
@allure.title("测试修改岗位接口")
|
||||
def test_joyhub_post_update_put(self):
|
||||
"""测试修改岗位接口"""
|
||||
with allure.step("1. 先创建一个测试岗位"):
|
||||
timestamp = int(time.time())
|
||||
create_resp = self.test_case.kw_joyhub_post_create_post(
|
||||
name=f"修改测试岗位_{timestamp}",
|
||||
code=f"update_test_post_{timestamp}",
|
||||
sort=888,
|
||||
status=1
|
||||
)
|
||||
post_id = create_resp.get("data") if create_resp and create_resp.get("code") == 0 else None
|
||||
|
||||
if not post_id:
|
||||
pytest.skip("创建测试岗位失败,跳过修改测试")
|
||||
|
||||
allure.attach(json.dumps({"id": post_id}, ensure_ascii=False), name="待修改岗位ID", attachment_type=allure.attachment_type.TEXT)
|
||||
|
||||
with allure.step("2. 准备修改参数"):
|
||||
params = {
|
||||
"post_id": post_id,
|
||||
"name": f"测试岗位_修改_{timestamp}",
|
||||
"code": f"test_post_updated_{timestamp}",
|
||||
"sort": 200,
|
||||
"status": 1,
|
||||
"remark": "修改后的备注"
|
||||
}
|
||||
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_post_update_put(**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 resp["data"] is True, "修改岗位失败"
|
||||
logging.info("修改岗位接口验证通过")
|
||||
|
||||
@allure.story("验证删除岗位")
|
||||
@allure.title("测试删除岗位接口")
|
||||
def test_joyhub_post_delete_post(self):
|
||||
"""测试删除岗位接口"""
|
||||
with allure.step("1. 先创建一个测试岗位"):
|
||||
timestamp = int(time.time())
|
||||
create_resp = self.test_case.kw_joyhub_post_create_post(
|
||||
name=f"删除测试岗位_{timestamp}",
|
||||
code=f"delete_test_post_{timestamp}",
|
||||
sort=999,
|
||||
status=1
|
||||
)
|
||||
post_id = create_resp.get("data") if create_resp and create_resp.get("code") == 0 else None
|
||||
|
||||
if not post_id:
|
||||
pytest.skip("创建测试岗位失败,跳过删除测试")
|
||||
|
||||
allure.attach(json.dumps({"id": post_id}, ensure_ascii=False), name="待删除岗位ID", attachment_type=allure.attachment_type.TEXT)
|
||||
|
||||
with allure.step("2. 调用删除接口"):
|
||||
resp = self.test_case.kw_joyhub_post_delete_post(post_id=post_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字段"
|
||||
# 错误码1002005004表示岗位被引用,允许这种情况通过
|
||||
if resp["code"] == 1002005004:
|
||||
logging.warning(f"岗位已被引用无法删除,code={resp.get('code')},msg={resp.get('msg')}")
|
||||
pytest.skip("岗位已被其他数据引用,跳过删除测试")
|
||||
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_post_delete_list_post(self):
|
||||
"""测试批量删除岗位接口"""
|
||||
with allure.step("1. 先创建两个测试岗位"):
|
||||
timestamp = int(time.time())
|
||||
resp1 = self.test_case.kw_joyhub_post_create_post(
|
||||
name=f"批量删除测试岗位1_{timestamp}",
|
||||
code=f"batch_delete_test_1_{timestamp}",
|
||||
sort=300,
|
||||
status=1
|
||||
)
|
||||
resp2 = self.test_case.kw_joyhub_post_create_post(
|
||||
name=f"批量删除测试岗位2_{timestamp}",
|
||||
code=f"batch_delete_test_2_{timestamp}",
|
||||
sort=301,
|
||||
status=1
|
||||
)
|
||||
|
||||
post_id_1 = resp1.get("data") if resp1 and resp1.get("code") == 0 else None
|
||||
post_id_2 = resp2.get("data") if resp2 and resp2.get("code") == 0 else None
|
||||
|
||||
if not post_id_1 or not post_id_2:
|
||||
pytest.skip("创建测试岗位失败,跳过批量删除测试")
|
||||
|
||||
ids = [post_id_1, post_id_2]
|
||||
allure.attach(json.dumps({"ids": ids}, ensure_ascii=False), name="待删除岗位ID", attachment_type=allure.attachment_type.TEXT)
|
||||
|
||||
with allure.step("2. 调用批量删除接口"):
|
||||
resp = self.test_case.kw_joyhub_post_delete_list_post(ids=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字段"
|
||||
# 错误码1002005004表示岗位被引用,允许这种情况通过
|
||||
if resp["code"] == 1002005004:
|
||||
logging.warning(f"岗位已被引用无法删除,code={resp.get('code')},msg={resp.get('msg')}")
|
||||
pytest.skip("岗位已被其他数据引用,跳过批量删除测试")
|
||||
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_post_list_all_simple_get(self):
|
||||
"""测试获取岗位全列表接口"""
|
||||
with allure.step("1. 调用接口"):
|
||||
resp = self.test_case.kw_joyhub_post_list_all_simple_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("获取岗位全列表接口验证通过")
|
||||
|
||||
@allure.story("验证获取岗位精简列表")
|
||||
@allure.title("测试获取岗位精简列表接口")
|
||||
def test_joyhub_post_simple_list_get(self):
|
||||
"""测试获取岗位精简列表接口"""
|
||||
with allure.step("1. 调用接口"):
|
||||
resp = self.test_case.kw_joyhub_post_simple_list_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("获取岗位精简列表接口验证通过")
|
||||
433
dulizhan/test_case/TestCase/接口/JoyHub/Joyhub_Role.py
Normal file
433
dulizhan/test_case/TestCase/接口/JoyHub/Joyhub_Role.py
Normal file
@@ -0,0 +1,433 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# 作者 周琦 2026/04/30
|
||||
"""
|
||||
JoyHub 角色管理测试用例
|
||||
"""
|
||||
import allure
|
||||
import logging
|
||||
import json
|
||||
import requests
|
||||
|
||||
from dulizhan.library.BusinessKw.JoyHub.RoleManage import RoleManage
|
||||
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||
|
||||
|
||||
@allure.feature('管理后台 - 角色模块')
|
||||
class TestRoleManage(object):
|
||||
test_case = RoleManage()
|
||||
created_role_id = None
|
||||
token_set = False
|
||||
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
"""在整个测试类开始时登录一次,所有测试用例共享token"""
|
||||
logging.info("=============================================")
|
||||
logging.info("=========== 开始登录,获取Token ============")
|
||||
logging.info("=============================================")
|
||||
|
||||
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'}
|
||||
|
||||
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_role_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_role_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_role_create_post(self):
|
||||
"""测试新增角色"""
|
||||
import random
|
||||
|
||||
with allure.step("准备新增角色参数"):
|
||||
role_name = "测试角色{}".format(random.randint(1000, 9999))
|
||||
role_code = "TEST_ROLE_{}".format(random.randint(1000, 9999))
|
||||
payload = {
|
||||
"name": role_name,
|
||||
"code": role_code,
|
||||
"sort": 100,
|
||||
"status": 1,
|
||||
"remark": "测试角色备注"
|
||||
}
|
||||
allure.attach(json.dumps(payload, ensure_ascii=False, indent=2), "请求参数", attachment_type=allure.attachment_type.JSON)
|
||||
logging.info("准备新增角色: {}".format(role_name))
|
||||
|
||||
with allure.step("调用新增角色接口"):
|
||||
response_data = self.test_case.kw_joyhub_role_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字段不为空 ✓")
|
||||
|
||||
assert isinstance(response_data['data'], int), "data字段应为整数类型"
|
||||
logging.info("断言: data字段为整数类型 ✓")
|
||||
|
||||
logging.info("✓ 新增角色成功,角色ID: {}".format(response_data['data']))
|
||||
self.created_role_id = response_data['data']
|
||||
|
||||
@allure.story("验证获得角色详情")
|
||||
def test_joyhub_role_get_get(self):
|
||||
"""测试角色详情查询"""
|
||||
import random
|
||||
|
||||
with allure.step("创建测试角色"):
|
||||
role_name = "测试角色详情{}".format(random.randint(1000, 9999))
|
||||
role_code = "TEST_ROLE_DETAIL_{}".format(random.randint(1000, 9999))
|
||||
create_resp = self.test_case.kw_joyhub_role_create_post(
|
||||
note="创建测试角色",
|
||||
name=role_name,
|
||||
code=role_code,
|
||||
sort=200,
|
||||
status=1
|
||||
)
|
||||
role_id = create_resp.get('data')
|
||||
logging.info("创建测试角色成功,角色ID: {}".format(role_id))
|
||||
|
||||
with allure.step("调用查询角色详情接口"):
|
||||
params = {"id": role_id}
|
||||
allure.attach(json.dumps(params, ensure_ascii=False, indent=2), "请求参数", attachment_type=allure.attachment_type.JSON)
|
||||
response_data = self.test_case.kw_joyhub_role_get_get(
|
||||
note="获得角色信息",
|
||||
id=role_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'] == role_id, "返回的角色ID与请求不一致"
|
||||
logging.info("断言: 返回的角色ID与请求一致 ✓")
|
||||
|
||||
assert 'name' in data, "角色详情中缺少name字段"
|
||||
logging.info("断言: 角色详情包含name字段 ✓")
|
||||
|
||||
assert data['name'] == role_name, "返回的角色名称与创建时不一致"
|
||||
logging.info("断言: 返回的角色名称与创建时一致 ✓")
|
||||
|
||||
logging.info("✓ 角色详情查询成功")
|
||||
|
||||
@allure.story("验证修改角色")
|
||||
def test_joyhub_role_update_put(self):
|
||||
"""测试修改角色"""
|
||||
import random
|
||||
|
||||
with allure.step("创建测试角色"):
|
||||
role_name = "测试角色修改{}".format(random.randint(1000, 9999))
|
||||
role_code = "TEST_ROLE_UPDATE_{}".format(random.randint(1000, 9999))
|
||||
create_resp = self.test_case.kw_joyhub_role_create_post(
|
||||
note="创建测试角色",
|
||||
name=role_name,
|
||||
code=role_code,
|
||||
sort=300,
|
||||
status=1
|
||||
)
|
||||
role_id = create_resp.get('data')
|
||||
logging.info("创建测试角色成功,角色ID: {}".format(role_id))
|
||||
|
||||
with allure.step("准备修改参数"):
|
||||
new_name = "修改后的角色名称{}".format(random.randint(1000, 9999))
|
||||
payload = {
|
||||
"id": role_id,
|
||||
"name": new_name,
|
||||
"code": role_code,
|
||||
"sort": 301,
|
||||
"status": 1,
|
||||
"remark": "修改后的备注"
|
||||
}
|
||||
allure.attach(json.dumps(payload, ensure_ascii=False, indent=2), "请求参数", attachment_type=allure.attachment_type.JSON)
|
||||
logging.info("准备修改角色,新名称: {}".format(new_name))
|
||||
|
||||
with allure.step("调用修改角色接口"):
|
||||
response_data = self.test_case.kw_joyhub_role_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_role_delete_post(self):
|
||||
"""测试删除角色"""
|
||||
import random
|
||||
|
||||
with allure.step("创建测试角色"):
|
||||
role_name = "测试角色删除{}".format(random.randint(1000, 9999))
|
||||
role_code = "TEST_ROLE_DELETE_{}".format(random.randint(1000, 9999))
|
||||
create_resp = self.test_case.kw_joyhub_role_create_post(
|
||||
note="创建测试角色",
|
||||
name=role_name,
|
||||
code=role_code,
|
||||
sort=400,
|
||||
status=1
|
||||
)
|
||||
role_id = create_resp.get('data')
|
||||
logging.info("创建测试角色成功,角色ID: {}".format(role_id))
|
||||
|
||||
with allure.step("准备删除参数"):
|
||||
payload = {"id": role_id}
|
||||
allure.attach(json.dumps(payload, ensure_ascii=False, indent=2), "请求参数", attachment_type=allure.attachment_type.JSON)
|
||||
logging.info("准备删除角色,角色ID: {}".format(role_id))
|
||||
|
||||
with allure.step("调用删除接口"):
|
||||
response_data = self.test_case.kw_joyhub_role_delete_post(
|
||||
note="删除角色",
|
||||
id=role_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_role_delete_list_post(self):
|
||||
"""测试批量删除角色"""
|
||||
import random
|
||||
|
||||
with allure.step("创建测试角色"):
|
||||
role_ids = []
|
||||
for i in range(2):
|
||||
role_name = "测试批量删除角色{}".format(random.randint(1000, 9999))
|
||||
role_code = "TEST_ROLE_BATCH_{}_{}".format(random.randint(1000, 9999), i)
|
||||
create_resp = self.test_case.kw_joyhub_role_create_post(
|
||||
note="创建测试角色{}".format(i),
|
||||
name=role_name,
|
||||
code=role_code,
|
||||
sort=500 + i,
|
||||
status=1
|
||||
)
|
||||
role_ids.append(create_resp.get('data'))
|
||||
logging.info("创建测试角色成功,角色ID列表: {}".format(role_ids))
|
||||
|
||||
with allure.step("准备批量删除参数"):
|
||||
payload = {"ids": role_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_role_delete_list_post(
|
||||
note="批量删除角色",
|
||||
ids=role_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("✓ 批量删除角色成功")
|
||||
|
||||
@allure.story("验证获取角色精简信息列表")
|
||||
def test_joyhub_role_simple_list_get(self):
|
||||
"""测试获取角色精简信息列表"""
|
||||
with allure.step("调用查询接口"):
|
||||
response_data = self.test_case.kw_joyhub_role_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_role_list_all_simple_get(self):
|
||||
"""测试获取所有角色精简信息列表"""
|
||||
with allure.step("调用查询接口"):
|
||||
response_data = self.test_case.kw_joyhub_role_list_all_simple_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("✓ 所有角色精简信息列表查询成功")
|
||||
308
dulizhan/test_case/TestCase/接口/JoyHub/Joyhub_ShippingTemplate.py
Normal file
308
dulizhan/test_case/TestCase/接口/JoyHub/Joyhub_ShippingTemplate.py
Normal file
@@ -0,0 +1,308 @@
|
||||
import pytest
|
||||
import allure
|
||||
import logging
|
||||
import requests
|
||||
import json
|
||||
import time
|
||||
from dulizhan.library.BusinessKw.JoyHub.ShippingTemplateManage import ShippingTemplateManage
|
||||
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||
|
||||
|
||||
@allure.feature("管理后台 - 运费模板模块")
|
||||
class TestShippingTemplateManage:
|
||||
shipping_template_id = None
|
||||
token_set = False
|
||||
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
"""在整个测试类开始时登录一次,所有测试用例共享token"""
|
||||
logging.info("=============================================")
|
||||
logging.info("=========== 开始登录,获取Token ============")
|
||||
logging.info("=============================================")
|
||||
|
||||
cls.test_case = ShippingTemplateManage()
|
||||
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)))
|
||||
|
||||
def setup_method(self):
|
||||
"""每个测试方法执行前检查token"""
|
||||
if not self.token_set:
|
||||
pytest.skip("Token未设置,跳过测试")
|
||||
|
||||
@allure.story("验证登录接口")
|
||||
@allure.title("测试登录接口")
|
||||
def test_joyhub_login_post(self):
|
||||
"""登录测试用例,验证登录接口是否正常"""
|
||||
with allure.step("1. 准备登录参数"):
|
||||
username = "joytest"
|
||||
password = "Zhou1599"
|
||||
allure.attach(f"用户名: {username}, 密码: {password}", name="登录参数", attachment_type=allure.attachment_type.TEXT)
|
||||
|
||||
with allure.step("2. 调用登录接口"):
|
||||
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'}
|
||||
response = requests.post(url, json=payload, headers=headers, verify=False, timeout=10)
|
||||
resp = response.json()
|
||||
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 "accessToken" in resp["data"], "响应中缺少accessToken字段"
|
||||
logging.info("登录接口验证通过")
|
||||
|
||||
@allure.story("验证获得运费模板分页列表")
|
||||
@allure.title("测试获得运费模板分页列表接口")
|
||||
def test_joyhub_shipping_template_page_get(self):
|
||||
"""测试获得运费模板分页列表接口"""
|
||||
with allure.step("1. 准备请求参数"):
|
||||
params = {"page_no": 1, "page_size": 10}
|
||||
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_shipping_template_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 isinstance(resp["data"]["list"], list), "list字段不是数组类型"
|
||||
logging.info("获得运费模板分页列表接口验证通过")
|
||||
|
||||
@allure.story("验证创建运费模板")
|
||||
@allure.title("测试创建运费模板接口")
|
||||
def test_joyhub_shipping_template_create_post(self):
|
||||
"""测试创建运费模板接口"""
|
||||
with allure.step("1. 准备请求参数"):
|
||||
timestamp = int(time.time())
|
||||
params = {
|
||||
"template_name": f"测试模板_{timestamp}",
|
||||
"is_default": 2,
|
||||
"calculation_algorithm": "fixed_amount",
|
||||
"currency": "USD",
|
||||
"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_shipping_template_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字段不是整数类型"
|
||||
TestShippingTemplateManage.shipping_template_id = resp["data"]
|
||||
logging.info(f"创建运费模板成功,模板ID: {TestShippingTemplateManage.shipping_template_id}")
|
||||
|
||||
@allure.story("验证获得运费模板详情")
|
||||
@allure.title("测试获得运费模板详情接口")
|
||||
def test_joyhub_shipping_template_get_detail_get(self):
|
||||
"""测试获得运费模板详情(含规则与子表)接口"""
|
||||
if not TestShippingTemplateManage.shipping_template_id:
|
||||
pytest.skip("没有可用的运费模板ID,跳过测试")
|
||||
|
||||
with allure.step("1. 准备请求参数"):
|
||||
shipping_template_id = TestShippingTemplateManage.shipping_template_id
|
||||
allure.attach(json.dumps({"id": shipping_template_id}, ensure_ascii=False), name="请求参数", attachment_type=allure.attachment_type.TEXT)
|
||||
|
||||
with allure.step("2. 调用接口"):
|
||||
resp = self.test_case.kw_joyhub_shipping_template_get_detail_get(shipping_template_id=shipping_template_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字段"
|
||||
logging.info("获得运费模板详情接口验证通过")
|
||||
|
||||
@allure.story("验证保存运费模板(含规则与子表)")
|
||||
@allure.title("测试保存运费模板(含规则与子表)接口")
|
||||
def test_joyhub_shipping_template_save_with_children_post(self):
|
||||
"""测试保存运费模板信息(含规则与子表)接口"""
|
||||
with allure.step("1. 准备请求参数"):
|
||||
timestamp = int(time.time())
|
||||
params = {
|
||||
"template_name": f"测试模板_含规则_{timestamp}",
|
||||
"is_default": 2,
|
||||
"calculation_algorithm": "fixed_amount",
|
||||
"currency": "USD",
|
||||
"status": 1,
|
||||
"shipping_rules": []
|
||||
}
|
||||
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_shipping_template_save_with_children_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字段不是整数类型"
|
||||
logging.info(f"保存运费模板(含规则与子表)成功,模板ID: {resp['data']}")
|
||||
|
||||
@allure.story("验证更新运费模板")
|
||||
@allure.title("测试更新运费模板接口")
|
||||
def test_joyhub_shipping_template_update_put(self):
|
||||
"""测试更新运费模板接口"""
|
||||
with allure.step("1. 先创建一个测试运费模板"):
|
||||
timestamp = int(time.time())
|
||||
create_resp = self.test_case.kw_joyhub_shipping_template_create_post(
|
||||
template_name=f"待修改模板_{timestamp}",
|
||||
is_default=2,
|
||||
calculation_algorithm="fixed_amount",
|
||||
currency="USD",
|
||||
status=1
|
||||
)
|
||||
shipping_template_id = create_resp.get("data") if create_resp and create_resp.get("code") == 0 else None
|
||||
|
||||
if not shipping_template_id:
|
||||
pytest.skip("创建测试运费模板失败,跳过更新测试")
|
||||
|
||||
allure.attach(json.dumps({"id": shipping_template_id}, ensure_ascii=False), name="待修改模板ID", attachment_type=allure.attachment_type.TEXT)
|
||||
|
||||
with allure.step("2. 准备修改参数"):
|
||||
params = {
|
||||
"id": shipping_template_id,
|
||||
"template_name": f"测试模板_修改_{timestamp}",
|
||||
"is_default": 2,
|
||||
"calculation_algorithm": "percentage",
|
||||
"currency": "CNY",
|
||||
"status": 2
|
||||
}
|
||||
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_shipping_template_update_put(**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 resp["data"] is True, "更新运费模板失败"
|
||||
logging.info("更新运费模板接口验证通过")
|
||||
|
||||
@allure.story("验证删除运费模板")
|
||||
@allure.title("测试删除运费模板接口")
|
||||
def test_joyhub_shipping_template_delete_post(self):
|
||||
"""测试删除运费模板接口"""
|
||||
with allure.step("1. 先创建一个测试运费模板"):
|
||||
timestamp = int(time.time())
|
||||
create_resp = self.test_case.kw_joyhub_shipping_template_create_post(
|
||||
template_name=f"待删除模板_{timestamp}",
|
||||
is_default=2,
|
||||
calculation_algorithm="fixed_amount",
|
||||
currency="USD",
|
||||
status=1
|
||||
)
|
||||
shipping_template_id = create_resp.get("data") if create_resp and create_resp.get("code") == 0 else None
|
||||
|
||||
if not shipping_template_id:
|
||||
pytest.skip("创建测试运费模板失败,跳过删除测试")
|
||||
|
||||
allure.attach(json.dumps({"id": shipping_template_id}, ensure_ascii=False), name="待删除模板ID", attachment_type=allure.attachment_type.TEXT)
|
||||
|
||||
with allure.step("2. 先停用模板(启用的不能删)"):
|
||||
update_resp = self.test_case.kw_joyhub_shipping_template_update_put(
|
||||
id=shipping_template_id,
|
||||
template_name=f"待删除模板_{timestamp}",
|
||||
is_default=2,
|
||||
calculation_algorithm="fixed_amount",
|
||||
currency="USD",
|
||||
status=2
|
||||
)
|
||||
if update_resp.get("code") != 0:
|
||||
pytest.skip("停用模板失败,跳过删除测试")
|
||||
logging.info(f"已停用模板 {shipping_template_id}")
|
||||
|
||||
with allure.step("3. 调用删除接口"):
|
||||
resp = self.test_case.kw_joyhub_shipping_template_delete_post(shipping_template_id=shipping_template_id)
|
||||
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 resp["data"] is True, "删除运费模板失败"
|
||||
logging.info("删除运费模板接口验证通过")
|
||||
|
||||
@allure.story("验证批量删除运费模板")
|
||||
@allure.title("测试批量删除运费模板接口")
|
||||
def test_joyhub_shipping_template_delete_list_post(self):
|
||||
"""测试批量删除运费模板接口"""
|
||||
with allure.step("1. 先创建两个测试运费模板"):
|
||||
timestamp = int(time.time())
|
||||
resp1 = self.test_case.kw_joyhub_shipping_template_create_post(
|
||||
template_name=f"批量删除模板1_{timestamp}",
|
||||
is_default=2,
|
||||
calculation_algorithm="fixed_amount",
|
||||
currency="USD",
|
||||
status=1
|
||||
)
|
||||
resp2 = self.test_case.kw_joyhub_shipping_template_create_post(
|
||||
template_name=f"批量删除模板2_{timestamp}",
|
||||
is_default=2,
|
||||
calculation_algorithm="fixed_amount",
|
||||
currency="USD",
|
||||
status=1
|
||||
)
|
||||
|
||||
template_id_1 = resp1.get("data") if resp1 and resp1.get("code") == 0 else None
|
||||
template_id_2 = resp2.get("data") if resp2 and resp2.get("code") == 0 else None
|
||||
|
||||
if not template_id_1 or not template_id_2:
|
||||
pytest.skip("创建测试运费模板失败,跳过批量删除测试")
|
||||
|
||||
ids = [template_id_1, template_id_2]
|
||||
allure.attach(json.dumps({"ids": ids}, ensure_ascii=False), name="待删除模板ID", attachment_type=allure.attachment_type.TEXT)
|
||||
|
||||
with allure.step("2. 调用批量删除接口"):
|
||||
resp = self.test_case.kw_joyhub_shipping_template_delete_list_post(ids=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("批量删除运费模板接口验证通过")
|
||||
174
dulizhan/test_case/TestCase/接口/JoyHub/Joyhub_UserProfile.py
Normal file
174
dulizhan/test_case/TestCase/接口/JoyHub/Joyhub_UserProfile.py
Normal file
@@ -0,0 +1,174 @@
|
||||
import pytest
|
||||
import allure
|
||||
import logging
|
||||
import requests
|
||||
import json
|
||||
from dulizhan.library.BusinessKw.JoyHub.UserProfile import UserProfile
|
||||
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||
|
||||
|
||||
@allure.feature("管理后台 - 用户个人中心模块")
|
||||
class TestUserProfile:
|
||||
token_set = False
|
||||
original_password = "Zhou1599"
|
||||
test_password = "Aa123456"
|
||||
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
"""在整个测试类开始时登录一次,所有测试用例共享token"""
|
||||
logging.info("=============================================")
|
||||
logging.info("=========== 开始登录,获取Token ============")
|
||||
logging.info("=============================================")
|
||||
|
||||
cls.test_case = UserProfile()
|
||||
username = "joytest"
|
||||
password = cls.original_password
|
||||
|
||||
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)))
|
||||
|
||||
def setup_method(self):
|
||||
"""每个测试方法执行前检查token"""
|
||||
if not self.token_set:
|
||||
pytest.skip("Token未设置,跳过测试")
|
||||
|
||||
@classmethod
|
||||
def teardown_class(cls):
|
||||
"""测试类结束后,确保密码改回原密码"""
|
||||
logging.info("=============================================")
|
||||
logging.info("=========== 测试结束,恢复原密码 ============")
|
||||
logging.info("=============================================")
|
||||
|
||||
try:
|
||||
# 先用测试密码登录
|
||||
url = "https://joyhub-website-manager-api-test.best-envision.com/admin-api/system/auth/login-dev"
|
||||
payload = {"username": "joytest", "password": cls.test_password}
|
||||
headers = {'Content-Type': 'application/json', 'tenant-id': '126'}
|
||||
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)
|
||||
resp = cls.test_case.kw_joyhub_user_profile_update_password_put(
|
||||
old_password=cls.test_password,
|
||||
new_password=cls.original_password
|
||||
)
|
||||
if resp and resp.get('code') == 0:
|
||||
logging.info("密码已恢复为原密码: {}".format(cls.original_password))
|
||||
else:
|
||||
logging.warning("恢复原密码失败: {}".format(resp))
|
||||
except Exception as e:
|
||||
logging.error("恢复原密码异常: {}".format(str(e)))
|
||||
|
||||
@allure.story("验证获得登录用户信息")
|
||||
@allure.title("测试获得登录用户信息接口")
|
||||
def test_joyhub_user_profile_get_get(self):
|
||||
"""测试获得登录用户信息接口"""
|
||||
with allure.step("1. 调用接口"):
|
||||
resp = self.test_case.kw_joyhub_user_profile_get_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 "id" in resp["data"], "响应中缺少id字段"
|
||||
assert "username" in resp["data"], "响应中缺少username字段"
|
||||
logging.info("获得登录用户信息接口验证通过")
|
||||
|
||||
@allure.story("验证修改用户个人信息")
|
||||
@allure.title("测试修改用户个人信息接口")
|
||||
def test_joyhub_user_profile_update_put(self):
|
||||
"""测试修改用户个人信息接口"""
|
||||
with allure.step("1. 先获取当前用户信息"):
|
||||
get_resp = self.test_case.kw_joyhub_user_profile_get_get()
|
||||
if not get_resp or get_resp.get('code') != 0:
|
||||
pytest.skip("获取用户信息失败,跳过修改测试")
|
||||
|
||||
original_data = get_resp.get('data', {})
|
||||
allure.attach(json.dumps(original_data, ensure_ascii=False, indent=2), name="原始用户信息", attachment_type=allure.attachment_type.JSON)
|
||||
|
||||
with allure.step("2. 准备修改参数"):
|
||||
params = {
|
||||
"nickname": "测试用户_修改",
|
||||
"email": "test_updated@example.com",
|
||||
"mobile": "13900139000",
|
||||
"sex": 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_user_profile_update_put(**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 resp["data"] is True, "修改用户个人信息失败"
|
||||
logging.info("修改用户个人信息接口验证通过")
|
||||
|
||||
with allure.step("5. 恢复原始信息"):
|
||||
# 恢复原始信息
|
||||
restore_params = {
|
||||
"nickname": original_data.get("nickname", ""),
|
||||
"email": original_data.get("email", ""),
|
||||
"mobile": original_data.get("mobile", ""),
|
||||
"sex": original_data.get("sex"),
|
||||
"avatar": original_data.get("avatar", "")
|
||||
}
|
||||
restore_resp = self.test_case.kw_joyhub_user_profile_update_put(**restore_params)
|
||||
if restore_resp and restore_resp.get('code') == 0:
|
||||
logging.info("用户信息已恢复")
|
||||
else:
|
||||
logging.warning("恢复用户信息失败: {}".format(restore_resp))
|
||||
|
||||
@allure.story("验证修改用户个人密码")
|
||||
@allure.title("测试修改用户个人密码接口")
|
||||
def test_joyhub_user_profile_update_password_put(self):
|
||||
"""测试修改用户个人密码接口"""
|
||||
with allure.step("1. 准备修改密码参数"):
|
||||
params = {
|
||||
"old_password": self.original_password,
|
||||
"new_password": self.test_password
|
||||
}
|
||||
allure.attach(json.dumps({"oldPassword": "******", "newPassword": "******"}, ensure_ascii=False), name="修改参数", attachment_type=allure.attachment_type.TEXT)
|
||||
|
||||
with allure.step("2. 调用修改密码接口"):
|
||||
resp = self.test_case.kw_joyhub_user_profile_update_password_put(**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("修改用户个人密码接口验证通过,密码已修改为: {}".format(self.test_password))
|
||||
logging.info("注意:测试类结束后将自动恢复原密码: {}".format(self.original_password))
|
||||
534
dulizhan/test_case/TestCase/接口/JoyHub/Joyhub_user.py
Normal file
534
dulizhan/test_case/TestCase/接口/JoyHub/Joyhub_user.py
Normal file
@@ -0,0 +1,534 @@
|
||||
# -*- 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("✓ 批量删除用户成功")
|
||||
7
dulizhan/test_case/TestCase/接口/JoyHub/__init__.py
Normal file
7
dulizhan/test_case/TestCase/接口/JoyHub/__init__.py
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
"""
|
||||
JoyHub接口测试用例模块
|
||||
"""
|
||||
from .Joyhub_user import TestUserManage
|
||||
|
||||
__all__ = ['TestUserManage']
|
||||
@@ -0,0 +1,75 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import allure
|
||||
import logging
|
||||
|
||||
from zhyy.library.BusinessKw.SZPurchase.PurchaseOrderManage import PurchaseOrder
|
||||
|
||||
|
||||
@allure.feature('深圳采购工作台采购订单页面')
|
||||
class Test_purchase_order(object):
|
||||
test_case = PurchaseOrder()
|
||||
|
||||
def teardown_method(self):
|
||||
logging.info("-----------------------------End-------------------------------")
|
||||
|
||||
@allure.story("验证采购工作台采购订单页面列表查询")
|
||||
def test_check_purchase_order_page(self):
|
||||
purchase_order_code = 'PO251209048' # 采购单号 必填
|
||||
supplier_company_ids = ['334'] # 供应商id 非必填
|
||||
payment_status = '0' # 付款状态 非必填
|
||||
status = '0' # 采购单状态 非必填
|
||||
page_no = 1 # 页码 必填
|
||||
page_size = 10 # 每页条数 必填
|
||||
response_data = self.test_case.kw_zhyy_get_purchase_page_post(
|
||||
note="采购工作台采购订单页面列表查询",
|
||||
user='purchase',
|
||||
order_sn=purchase_order_code,
|
||||
supplier_company_ids=supplier_company_ids,
|
||||
payment_status=payment_status,
|
||||
status=status,
|
||||
page_no=page_no,
|
||||
page_size=page_size
|
||||
)
|
||||
|
||||
# 断言检查
|
||||
assert response_data is not None, "响应数据不能为空"
|
||||
assert 'code' in response_data, "响应数据中缺少code字段"
|
||||
assert response_data['code'] == 0, "接口调用失败,code: {}, msg: {}".format(
|
||||
response_data.get('code'), response_data.get('msg', '未知错误'))
|
||||
assert 'data' in response_data, "响应数据中缺少data字段"
|
||||
assert response_data['data'] is not None, "响应数据中的data字段不能为空"
|
||||
|
||||
# 如果传入了采购单号,检查返回的数据中是否包含该采购单号
|
||||
if purchase_order_code:
|
||||
data = response_data.get('data', {})
|
||||
order_found = False
|
||||
|
||||
# 检查返回的数据结构,可能包含列表或其他结构
|
||||
if isinstance(data, dict):
|
||||
# 如果data是字典,可能包含records、list、data等字段
|
||||
records = data.get('records') or data.get('list') or data.get('data') or []
|
||||
if isinstance(records, list) and len(records) > 0:
|
||||
# 检查列表中是否包含指定的采购单号
|
||||
for item in records:
|
||||
if isinstance(item, dict):
|
||||
order_sn = item.get('order_sn') or item.get('orderSn') or item.get('orderSn')
|
||||
if order_sn == purchase_order_code:
|
||||
order_found = True
|
||||
break
|
||||
elif isinstance(data, list):
|
||||
# 如果data本身就是列表
|
||||
for item in data:
|
||||
if isinstance(item, dict):
|
||||
order_sn = item.get('order_sn') or item.get('orderSn') or item.get('orderSn')
|
||||
if order_sn == purchase_order_code:
|
||||
order_found = True
|
||||
break
|
||||
|
||||
if order_found:
|
||||
logging.info("✓ 断言通过:返回的数据中包含采购单号 {}".format(purchase_order_code))
|
||||
else:
|
||||
logging.warning("⚠ 警告:返回的数据中未找到采购单号: {},但接口调用成功".format(purchase_order_code))
|
||||
|
||||
logging.info("✓ 所有断言检查通过")
|
||||
print("✓ 查询成功,响应数据: {}".format(response_data))
|
||||
19
dulizhan/test_case/TestCase/接口/SZPurchase/index.py
Normal file
19
dulizhan/test_case/TestCase/接口/SZPurchase/index.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import allure
|
||||
import logging
|
||||
|
||||
from zhyy.library.BusinessKw.SZPurchase.index import PurchaseIndex
|
||||
|
||||
|
||||
@allure.feature('深圳采购工作台首页')
|
||||
class Test_purchase_index(object):
|
||||
# config = ReadConfig.ReadConfig() # 调用读取配置文件的方法类
|
||||
test_case = PurchaseIndex()
|
||||
|
||||
def teardown_method(self):
|
||||
logging.info("-----------------------------End-------------------------------")
|
||||
|
||||
@allure.story("验证采购工作台待办任务与在办任务功能")
|
||||
def test_check_todo(self):
|
||||
get_purchase_data = self.test_case.kw_zhyy_get_todo(note="采购工作台首页待办任务PO与在办任务PO", user='purchase')
|
||||
0
dulizhan/test_case/TestCase/接口/__init__.py
Normal file
0
dulizhan/test_case/TestCase/接口/__init__.py
Normal file
14
dulizhan/test_case/TestCase/接口/conftest.py
Normal file
14
dulizhan/test_case/TestCase/接口/conftest.py
Normal file
@@ -0,0 +1,14 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
测试配置文件
|
||||
用于设置测试环境的路径和配置
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
|
||||
# 添加项目根目录到 Python 路径,确保能导入 zhyy 模块
|
||||
current_file_path = os.path.abspath(__file__)
|
||||
# 从 test_case/TestCase/接口/conftest.py 向上找到项目根目录 d:\zhyy
|
||||
project_root = os.path.abspath(os.path.join(os.path.dirname(current_file_path), '../../../..'))
|
||||
if project_root not in sys.path:
|
||||
sys.path.insert(0, project_root)
|
||||
0
dulizhan/test_case/__init__.py
Normal file
0
dulizhan/test_case/__init__.py
Normal file
44
dulizhan/test_case/jenkins_build.bat
Normal file
44
dulizhan/test_case/jenkins_build.bat
Normal file
@@ -0,0 +1,44 @@
|
||||
@echo off
|
||||
REM Jenkins构建脚本(Windows)
|
||||
REM 用于在Jenkins中执行测试并生成Allure报告
|
||||
|
||||
setlocal enabledelayedexpansion
|
||||
|
||||
REM 设置工作目录
|
||||
if defined WORKSPACE (
|
||||
cd /d %WORKSPACE%
|
||||
) else (
|
||||
cd /d %~dp0..
|
||||
)
|
||||
|
||||
REM 进入测试目录
|
||||
cd zhyy\test_case
|
||||
|
||||
REM 运行测试(根据参数选择运行方式)
|
||||
if "%RUN_TYPE%"=="" set RUN_TYPE=all
|
||||
|
||||
if "%RUN_TYPE%"=="all" (
|
||||
python run_tests.py --all --no-report
|
||||
) else if "%RUN_TYPE%"=="feature" (
|
||||
python run_tests.py --feature "%FEATURE_NAME%" --no-report
|
||||
) else if "%RUN_TYPE%"=="story" (
|
||||
python run_tests.py --story "%STORY_NAME%" --no-report
|
||||
) else if "%RUN_TYPE%"=="dir" (
|
||||
python run_tests.py --dir "%DIR_PATH%" --no-report
|
||||
) else if "%RUN_TYPE%"=="file" (
|
||||
python run_tests.py --file "%FILE_PATH%" --no-report
|
||||
) else if "%RUN_TYPE%"=="keyword" (
|
||||
python run_tests.py --keyword "%KEYWORD%" --no-report
|
||||
) else if "%RUN_TYPE%"=="marker" (
|
||||
python run_tests.py --marker "%MARKER%" --no-report
|
||||
) else (
|
||||
echo 未知的运行类型: %RUN_TYPE%
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
REM 生成Allure报告(Jenkins插件会自动处理,这里可选)
|
||||
REM allure generate reports\allure-results -o reports\allure-report --clean
|
||||
|
||||
echo 测试执行完成,Allure结果已保存到: reports\allure-results
|
||||
|
||||
endlocal
|
||||
47
dulizhan/test_case/jenkins_build.sh
Normal file
47
dulizhan/test_case/jenkins_build.sh
Normal file
@@ -0,0 +1,47 @@
|
||||
#!/bin/bash
|
||||
# Jenkins构建脚本(Linux/Mac)
|
||||
# 用于在Jenkins中执行测试并生成Allure报告
|
||||
|
||||
set -e # 遇到错误立即退出
|
||||
|
||||
# 设置工作目录
|
||||
cd ${WORKSPACE:-$(pwd)}
|
||||
|
||||
# 进入测试目录
|
||||
cd zhyy/test_case
|
||||
|
||||
# 运行测试(根据参数选择运行方式)
|
||||
RUN_TYPE=${RUN_TYPE:-all}
|
||||
|
||||
case ${RUN_TYPE} in
|
||||
all)
|
||||
python run_tests.py --all --no-report
|
||||
;;
|
||||
feature)
|
||||
python run_tests.py --feature "${FEATURE_NAME}" --no-report
|
||||
;;
|
||||
story)
|
||||
python run_tests.py --story "${STORY_NAME}" --no-report
|
||||
;;
|
||||
dir)
|
||||
python run_tests.py --dir "${DIR_PATH}" --no-report
|
||||
;;
|
||||
file)
|
||||
python run_tests.py --file "${FILE_PATH}" --no-report
|
||||
;;
|
||||
keyword)
|
||||
python run_tests.py --keyword "${KEYWORD}" --no-report
|
||||
;;
|
||||
marker)
|
||||
python run_tests.py --marker "${MARKER}" --no-report
|
||||
;;
|
||||
*)
|
||||
echo "未知的运行类型: ${RUN_TYPE}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# 生成Allure报告(Jenkins插件会自动处理,这里可选)
|
||||
# allure generate reports/allure-results -o reports/allure-report --clean || true
|
||||
|
||||
echo "测试执行完成,Allure结果已保存到: reports/allure-results"
|
||||
7
dulizhan/test_case/run_all.bat
Normal file
7
dulizhan/test_case/run_all.bat
Normal file
@@ -0,0 +1,7 @@
|
||||
@echo off
|
||||
chcp 65001 >nul
|
||||
echo ========================================
|
||||
echo 运行所有测试用例
|
||||
echo ========================================
|
||||
python run_tests.py --all --report
|
||||
pause
|
||||
7
dulizhan/test_case/run_purchase.bat
Normal file
7
dulizhan/test_case/run_purchase.bat
Normal file
@@ -0,0 +1,7 @@
|
||||
@echo off
|
||||
chcp 65001 >nul
|
||||
echo ========================================
|
||||
echo 运行采购相关测试用例
|
||||
echo ========================================
|
||||
python run_tests.py --dir "接口/SZPurchase" --report
|
||||
pause
|
||||
250
dulizhan/test_case/run_tests.py
Normal file
250
dulizhan/test_case/run_tests.py
Normal file
@@ -0,0 +1,250 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
统一测试执行文件
|
||||
支持批量运行所有用例、按标签运行、按目录运行等
|
||||
"""
|
||||
import argparse
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
# 添加项目根目录到 Python 路径
|
||||
current_file_path = os.path.abspath(__file__)
|
||||
project_root = os.path.abspath(os.path.join(os.path.dirname(current_file_path), '../../'))
|
||||
if project_root not in sys.path:
|
||||
sys.path.insert(0, project_root)
|
||||
|
||||
print(project_root)
|
||||
|
||||
# 测试目录 - 已经包含了接口目录
|
||||
TEST_CASE_DIR = 'dulizhan/test_case/TestCase'
|
||||
case_dir = os.path.join(project_root, TEST_CASE_DIR)
|
||||
|
||||
# 报告目录
|
||||
REPORT_DIR = os.path.join(os.path.dirname(current_file_path), 'reports')
|
||||
ALLURE_RESULTS_DIR = os.path.join(REPORT_DIR, 'allure-results')
|
||||
ALLURE_REPORT_DIR = os.path.join(REPORT_DIR, 'allure-report')
|
||||
ALLURE_PATH = os.path.join(project_root, 'allure', 'allure-2.28.0', 'bin', 'allure.bat')
|
||||
|
||||
print(ALLURE_REPORT_DIR)
|
||||
|
||||
|
||||
def ensure_dirs():
|
||||
"""确保报告目录存在"""
|
||||
os.makedirs(ALLURE_RESULTS_DIR, exist_ok=True)
|
||||
os.makedirs(ALLURE_REPORT_DIR, exist_ok=True)
|
||||
|
||||
|
||||
def run_pytest(args_list):
|
||||
"""执行pytest命令"""
|
||||
# 设置PYTHONPATH环境变量
|
||||
env = os.environ.copy()
|
||||
env['PYTHONPATH'] = project_root + (os.pathsep + env['PYTHONPATH'] if 'PYTHONPATH' in env else '')
|
||||
|
||||
# 检测Jenkins环境
|
||||
is_jenkins = 'JENKINS_URL' in env or 'BUILD_NUMBER' in env
|
||||
if is_jenkins and 'WORKSPACE' in env:
|
||||
# Jenkins环境下使用绝对路径
|
||||
global ALLURE_RESULTS_DIR, ALLURE_REPORT_DIR
|
||||
ALLURE_RESULTS_DIR = os.path.join(env['WORKSPACE'], 'zhyy', 'test_case', 'reports', 'allure-results')
|
||||
ALLURE_REPORT_DIR = os.path.join(env['WORKSPACE'], 'zhyy', 'test_case', 'reports', 'allure-report')
|
||||
ensure_dirs()
|
||||
|
||||
cmd = ['python', '-m', 'pytest'] + args_list
|
||||
print("执行命令: {}".format(' '.join(cmd)))
|
||||
|
||||
# 执行命令
|
||||
result = subprocess.run(' '.join(cmd), shell=True, cwd=project_root, env=env)
|
||||
return result.returncode
|
||||
|
||||
|
||||
def find_test_files(directory):
|
||||
"""递归查找所有测试文件"""
|
||||
test_files = []
|
||||
for root, dirs, files in os.walk(directory):
|
||||
for file in files:
|
||||
if file.endswith('.py') and not file.startswith('__'):
|
||||
test_files.append(os.path.join(root, file))
|
||||
return test_files
|
||||
|
||||
|
||||
def run_tests(target, test_type='all', **kwargs):
|
||||
"""运行测试"""
|
||||
base_args = ['-v', '--tb=short', '--alluredir={}'.format(ALLURE_RESULTS_DIR)]
|
||||
|
||||
if test_type == 'all':
|
||||
print("运行所有测试用例...")
|
||||
test_files = find_test_files(case_dir)
|
||||
if not test_files:
|
||||
print("错误: 未找到测试文件")
|
||||
return 1
|
||||
args = test_files + base_args
|
||||
elif test_type == 'feature':
|
||||
print("按feature标签运行: {}".format(target))
|
||||
test_files = find_test_files(case_dir)
|
||||
if not test_files:
|
||||
print("错误: 未找到测试文件")
|
||||
return 1
|
||||
args = test_files + ['--allure-features={}'.format(target)] + base_args
|
||||
elif test_type == 'story':
|
||||
print("按story标签运行: {}".format(target))
|
||||
test_files = find_test_files(case_dir)
|
||||
if not test_files:
|
||||
print("错误: 未找到测试文件")
|
||||
return 1
|
||||
args = test_files + ['--allure-stories={}'.format(target)] + base_args
|
||||
elif test_type == 'marker':
|
||||
print("按pytest标记运行: {}".format(target))
|
||||
test_files = find_test_files(case_dir)
|
||||
if not test_files:
|
||||
print("错误: 未找到测试文件")
|
||||
return 1
|
||||
args = test_files + ['-m={}'.format(target)] + base_args
|
||||
elif test_type == 'dir':
|
||||
full_path = os.path.join(case_dir, target.replace('/', os.sep).replace('\\', os.sep))
|
||||
if not os.path.exists(full_path):
|
||||
print("错误: 目录不存在: {}".format(full_path))
|
||||
return 1
|
||||
print("按目录运行: {}".format(target))
|
||||
test_files = find_test_files(full_path)
|
||||
if not test_files:
|
||||
print("错误: 未找到测试文件")
|
||||
return 1
|
||||
args = test_files + base_args
|
||||
elif test_type == 'file':
|
||||
full_path = os.path.join(case_dir, target.replace('/', os.sep).replace('\\', os.sep))
|
||||
if not os.path.exists(full_path):
|
||||
print("错误: 文件不存在: {}".format(full_path))
|
||||
return 1
|
||||
print("按文件运行: {}".format(target))
|
||||
args = [full_path] + base_args
|
||||
elif test_type == 'keyword':
|
||||
print("按关键字运行: {}".format(target))
|
||||
test_files = find_test_files(case_dir)
|
||||
if not test_files:
|
||||
print("错误: 未找到测试文件")
|
||||
return 1
|
||||
args = test_files + ['-k={}'.format(target)] + base_args
|
||||
else:
|
||||
print("错误: 未知的测试类型: {}".format(test_type))
|
||||
return 1
|
||||
|
||||
return run_pytest(args)
|
||||
|
||||
|
||||
def generate_allure_report():
|
||||
"""生成allure报告"""
|
||||
print("生成Allure报告...")
|
||||
|
||||
if not os.path.exists(ALLURE_PATH):
|
||||
print("警告: 未找到allure命令,请检查路径: {}".format(ALLURE_PATH))
|
||||
print("尝试使用系统环境变量中的allure...")
|
||||
cmd = 'allure generate {} -o {} --clean'.format(ALLURE_RESULTS_DIR, ALLURE_REPORT_DIR)
|
||||
else:
|
||||
cmd = '"{}" generate {} -o {} --clean'.format(ALLURE_PATH, ALLURE_RESULTS_DIR, ALLURE_REPORT_DIR)
|
||||
|
||||
print("执行命令: {}".format(cmd))
|
||||
|
||||
try:
|
||||
subprocess.run(cmd, shell=True, check=True)
|
||||
print("Allure报告生成成功: {}".format(ALLURE_REPORT_DIR))
|
||||
print("打开报告命令: allure open {}".format(ALLURE_REPORT_DIR))
|
||||
return 0
|
||||
except subprocess.CalledProcessError as e:
|
||||
print("生成Allure报告失败: {}".format(e))
|
||||
return 1
|
||||
except FileNotFoundError:
|
||||
print("警告: 未找到allure命令,请先安装allure")
|
||||
return 1
|
||||
|
||||
|
||||
def open_allure_report():
|
||||
"""打开allure报告"""
|
||||
print("打开Allure报告...")
|
||||
|
||||
if not os.path.exists(ALLURE_PATH):
|
||||
cmd = 'allure open {}'.format(ALLURE_REPORT_DIR)
|
||||
else:
|
||||
cmd = '"{}" open {}'.format(ALLURE_PATH, ALLURE_REPORT_DIR)
|
||||
|
||||
try:
|
||||
subprocess.Popen(cmd, shell=True)
|
||||
print("Allure报告已在浏览器中打开")
|
||||
except FileNotFoundError:
|
||||
print("警告: 未找到allure命令,请先安装allure")
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description='统一测试执行工具',
|
||||
epilog="""
|
||||
使用示例:
|
||||
# 运行所有测试
|
||||
python run_tests.py
|
||||
|
||||
# 按feature标签运行
|
||||
python run_tests.py --feature "深圳采购工作台采购订单页面"
|
||||
|
||||
# 按目录运行(相对于TestCase目录)
|
||||
python run_tests.py --dir "接口/JoyHub"
|
||||
|
||||
# 生成并打开报告
|
||||
python run_tests.py --report --open
|
||||
"""
|
||||
)
|
||||
|
||||
# 运行选项
|
||||
run_group = parser.add_mutually_exclusive_group(required=False)
|
||||
run_group.add_argument('--feature', type=str, help='按allure feature标签运行')
|
||||
run_group.add_argument('--story', type=str, help='按allure story标签运行')
|
||||
run_group.add_argument('--dir', type=str, help='按目录运行(相对于TestCase目录)')
|
||||
run_group.add_argument('--file', type=str, help='按文件运行(相对于TestCase目录)')
|
||||
run_group.add_argument('--keyword', type=str, help='按关键字运行')
|
||||
run_group.add_argument('--marker', type=str, help='按pytest标记运行')
|
||||
|
||||
# 报告选项
|
||||
parser.add_argument('--report', action='store_true', help='生成Allure报告')
|
||||
parser.add_argument('--open', action='store_true', help='打开Allure报告')
|
||||
parser.add_argument('--no-report', action='store_true', help='不生成Allure报告')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# 确保目录存在
|
||||
ensure_dirs()
|
||||
|
||||
# 执行测试
|
||||
exit_code = 0
|
||||
if args.feature:
|
||||
exit_code = run_tests(args.feature, 'feature')
|
||||
elif args.story:
|
||||
exit_code = run_tests(args.story, 'story')
|
||||
elif args.dir:
|
||||
exit_code = run_tests(args.dir, 'dir')
|
||||
elif args.file:
|
||||
exit_code = run_tests(args.file, 'file')
|
||||
elif args.keyword:
|
||||
exit_code = run_tests(args.keyword, 'keyword')
|
||||
elif args.marker:
|
||||
exit_code = run_tests(args.marker, 'marker')
|
||||
else:
|
||||
# 默认运行所有测试
|
||||
exit_code = run_tests(None, 'all')
|
||||
|
||||
# 生成报告
|
||||
if args.report or (not args.no_report and exit_code == 0):
|
||||
generate_allure_report()
|
||||
if args.open:
|
||||
open_allure_report()
|
||||
|
||||
print("=" * 80)
|
||||
if exit_code == 0:
|
||||
print("测试执行完成")
|
||||
else:
|
||||
print("测试执行失败,退出码: {}".format(exit_code))
|
||||
print("=" * 80)
|
||||
|
||||
sys.exit(exit_code)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user