Files
xianyan/Script/api_test_full.py
Developer a4b7105999 feat: 新增API响应模型、缓存配置和状态管理
refactor: 优化网络请求和错误处理

fix: 修复颜色引用和UI细节问题

docs: 更新API文档和设计规范

chore: 清理无用文件和脚本

perf: 优化图片导出和压缩逻辑

build: 更新依赖和构建配置

style: 调整代码格式和注释

test: 添加接口验证脚本

ci: 更新CI配置和脚本
2026-04-29 01:39:48 +08:00

313 lines
10 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
============================================================
闲言APP — 全量API接口测试脚本
创建时间: 2026-04-28
更新时间: 2026-04-28
作用: 模拟用户注册登录测试所有API接口
上次更新: 增加收藏、笔记、签到、统计、纠错接口测试
============================================================
"""
import requests
import json
import time
import random
import string
BASE_URL = "https://tools.wktyl.com"
TIMEOUT = 15
TEST_ACCOUNT = f"testbot_{''.join(random.choices(string.digits, k=4))}"
TEST_PASSWORD = "Test123456"
TEST_EMAIL = f"{TEST_ACCOUNT}@test.local"
token = None
user_id = None
def log_test(name, success, detail=""):
status = "" if success else ""
print(f" {status} {name}" + (f"{detail}" if detail else ""))
def api_get(path, params=None, use_token=True):
headers = {}
if use_token and token:
headers["token"] = token
try:
r = requests.get(f"{BASE_URL}{path}", params=params, headers=headers, timeout=TIMEOUT)
return r.json()
except Exception as e:
return {"code": -999, "msg": str(e)}
def api_post(path, data=None, use_token=True):
headers = {"Content-Type": "application/x-www-form-urlencoded"}
if use_token and token:
headers["token"] = token
try:
r = requests.post(f"{BASE_URL}{path}", data=data, headers=headers, timeout=TIMEOUT)
return r.json()
except Exception as e:
return {"code": -999, "msg": str(e)}
def test_auth():
global token, user_id
print("\n🔐 认证模块测试")
print("-" * 40)
data = api_post("/api/user/register", data={
"username": TEST_ACCOUNT,
"password": TEST_PASSWORD,
"email": TEST_EMAIL,
}, use_token=False)
reg_ok = data.get("code") in [1, 0]
log_test("用户注册", reg_ok, f"code={data.get('code')}, msg={data.get('msg', '')[:30]}")
data = api_post("/api/user/login", data={
"account": TEST_ACCOUNT,
"password": TEST_PASSWORD,
}, use_token=False)
login_ok = data.get("code") == 1
log_test("用户登录", login_ok, f"code={data.get('code')}")
if login_ok:
userinfo = data.get("data", {}).get("userinfo", {})
token = userinfo.get("token", "")
user_id = userinfo.get("id", 0)
print(f" 📌 token={token[:20]}... user_id={user_id}")
data = api_get("/api/user/index")
log_test("获取用户信息", data.get("code") == 1, f"nickname={data.get('data', {}).get('nickname', 'N/A')}")
data = api_post("/api/user/tokenLogin", use_token=True)
log_test("Token自动登录", data.get("code") == 1)
data = api_get("/api/user/index", use_token=False)
log_test("未登录访问用户信息", data.get("code") in [0, -1, 401])
def test_signin():
print("\n📅 签到模块测试")
print("-" * 40)
data = api_post("/api/user/signin")
log_test("每日签到", data.get("code") in [1, 0], f"msg={data.get('msg', '')[:30]}")
data = api_post("/api/user/signin")
log_test("重复签到", data.get("code") == 0, f"msg={data.get('msg', '')[:30]}")
def test_favorite():
print("\n💕 收藏模块测试")
print("-" * 40)
data = api_post("/api/user/favorite", data={
"action": "add",
"target_type": "article",
"target_id": 1,
})
log_test("添加收藏", data.get("code") == 1, f"msg={data.get('msg', '')[:30]}")
data = api_post("/api/user/favorite", data={
"action": "check",
"target_type": "article",
"target_id": 1,
})
is_fav = (data.get("data") or {}).get("is_favorited", False)
log_test("检查收藏状态", data.get("code") == 1, f"is_favorited={is_fav}")
data = api_get("/api/user/favorite", params={
"action": "list",
"target_type": "article",
"page": 1,
"limit": 10,
})
fav_data = data.get("data") or {}
total = fav_data.get("total", "N/A")
log_test("收藏列表", data.get("code") == 1, f"total={total}")
data = api_post("/api/user/favorite", data={
"action": "remove",
"target_type": "article",
"target_id": 1,
})
log_test("取消收藏", data.get("code") == 1, f"msg={data.get('msg', '')[:30]}")
data = api_post("/api/user/favorite", data={
"action": "check",
"target_type": "article",
"target_id": 1,
})
is_fav2 = (data.get("data") or {}).get("is_favorited", True)
log_test("取消后检查", not is_fav2, f"is_favorited={is_fav2}")
def test_note():
print("\n📝 笔记模块测试")
print("-" * 40)
data = api_post("/api/user/note", data={
"action": "add",
"title": f"测试笔记_{int(time.time())}",
"content": "这是一条自动测试创建的笔记内容,用于验证笔记接口功能。",
"category": "测试",
})
log_test("添加笔记", data.get("code") == 1, f"msg={data.get('msg', '')[:30]}")
data = api_get("/api/user/note", params={
"action": "list",
"page": 1,
"limit": 10,
})
note_data = data.get("data") or {}
notes = note_data.get("list") or []
total = note_data.get("total", "N/A")
note_id = notes[0].get("id", 0) if notes else 0
log_test("笔记列表", data.get("code") == 1, f"total={total}, first_id={note_id}")
if note_id:
data = api_post("/api/user/note", data={
"action": "edit",
"id": note_id,
"title": f"编辑后的笔记_{int(time.time())}",
"content": "这是编辑后的笔记内容。",
})
log_test("编辑笔记", data.get("code") == 1, f"msg={data.get('msg', '')[:30]}")
data = api_post("/api/user/note", data={
"action": "delete",
"id": note_id,
})
log_test("删除笔记", data.get("code") == 1, f"msg={data.get('msg', '')[:30]}")
else:
log_test("编辑笔记", False, "无笔记可编辑")
log_test("删除笔记", False, "无笔记可删除")
def test_statistics():
print("\n📊 统计模块测试")
print("-" * 40)
data = api_get("/api/statistics/overview", use_token=False)
log_test("站点总览", data.get("code") == 1, f"users={data.get('data', {}).get('total_users', 'N/A')}")
data = api_get("/api/statistics/users", use_token=False)
log_test("用户统计", data.get("code") == 1, f"total={data.get('data', {}).get('total', 'N/A')}")
data = api_get("/api/statistics/signins", use_token=False)
log_test("签到统计", data.get("code") == 1, f"total={data.get('data', {}).get('total', 'N/A')}")
data = api_get("/api/statistics/coins", use_token=False)
log_test("金币统计", data.get("code") == 1, f"total_score={data.get('data', {}).get('total_score', 'N/A')}")
data = api_get("/api/statistics/notes", use_token=False)
log_test("笔记统计", data.get("code") == 1, f"total={data.get('data', {}).get('total', 'N/A')}")
def test_search():
print("\n🔍 搜索模块测试")
print("-" * 40)
data = api_get("/api/search/index", params={
"keyword": "",
"type": "all",
"mode": "fuzzy",
}, use_token=False)
log_test("综合搜索", data.get("code") == 1, f"keyword={data.get('data', {}).get('keyword', 'N/A')}")
data = api_get("/api/search/index", params={
"keyword": "",
"type": "hanzi",
"mode": "exact",
}, use_token=False)
hanzi_data = data.get("data") or {}
hanzi_total = (hanzi_data.get("results") or {}).get("hanzi", {}).get("total", "N/A")
log_test("汉字搜索", data.get("code") == 1, f"hanzi_total={hanzi_total}")
data = api_get("/api/search/index", params={
"keyword": "一心",
"type": "cy",
"mode": "fuzzy",
}, use_token=False)
log_test("成语搜索", data.get("code") == 1)
data = api_get("/api/search/index", params={
"keyword": "静夜思",
"type": "poetry",
"mode": "exact",
}, use_token=False)
log_test("诗词搜索", data.get("code") == 1)
data = api_get("/api/search/index", params={
"keyword": "",
"type": "all",
}, use_token=False)
log_test("空关键词搜索", data.get("code") in [0, 1], f"msg={data.get('msg', '')[:30]}")
def test_correction():
print("\n🔍 纠错模块测试")
print("-" * 40)
data = api_post("/api/webapi/correction_submit", data={
"content": f"自动测试纠错内容_{int(time.time())}:此条为接口测试数据,可忽略。",
"mail": TEST_EMAIL,
"source_url": "https://tools.wktyl.com/hanzi/1",
}, use_token=False)
log_test("提交纠错", data.get("code") == 1, f"msg={data.get('msg', '')[:30]}")
def test_webapi():
print("\n🌐 WebAPI模块测试")
print("-" * 40)
data = api_get("/api/webapi/hitokoto", use_token=False)
log_test("一言接口", data.get("code") == 1 or "hitokoto" in str(data)[:100])
data = api_get("/api/webapi/moyu", use_token=False)
log_test("摸鱼接口", data.get("code") == 1 or "moyu" in str(data)[:100] or data.get("data") is not None)
def test_profile():
print("\n👤 个人信息模块测试")
print("-" * 40)
data = api_post("/api/user/profile", data={
"nickname": f"测试昵称_{int(time.time())}",
"bio": "这是自动测试修改的个人简介",
})
log_test("修改个人信息", data.get("code") == 1, f"msg={data.get('msg', '')[:30]}")
data = api_get("/api/user/index")
nickname = data.get("data", {}).get("nickname", "N/A")
log_test("验证修改结果", data.get("code") == 1, f"nickname={nickname}")
if __name__ == "__main__":
print("=" * 50)
print("🚀 闲言APP — 全量API接口测试")
print(f" 时间: {time.strftime('%Y-%m-%d %H:%M:%S')}")
print(f" 测试账号: {TEST_ACCOUNT}")
print("=" * 50)
try:
test_auth()
if token:
test_signin()
test_favorite()
test_note()
test_profile()
test_statistics()
test_search()
test_correction()
test_webapi()
except Exception as e:
print(f"\n💥 测试中断: {e}")
import traceback
traceback.print_exc()
print("\n" + "=" * 50)
print("🏁 测试完成!")
print("=" * 50)