性能优化
This commit is contained in:
121
scripts/test/web/test_upload.py
Normal file
121
scripts/test/web/test_upload.py
Normal file
@@ -0,0 +1,121 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
文件上传测试。POST /api/upload 上传图片,DELETE /api/upload 删除。
|
||||
验证:本地存储(OSS 未配置时)、响应格式、删除流程。
|
||||
"""
|
||||
import io
|
||||
import pytest
|
||||
import requests
|
||||
|
||||
|
||||
# 最小有效 JPEG(1x1 像素,约 100 字节)
|
||||
_MIN_JPEG = (
|
||||
b"\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00\x01\x00\x00"
|
||||
b"\xff\xdb\x00C\x00\x08\x06\x06\x07\x06\x05\x08\x07\x07\x07\t\t\x08\n\x0c\x14\r\x0c\x0b\x0b\x0c\x19\x12\x13\x0f\x14\x1d\x1a\x1f\x1e\x1d\x1a\x1c\x1c"
|
||||
b" $.' \",#\x1c\x1c(7),01444\x1f'9=82<.342\xff\xc0\x00\x0b\x08\x00\x01\x00\x01\x01\x01\x11\x00\xff\xc4\x00\x1f\x00\x00\x01\x05\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\xff\xda\x00\x08\x01\x01\x00\x00\x00?\x00\xfe\x02\x1f\xff\xd9"
|
||||
)
|
||||
|
||||
|
||||
def test_upload_post_success(base_url):
|
||||
"""POST /api/upload 上传图片成功,返回 url、fileName、size、type"""
|
||||
files = {"file": ("test_upload.jpg", io.BytesIO(_MIN_JPEG), "image/jpeg")}
|
||||
data = {"folder": "test"}
|
||||
r = requests.post(
|
||||
f"{base_url}/api/upload",
|
||||
files=files,
|
||||
data=data,
|
||||
timeout=10,
|
||||
)
|
||||
assert r.status_code == 200, f"期望 200,实际 {r.status_code}: {r.text}"
|
||||
body = r.json()
|
||||
assert body.get("success") is True, body
|
||||
assert "url" in body, body
|
||||
assert body["url"], "url 不应为空"
|
||||
data_out = body.get("data", {})
|
||||
assert "url" in data_out
|
||||
assert "fileName" in data_out
|
||||
assert "size" in data_out
|
||||
assert data_out["size"] == len(_MIN_JPEG)
|
||||
assert "type" in data_out
|
||||
assert "image" in str(data_out.get("type", "")).lower()
|
||||
|
||||
|
||||
def test_upload_post_with_admin_token(base_url, admin_token):
|
||||
"""POST /api/upload 带管理端 token 也可上传(接口不强制鉴权)"""
|
||||
if not admin_token:
|
||||
pytest.skip("admin 登录失败")
|
||||
files = {"file": ("avatar.jpg", io.BytesIO(_MIN_JPEG), "image/jpeg")}
|
||||
# multipart 上传不设 Content-Type,让 requests 自动带 boundary
|
||||
headers = {"Authorization": f"Bearer {admin_token}"}
|
||||
r = requests.post(
|
||||
f"{base_url}/api/upload",
|
||||
files=files,
|
||||
headers=headers,
|
||||
timeout=10,
|
||||
)
|
||||
assert r.status_code == 200
|
||||
body = r.json()
|
||||
assert body.get("success") is True
|
||||
assert body.get("url")
|
||||
|
||||
|
||||
def test_upload_post_no_file(base_url):
|
||||
"""POST /api/upload 无 file 返回 400"""
|
||||
r = requests.post(
|
||||
f"{base_url}/api/upload",
|
||||
data={"folder": "test"},
|
||||
timeout=10,
|
||||
)
|
||||
assert r.status_code == 400
|
||||
body = r.json()
|
||||
assert body.get("success") is False
|
||||
assert "error" in body or "请选择" in body.get("error", "")
|
||||
|
||||
|
||||
def test_upload_post_invalid_type(base_url):
|
||||
"""POST /api/upload 非图片格式返回 400"""
|
||||
files = {"file": ("test.txt", io.BytesIO(b"hello"), "text/plain")}
|
||||
r = requests.post(
|
||||
f"{base_url}/api/upload",
|
||||
files=files,
|
||||
timeout=10,
|
||||
)
|
||||
assert r.status_code == 400
|
||||
body = r.json()
|
||||
assert body.get("success") is False
|
||||
|
||||
|
||||
def test_upload_delete_local(base_url):
|
||||
"""DELETE /api/upload 删除本地文件:先上传再删除"""
|
||||
# 1. 上传
|
||||
files = {"file": ("del_test.jpg", io.BytesIO(_MIN_JPEG), "image/jpeg")}
|
||||
r1 = requests.post(
|
||||
f"{base_url}/api/upload",
|
||||
files=files,
|
||||
data={"folder": "test"},
|
||||
timeout=10,
|
||||
)
|
||||
assert r1.status_code == 200
|
||||
url = r1.json().get("url")
|
||||
assert url, "上传应返回 url"
|
||||
# path 支持 /uploads/xxx 或含 /uploads/ 的完整 URL
|
||||
path = url
|
||||
|
||||
# 2. 删除
|
||||
r2 = requests.delete(
|
||||
f"{base_url}/api/upload",
|
||||
params={"path": path},
|
||||
timeout=10,
|
||||
)
|
||||
assert r2.status_code == 200
|
||||
body = r2.json()
|
||||
assert body.get("success") is True
|
||||
assert "删除成功" in body.get("message", "")
|
||||
|
||||
|
||||
def test_upload_delete_no_path(base_url):
|
||||
"""DELETE /api/upload 无 path 返回 400"""
|
||||
r = requests.delete(f"{base_url}/api/upload", timeout=10)
|
||||
assert r.status_code == 400
|
||||
body = r.json()
|
||||
assert body.get("success") is False
|
||||
155
scripts/test/功能测试流程.md
Normal file
155
scripts/test/功能测试流程.md
Normal file
@@ -0,0 +1,155 @@
|
||||
# Soul 创业派对 - 功能测试流程
|
||||
|
||||
> 测试工程师产出。按流程执行,成功项打 ☑️,失败项列出问题,最后输出报告。
|
||||
|
||||
---
|
||||
|
||||
## 一、测试流程总览
|
||||
|
||||
```
|
||||
环境准备 → 自动化用例执行 → 手工功能验证 → 问题汇总 → 输出报告
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 二、环境准备
|
||||
|
||||
| 步骤 | 内容 | 结果 |
|
||||
|------|------|------|
|
||||
| 1 | soul-api 已启动(local 时)或测试服已部署 | ☐ / 问题:_____ |
|
||||
| 2 | 配置 `.env.test`(SOUL_TEST_ENV 或 SOUL_API_BASE) | ☐ / 问题:_____ |
|
||||
| 3 | 管理端可访问,默认账号 admin/admin123 可登录 | ☐ / 问题:_____ |
|
||||
| 4 | 小程序可访问(真机或开发者工具) | ☐ / 问题:_____ |
|
||||
|
||||
**环境信息记录**:
|
||||
- 执行日期:__________
|
||||
- 测试环境:local / souldev / soulapi
|
||||
- API 地址:__________
|
||||
|
||||
---
|
||||
|
||||
## 三、自动化用例执行
|
||||
|
||||
在 `scripts/test` 下执行:
|
||||
|
||||
```bash
|
||||
cd scripts/test
|
||||
$env:SOUL_TEST_ENV="local" # 或 souldev
|
||||
pytest -v
|
||||
```
|
||||
|
||||
### 3.1 小程序接口(miniapp)
|
||||
|
||||
| 用例 | 验证点 | 结果 | 问题(若失败) |
|
||||
|------|--------|------|----------------|
|
||||
| test_config_public | GET /api/miniprogram/config 返回 prices、features、mpConfig | ☐ | |
|
||||
| test_dev_login_as | POST /api/miniprogram/dev/login-as 按 userId 登录 | ☐ | |
|
||||
|
||||
### 3.2 管理端接口(web)
|
||||
|
||||
| 用例 | 验证点 | 结果 | 问题(若失败) |
|
||||
|------|--------|------|----------------|
|
||||
| test_admin_login | POST /api/admin 登录成功 | ☐ | |
|
||||
| test_admin_check_with_token | GET /api/admin 带 token 鉴权通过 | ☐ | |
|
||||
| test_admin_check_without_token | GET /api/admin 无 token 返回 401 | ☐ | |
|
||||
|
||||
### 3.3 流程测试(process)
|
||||
|
||||
| 用例 | 验证点 | 结果 | 问题(若失败) |
|
||||
|------|--------|------|----------------|
|
||||
| test_health | GET /health 返回 200 | ☐ | |
|
||||
| test_person_ensure_* | @某人 创建 Person + 存客宝计划 | ☐ | |
|
||||
| test_article_mention_* | 文章保存自动创建 Person | ☐ | |
|
||||
| test_backfill_persons_ckb_api_key | 从存客宝补齐 ckb_api_key | ☐ | |
|
||||
|
||||
---
|
||||
|
||||
## 四、手工功能验证
|
||||
|
||||
### 4.1 小程序端
|
||||
|
||||
| 场景 | 验证点 | 结果 | 问题(若失败) |
|
||||
|------|--------|------|----------------|
|
||||
| 登录 | 微信登录、手机号授权、token 持久化 | ☐ | |
|
||||
| 首页 | 书籍列表、搜索栏(searchEnabled 控制) | ☐ | |
|
||||
| 目录 | 章节列表、购买状态展示 | ☐ | |
|
||||
| 阅读 | 阅读页、购买章节/全书、支付流程 | ☐ | |
|
||||
| 我的 | 找伙伴、推广、搜索入口(featureConfig 控制) | ☐ | |
|
||||
| VIP | 开通、资料填写、头像上传、保存 | ☐ | |
|
||||
| 推荐 | 扫码/分享带 ref、绑定、分润展示 | ☐ | |
|
||||
|
||||
### 4.2 管理端
|
||||
|
||||
| 场景 | 验证点 | 结果 | 问题(若失败) |
|
||||
|------|--------|------|----------------|
|
||||
| 登录 | 账号密码登录、token 持久化 | ☐ | |
|
||||
| 仪表盘 | 数据统计展示 | ☐ | |
|
||||
| 用户管理 | 列表、搜索、分页、详情、行为轨迹 Tab | ☐ | |
|
||||
| 订单管理 | 列表、状态、筛选 | ☐ | |
|
||||
| 内容管理 | 书籍/章节 CRUD | ☐ | |
|
||||
| 提现 | 申请列表、审核、状态流转 | ☐ | |
|
||||
| 提现测试接口 | GIN_MODE=release 时返回 404 | ☐ | |
|
||||
|
||||
### 4.3 接口与数据流
|
||||
|
||||
| 场景 | 验证点 | 结果 | 问题(若失败) |
|
||||
|------|--------|------|----------------|
|
||||
| 路径隔离 | 小程序只调 /api/miniprogram/* | ☐ | |
|
||||
| 鉴权 | 需登录接口带 token,401 正确跳转 | ☐ | |
|
||||
| 支付回调 | 下单→支付→回调→分润 | ☐ | |
|
||||
|
||||
---
|
||||
|
||||
## 五、问题汇总(失败项)
|
||||
|
||||
将上述所有**未打 ☑️** 的项在此列出:
|
||||
|
||||
| 序号 | 模块 | 场景/用例 | 问题描述 | 严重程度 |
|
||||
|------|------|-----------|----------|----------|
|
||||
| 1 | | | | 高/中/低 |
|
||||
| 2 | | | | |
|
||||
| … | | | | |
|
||||
|
||||
---
|
||||
|
||||
## 六、测试报告(最终输出)
|
||||
|
||||
### 6.1 执行摘要
|
||||
|
||||
| 项目 | 内容 |
|
||||
|------|------|
|
||||
| 执行日期 | |
|
||||
| 测试环境 | |
|
||||
| 执行人 | |
|
||||
|
||||
### 6.2 结果统计
|
||||
|
||||
| 类型 | 总数 | 通过 ☑️ | 失败 | 通过率 |
|
||||
|------|------|---------|------|--------|
|
||||
| 自动化用例 | 12 | | | |
|
||||
| 手工-小程序 | 7 | | | |
|
||||
| 手工-管理端 | 7 | | | |
|
||||
| 手工-接口 | 3 | | | |
|
||||
| **合计** | **29** | | | |
|
||||
|
||||
### 6.3 结论
|
||||
|
||||
- [ ] **通过**:所有关键项 ☑️,无高/中严重问题
|
||||
- [ ] **有条件通过**:存在低严重问题,可上线但需跟进
|
||||
- [ ] **不通过**:存在高/中严重问题,需修复后复测
|
||||
|
||||
### 6.4 问题清单(若有)
|
||||
|
||||
| 序号 | 问题 | 严重程度 | 建议 |
|
||||
|------|------|----------|------|
|
||||
| 1 | | | |
|
||||
| 2 | | | |
|
||||
|
||||
---
|
||||
|
||||
## 七、使用说明
|
||||
|
||||
1. **执行前**:复制本文档或新建一份,填写环境信息。
|
||||
2. **执行中**:逐项验证,成功打 ☑️,失败在「问题」列填写。
|
||||
3. **执行后**:汇总失败项到「五、问题汇总」,填写「六、测试报告」。
|
||||
4. **归档**:报告保存为 `scripts/test/测试报告-YYYY-MM-DD.md`,便于追溯。
|
||||
102
scripts/test/测试报告-环境与用例清单.md
Normal file
102
scripts/test/测试报告-环境与用例清单.md
Normal file
@@ -0,0 +1,102 @@
|
||||
# Soul 创业派对 - 测试报告(环境与用例清单)
|
||||
|
||||
> 测试人员产出。环境就绪后执行 `pytest -v` 并填写结果。
|
||||
|
||||
---
|
||||
|
||||
## 一、测试环境
|
||||
|
||||
| 环境 | API 地址 | 说明 |
|
||||
|------|----------|------|
|
||||
| **local** | http://localhost:8080 | 本地开发,需先启动 soul-api |
|
||||
| **souldev** | https://souldev.quwanzhi.com | 测试服,需已部署 |
|
||||
| **soulapi** | https://soulapi.quwanzhi.com | 正式服,慎用 |
|
||||
|
||||
**配置方式**:
|
||||
- 复制 `scripts/test/.env.test.example` 为 `.env.test`
|
||||
- 设置 `SOUL_TEST_ENV=local|souldev|soulapi` 或 `SOUL_API_BASE=<地址>`
|
||||
|
||||
**运行命令**:
|
||||
```bash
|
||||
cd scripts/test
|
||||
# Windows PowerShell
|
||||
$env:SOUL_TEST_ENV="local" # 或 souldev
|
||||
pytest -v
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 二、用例清单(共 18 个)
|
||||
|
||||
### 2.1 小程序接口(miniapp/)
|
||||
|
||||
| 用例 | 验证点 | 前置条件 |
|
||||
|------|--------|----------|
|
||||
| **test_config_public** | GET /api/miniprogram/config 返回 200,含 prices、features、mpConfig | 无 |
|
||||
| **test_dev_login_as** | POST /api/miniprogram/dev/login-as 按 userId 登录成功 | SOUL_MINIPROGRAM_DEV_USER_ID 已配置;APP_ENV=development |
|
||||
|
||||
### 2.2 管理端接口(web/)
|
||||
|
||||
| 用例 | 验证点 | 前置条件 |
|
||||
|------|--------|----------|
|
||||
| **test_admin_login** | POST /api/admin 登录成功,返回 token、user | 无 |
|
||||
| **test_admin_check_with_token** | GET /api/admin 带 token 鉴权通过 | admin 登录成功 |
|
||||
| **test_admin_check_without_token** | GET /api/admin 无 token 返回 401 | 无 |
|
||||
| **test_upload_post_success** | POST /api/upload 上传图片成功,返回 url、data | 无 |
|
||||
| **test_upload_post_with_admin_token** | POST /api/upload 带 token 可上传 | admin 登录 |
|
||||
| **test_upload_post_no_file** | POST /api/upload 无 file 返回 400 | 无 |
|
||||
| **test_upload_post_invalid_type** | POST /api/upload 非图片格式返回 400 | 无 |
|
||||
| **test_upload_delete_local** | DELETE /api/upload 删除本地文件(先上传再删) | 无 |
|
||||
| **test_upload_delete_no_path** | DELETE /api/upload 无 path 返回 400 | 无 |
|
||||
|
||||
### 2.3 流程测试(process/)
|
||||
|
||||
| 用例 | 验证点 | 前置条件 |
|
||||
|------|--------|----------|
|
||||
| **test_health** | GET /health 返回 200 | soul-api 已启动 |
|
||||
| **test_person_ensure_creates_ckb_plan_when_not_exists** | @某人 不存在时 POST /api/db/persons 创建 Person + 存客宝计划 | admin 登录;CKB 配置正确 |
|
||||
| **test_person_ensure_returns_existing_when_name_exists** | 相同 name 返回已有 Person,不重复创建 | 同上 |
|
||||
| **test_person_ensure_rejects_empty_name** | 空 name 被拒绝 | 同上 |
|
||||
| **test_article_mention_flow_persons_list_contains_new** | 文章保存后 persons 列表含新人物 | 同上 |
|
||||
| **test_new_article_save_auto_creates_person_and_ckb** | 新文章保存自动创建 Person 与存客宝计划 | 同上 |
|
||||
| **test_backfill_persons_ckb_api_key** | 从存客宝补齐 persons.ckb_api_key | admin 登录;CKB 配置;persons 有 ckb_plan_id |
|
||||
|
||||
---
|
||||
|
||||
## 三、源码质量优化相关回归点(手工验证)
|
||||
|
||||
以下为 2026-03-17 源码质量优化后的建议回归项,自动化用例未覆盖:
|
||||
|
||||
| 场景 | 验证点 |
|
||||
|------|--------|
|
||||
| **支付流程** | read 页购买章节/全书 → 微信支付 → 回调更新购买状态 |
|
||||
| **管理端用户详情** | 用户列表点击详情 → 行为轨迹 Tab 展示(调用 /api/admin/user/track) |
|
||||
| **我的页** | 找伙伴、推广、搜索入口根据 featureConfig 显示/隐藏 |
|
||||
| **首页/目录** | 搜索栏根据 searchEnabled 显示/隐藏 |
|
||||
| **提现测试接口** | GIN_MODE=release 时 GET/POST /api/admin/withdraw-test 返回 404 |
|
||||
|
||||
---
|
||||
|
||||
## 四、测试结果记录
|
||||
|
||||
| 执行日期 | 环境 | 通过 | 失败 | 跳过 | 备注 |
|
||||
|----------|------|------|------|------|------|
|
||||
| 2026-03-17 | local | 16 | 0 | 2 | 含新增文件上传 6 用例;2 跳过(dev_login、backfill 需配置) |
|
||||
| (待填写) | local / souldev | - | - | - | - |
|
||||
|
||||
### 失败用例详情(若有)
|
||||
|
||||
| 用例 | 错误信息 | 处理 |
|
||||
|------|----------|------|
|
||||
| - | - | - |
|
||||
|
||||
---
|
||||
|
||||
## 五、环境就绪检查
|
||||
|
||||
执行测试前请确认:
|
||||
|
||||
- [ ] soul-api 已启动(local 时 `go run cmd/server/main.go` 或 `scripts/本地启动.sh`)
|
||||
- [ ] 测试环境变量已设置(SOUL_TEST_ENV 或 SOUL_API_BASE)
|
||||
- [ ] 管理端账号可登录(默认 admin/admin123)
|
||||
- [ ] 流程测试需 CKB 配置时,soul-api/.env 已配置 CKB_OPEN_API_KEY、CKB_OPEN_ACCOUNT
|
||||
Reference in New Issue
Block a user