619 lines
22 KiB
Python
619 lines
22 KiB
Python
"""
|
||
资产总览功能 - 全面测试脚本
|
||
测试覆盖:账户 CRUD、余额更新、变更历史、分期计划 CRUD、还款操作
|
||
"""
|
||
import requests
|
||
import sys
|
||
from datetime import date
|
||
|
||
BASE_URL = "http://localhost:23994/api"
|
||
|
||
passed = 0
|
||
failed = 0
|
||
errors = []
|
||
|
||
|
||
def test(name, condition, detail=""):
|
||
global passed, failed
|
||
if condition:
|
||
passed += 1
|
||
print(f" [PASS] {name}")
|
||
else:
|
||
failed += 1
|
||
errors.append(name)
|
||
print(f" [FAIL] {name} {detail}")
|
||
|
||
|
||
def section(title):
|
||
print(f"\n{'='*60}")
|
||
print(f" {title}")
|
||
print(f"{'='*60}")
|
||
|
||
|
||
# ============================================================
|
||
section("1. 账户 CRUD 测试")
|
||
# ============================================================
|
||
|
||
# 1.1 创建存款账户 - 微信
|
||
print("\n--- 创建存款账户 ---")
|
||
r = requests.post(f"{BASE_URL}/accounts", json={
|
||
"name": "微信",
|
||
"account_type": "savings",
|
||
"balance": 5800.50,
|
||
"icon": "wechat",
|
||
"color": "#67C23A",
|
||
"is_active": True,
|
||
"description": "日常零钱"
|
||
})
|
||
test("创建微信账户", r.status_code == 201, f"status={r.status_code}")
|
||
wechat = r.json()
|
||
test("微信账户ID存在", wechat.get("id") is not None)
|
||
test("微信余额正确", wechat.get("balance") == 5800.50)
|
||
test("微信类型正确", wechat.get("account_type") == "savings")
|
||
wechat_id = wechat["id"]
|
||
|
||
# 1.2 创建存款账户 - 支付宝
|
||
r = requests.post(f"{BASE_URL}/accounts", json={
|
||
"name": "支付宝",
|
||
"account_type": "savings",
|
||
"balance": 12300.00,
|
||
"icon": "alipay",
|
||
"color": "#1677FF",
|
||
"is_active": True,
|
||
"description": "工资卡"
|
||
})
|
||
test("创建支付宝账户", r.status_code == 201, f"status={r.status_code}")
|
||
alipay = r.json()
|
||
alipay_id = alipay["id"]
|
||
|
||
# 1.3 创建存款账户 - 银行卡
|
||
r = requests.post(f"{BASE_URL}/accounts", json={
|
||
"name": "招商银行",
|
||
"account_type": "savings",
|
||
"balance": 45600.00,
|
||
"icon": "bank",
|
||
"color": "#FF6B6B",
|
||
"is_active": True
|
||
})
|
||
test("创建招商银行账户", r.status_code == 201, f"status={r.status_code}")
|
||
bank = r.json()
|
||
bank_id = bank["id"]
|
||
|
||
# 1.4 创建欠款账户 - 花呗
|
||
r = requests.post(f"{BASE_URL}/accounts", json={
|
||
"name": "花呗",
|
||
"account_type": "debt",
|
||
"balance": 3000.00,
|
||
"icon": "credit-card",
|
||
"color": "#FFB347",
|
||
"is_active": True,
|
||
"description": "分3期,每月12号还"
|
||
})
|
||
test("创建花呗账户", r.status_code == 201, f"status={r.status_code}")
|
||
huabei = r.json()
|
||
huabei_id = huabei["id"]
|
||
|
||
# 1.5 创建欠款账户 - 白条
|
||
r = requests.post(f"{BASE_URL}/accounts", json={
|
||
"name": "白条",
|
||
"account_type": "debt",
|
||
"balance": 2000.00,
|
||
"icon": "ticket",
|
||
"color": "#E6A23C",
|
||
"is_active": True,
|
||
"description": "分6期,每月15号还"
|
||
})
|
||
test("创建白条账户", r.status_code == 201, f"status={r.status_code}")
|
||
baitiao = r.json()
|
||
baitiao_id = baitiao["id"]
|
||
|
||
# 1.6 创建一个已禁用的账户
|
||
r = requests.post(f"{BASE_URL}/accounts", json={
|
||
"name": "已注销信用卡",
|
||
"account_type": "debt",
|
||
"balance": 0,
|
||
"icon": "credit-card",
|
||
"color": "#909399",
|
||
"is_active": False,
|
||
"description": "测试禁用状态"
|
||
})
|
||
test("创建已禁用账户", r.status_code == 201)
|
||
disabled_id = r.json()["id"]
|
||
|
||
|
||
# ============================================================
|
||
section("2. 获取账户列表测试")
|
||
# ============================================================
|
||
|
||
print("\n--- 获取所有账户 ---")
|
||
r = requests.get(f"{BASE_URL}/accounts")
|
||
test("获取账户列表 200", r.status_code == 200, f"status={r.status_code}")
|
||
accounts = r.json()
|
||
test("账户总数正确", len(accounts) >= 5, f"实际数量: {len(accounts)}")
|
||
|
||
savings = [a for a in accounts if a["account_type"] == "savings" and a["is_active"]]
|
||
debt = [a for a in accounts if a["account_type"] == "debt" and a["is_active"]]
|
||
test("活跃存款账户数量", len(savings) == 3, f"实际: {len(savings)}")
|
||
test("活跃欠款账户数量", len(debt) == 2, f"实际: {len(debt)}")
|
||
|
||
# 2.1 获取单个账户
|
||
print("\n--- 获取单个账户 ---")
|
||
r = requests.get(f"{BASE_URL}/accounts/{wechat_id}")
|
||
test("获取单个微信账户 200", r.status_code == 200)
|
||
test("账户名称正确", r.json().get("name") == "微信")
|
||
|
||
# 2.2 获取不存在的账户
|
||
r = requests.get(f"{BASE_URL}/accounts/99999")
|
||
test("获取不存在账户 404", r.status_code == 404, f"status={r.status_code}")
|
||
|
||
|
||
# ============================================================
|
||
section("3. 更新账户测试")
|
||
# ============================================================
|
||
|
||
print("\n--- 更新账户信息 ---")
|
||
r = requests.put(f"{BASE_URL}/accounts/{wechat_id}", json={
|
||
"description": "日常零钱+红包"
|
||
})
|
||
test("更新微信描述 200", r.status_code == 200, f"status={r.status_code}")
|
||
test("描述更新成功", r.json().get("description") == "日常零钱+红包")
|
||
|
||
# 3.1 确认 balance 字段被忽略
|
||
r = requests.put(f"{BASE_URL}/accounts/{wechat_id}", json={
|
||
"balance": 99999 # 应该被忽略
|
||
})
|
||
test("更新忽略 balance", r.json().get("balance") == 5800.50,
|
||
f"余额不应被修改, 实际: {r.json().get('balance')}")
|
||
|
||
|
||
# ============================================================
|
||
section("4. 余额更新与变更历史测试")
|
||
# ============================================================
|
||
|
||
print("\n--- 更新微信余额 ---")
|
||
r = requests.post(f"{BASE_URL}/accounts/{wechat_id}/balance", json={
|
||
"new_balance": 6800.50,
|
||
"note": "收到红包"
|
||
})
|
||
test("更新微信余额 200", r.status_code == 200, f"status={r.status_code}")
|
||
test("微信余额更新成功", r.json().get("balance") == 6800.50)
|
||
|
||
print("\n--- 再次更新微信余额 ---")
|
||
r = requests.post(f"{BASE_URL}/accounts/{wechat_id}/balance", json={
|
||
"new_balance": 5300.50,
|
||
"note": "日常消费"
|
||
})
|
||
test("微信消费后余额", r.json().get("balance") == 5300.50)
|
||
|
||
print("\n--- 更新支付宝余额 ---")
|
||
r = requests.post(f"{BASE_URL}/accounts/{alipay_id}/balance", json={
|
||
"new_balance": 15300.00,
|
||
"note": "工资到账"
|
||
})
|
||
test("支付宝工资到账 200", r.status_code == 200)
|
||
test("支付宝余额正确", r.json().get("balance") == 15300.00)
|
||
|
||
print("\n--- 更新招商银行余额 ---")
|
||
r = requests.post(f"{BASE_URL}/accounts/{bank_id}/balance", json={
|
||
"new_balance": 40000.00,
|
||
"note": "取现"
|
||
})
|
||
test("招商银行取现 200", r.status_code == 200)
|
||
|
||
print("\n--- 更新花呗余额 ---")
|
||
r = requests.post(f"{BASE_URL}/accounts/{huabei_id}/balance", json={
|
||
"new_balance": 2500.00,
|
||
"note": "提前还款500"
|
||
})
|
||
test("花呗提前还款 200", r.status_code == 200)
|
||
test("花呗余额更新", r.json().get("balance") == 2500.00)
|
||
|
||
# ============================================================
|
||
section("5. 变更历史测试")
|
||
# ============================================================
|
||
|
||
print("\n--- 查看微信变更历史 ---")
|
||
r = requests.get(f"{BASE_URL}/accounts/{wechat_id}/history", params={
|
||
"page": 1,
|
||
"page_size": 10
|
||
})
|
||
test("获取微信历史 200", r.status_code == 200, f"status={r.status_code}")
|
||
history = r.json()
|
||
test("历史总数正确", history.get("total") == 2, f"实际: {history.get('total')}")
|
||
test("分页参数正确", history.get("page") == 1 and history.get("page_size") == 10)
|
||
|
||
if history.get("records"):
|
||
first_record = history["records"][0]
|
||
test("最新记录是消费", first_record.get("change_amount") == -1500.0,
|
||
f"实际: {first_record.get('change_amount')}")
|
||
test("消费前余额正确", first_record.get("balance_before") == 6800.50)
|
||
test("消费后余额正确", first_record.get("balance_after") == 5300.50)
|
||
test("消费备注正确", first_record.get("note") == "日常消费")
|
||
test("记录有创建时间", first_record.get("created_at") is not None)
|
||
|
||
print("\n--- 查看支付宝变更历史 ---")
|
||
r = requests.get(f"{BASE_URL}/accounts/{alipay_id}/history")
|
||
history_alipay = r.json()
|
||
test("支付宝历史 200", r.status_code == 200)
|
||
test("支付宝历史有记录", history_alipay.get("total") == 1)
|
||
|
||
print("\n--- 查看从未变更的账户历史 ---")
|
||
r = requests.get(f"{BASE_URL}/accounts/{baitiao_id}/history")
|
||
test("白条历史 200", r.status_code == 200)
|
||
test("白条无变更记录", r.json().get("total") == 0)
|
||
|
||
|
||
# ============================================================
|
||
section("6. 分期还款计划 CRUD 测试")
|
||
# ============================================================
|
||
|
||
# 6.1 为花呗创建分期计划(3期,每月12号,每期1000)
|
||
print("\n--- 创建花呗分期计划 ---")
|
||
r = requests.post(f"{BASE_URL}/debt-installments", json={
|
||
"account_id": huabei_id,
|
||
"total_amount": 3000.00,
|
||
"total_periods": 3,
|
||
"current_period": 1,
|
||
"payment_day": 12,
|
||
"payment_amount": 1000.00,
|
||
"start_date": "2026-03-12",
|
||
"is_completed": False
|
||
})
|
||
test("创建花呗分期 201", r.status_code == 201, f"status={r.status_code}")
|
||
huabei_inst = r.json()
|
||
test("花呗分期ID存在", huabei_inst.get("id") is not None)
|
||
test("花呗下次还款日期已计算", huabei_inst.get("next_payment_date") is not None)
|
||
test("花呗距今天数已计算", huabei_inst.get("days_until_payment") is not None)
|
||
test("花呗剩余期数", huabei_inst.get("remaining_periods") == 3)
|
||
test("花呗账户名称关联", huabei_inst.get("account_name") == "花呗")
|
||
huabei_inst_id = huabei_inst["id"]
|
||
|
||
# 6.2 为白条创建分期计划(6期,每月15号,每期333.33)
|
||
print("\n--- 创建白条分期计划 ---")
|
||
r = requests.post(f"{BASE_URL}/debt-installments", json={
|
||
"account_id": baitiao_id,
|
||
"total_amount": 2000.00,
|
||
"total_periods": 6,
|
||
"current_period": 3,
|
||
"payment_day": 15,
|
||
"payment_amount": 333.33,
|
||
"start_date": "2026-01-15",
|
||
"is_completed": False
|
||
})
|
||
test("创建白条分期 201", r.status_code == 201, f"status={r.status_code}")
|
||
baitiao_inst = r.json()
|
||
test("白条分期第3期", baitiao_inst.get("current_period") == 3)
|
||
test("白条剩余期数", baitiao_inst.get("remaining_periods") == 4)
|
||
baitiao_inst_id = baitiao_inst["id"]
|
||
|
||
# 6.3 验证不能给存款账户创建分期
|
||
print("\n--- 验证存款账户不能创建分期 ---")
|
||
r = requests.post(f"{BASE_URL}/debt-installments", json={
|
||
"account_id": wechat_id,
|
||
"total_amount": 1000,
|
||
"total_periods": 1,
|
||
"current_period": 1,
|
||
"payment_day": 1,
|
||
"payment_amount": 1000,
|
||
"start_date": "2026-04-01",
|
||
"is_completed": False
|
||
})
|
||
test("存款账户不能分期 400", r.status_code == 400, f"status={r.status_code}")
|
||
|
||
# 6.4 验证不存在的账户
|
||
r = requests.post(f"{BASE_URL}/debt-installments", json={
|
||
"account_id": 99999,
|
||
"total_amount": 1000,
|
||
"total_periods": 1,
|
||
"current_period": 1,
|
||
"payment_day": 1,
|
||
"payment_amount": 1000,
|
||
"start_date": "2026-04-01",
|
||
"is_completed": False
|
||
})
|
||
test("不存在账户不能分期 404", r.status_code == 404, f"status={r.status_code}")
|
||
|
||
|
||
# ============================================================
|
||
section("7. 获取分期计划列表测试")
|
||
# ============================================================
|
||
|
||
print("\n--- 获取所有分期计划 ---")
|
||
r = requests.get(f"{BASE_URL}/debt-installments")
|
||
test("获取分期列表 200", r.status_code == 200, f"status={r.status_code}")
|
||
installments = r.json()
|
||
test("分期计划总数 >= 2", len(installments) >= 2, f"实际: {len(installments)}")
|
||
|
||
# 验证排序:未完成的排前面,临近的排前面
|
||
if len(installments) >= 2:
|
||
first_active = next((i for i in installments if not i["is_completed"]), None)
|
||
test("列表第一个是未完成的", first_active is not None)
|
||
if first_active:
|
||
test("第一个有还款日期", first_active.get("next_payment_date") is not None)
|
||
test("第一个有距今天数", first_active.get("days_until_payment") is not None)
|
||
|
||
# 验证每个计划都有计算字段
|
||
for inst in installments:
|
||
test(f"分期#{inst['id']}有计算字段",
|
||
inst.get("next_payment_date") is not None and
|
||
inst.get("days_until_payment") is not None and
|
||
inst.get("remaining_periods") is not None,
|
||
f"id={inst['id']}")
|
||
|
||
|
||
# ============================================================
|
||
section("8. 更新分期计划测试")
|
||
# ============================================================
|
||
|
||
print("\n--- 更新花呗分期计划 ---")
|
||
r = requests.put(f"{BASE_URL}/debt-installments/{huabei_inst_id}", json={
|
||
"total_amount": 3500.00,
|
||
"payment_amount": 1166.67
|
||
})
|
||
test("更新花呗分期 200", r.status_code == 200, f"status={r.status_code}")
|
||
updated = r.json()
|
||
test("花呗总额更新", updated.get("total_amount") == 3500.00)
|
||
test("花呗每期金额更新", updated.get("payment_amount") == 1166.67)
|
||
|
||
# 恢复
|
||
requests.put(f"{BASE_URL}/debt-installments/{huabei_inst_id}", json={
|
||
"total_amount": 3000.00,
|
||
"payment_amount": 1000.00
|
||
})
|
||
|
||
|
||
# ============================================================
|
||
section("9. 标记还款测试(核心流程)")
|
||
# ============================================================
|
||
|
||
print("\n--- 花呗还款第1期 ---")
|
||
r = requests.patch(f"{BASE_URL}/debt-installments/{huabei_inst_id}/pay")
|
||
test("花呗还款第1期 200", r.status_code == 200, f"status={r.status_code}")
|
||
paid = r.json()
|
||
test("当前期数变为2", paid.get("current_period") == 2, f"实际: {paid.get('current_period')}")
|
||
test("未完成", paid.get("is_completed") == False)
|
||
test("剩余期数变为2", paid.get("remaining_periods") == 2)
|
||
|
||
print("\n--- 花呗还款第2期 ---")
|
||
r = requests.patch(f"{BASE_URL}/debt-installments/{huabei_inst_id}/pay")
|
||
test("花呗还款第2期 200", r.status_code == 200)
|
||
paid = r.json()
|
||
test("当前期数变为3", paid.get("current_period") == 3)
|
||
test("剩余期数变为1", paid.get("remaining_periods") == 1)
|
||
|
||
print("\n--- 花呗还款第3期(最后一期)---")
|
||
r = requests.patch(f"{BASE_URL}/debt-installments/{huabei_inst_id}/pay")
|
||
test("花呗还款第3期 200", r.status_code == 200)
|
||
paid = r.json()
|
||
test("标记为已完成", paid.get("is_completed") == True)
|
||
test("当前期数等于总期数", paid.get("current_period") == 3)
|
||
test("剩余期数为0", paid.get("remaining_periods") == 0)
|
||
|
||
print("\n--- 已完成的分期不能继续还款 ---")
|
||
r = requests.patch(f"{BASE_URL}/debt-installments/{huabei_inst_id}/pay")
|
||
test("已完成分期拒绝还款 400", r.status_code == 400, f"status={r.status_code}")
|
||
|
||
|
||
# ============================================================
|
||
section("10. 删除操作测试")
|
||
# ============================================================
|
||
|
||
# 10.1 删除分期计划
|
||
print("\n--- 删除白条分期计划 ---")
|
||
r = requests.delete(f"{BASE_URL}/debt-installments/{baitiao_inst_id}")
|
||
test("删除白条分期 200", r.status_code == 200, f"status={r.status_code}")
|
||
|
||
# 验证删除后列表中没有了
|
||
r = requests.get(f"{BASE_URL}/debt-installments")
|
||
ids = [i["id"] for i in r.json()]
|
||
test("白条分期已从列表移除", baitiao_inst_id not in ids)
|
||
|
||
# 10.2 删除已禁用账户
|
||
print("\n--- 删除已禁用账户 ---")
|
||
r = requests.delete(f"{BASE_URL}/accounts/{disabled_id}")
|
||
test("删除已禁用账户 200", r.status_code == 200)
|
||
|
||
# 10.3 验证删除后
|
||
r = requests.get(f"{BASE_URL}/accounts")
|
||
ids = [a["id"] for a in r.json()]
|
||
test("已禁用账户已移除", disabled_id not in ids)
|
||
|
||
# 10.4 重新创建一个花呗分期用来测试级联删除
|
||
print("\n--- 测试级联删除 ---")
|
||
r = requests.post(f"{BASE_URL}/debt-installments", json={
|
||
"account_id": huabei_id,
|
||
"total_amount": 1000.00,
|
||
"total_periods": 1,
|
||
"current_period": 1,
|
||
"payment_day": 25,
|
||
"payment_amount": 1000.00,
|
||
"start_date": "2026-03-25",
|
||
"is_completed": False
|
||
})
|
||
cascade_inst_id = r.json()["id"]
|
||
|
||
r = requests.delete(f"{BASE_URL}/accounts/{huabei_id}")
|
||
test("级联删除花呗账户 200", r.status_code == 200)
|
||
|
||
# 验证分期计划也被删除了
|
||
r = requests.get(f"{BASE_URL}/debt-installments")
|
||
ids = [i["id"] for i in r.json()]
|
||
test("花呗关联分期也被删除", cascade_inst_id not in ids)
|
||
|
||
# 验证历史记录也被删除
|
||
r = requests.get(f"{BASE_URL}/accounts/{huabei_id}/history")
|
||
test("花呗账户删除后历史不可访问", r.status_code == 404, f"status={r.status_code}")
|
||
|
||
|
||
# ============================================================
|
||
section("11. 边界条件测试")
|
||
# ============================================================
|
||
|
||
print("\n--- 余额更新到0 ---")
|
||
r = requests.post(f"{BASE_URL}/accounts/{baitiao_id}/balance", json={
|
||
"new_balance": 0,
|
||
"note": "还清"
|
||
})
|
||
test("余额归零 200", r.status_code == 200)
|
||
test("余额为0", r.json().get("balance") == 0)
|
||
|
||
print("\n--- 余额更新到大额 ---")
|
||
r = requests.post(f"{BASE_URL}/accounts/{baitiao_id}/balance", json={
|
||
"new_balance": 999999.99,
|
||
"note": "测试大额"
|
||
})
|
||
test("大额余额 200", r.status_code == 200)
|
||
test("大额余额正确", r.json().get("balance") == 999999.99)
|
||
|
||
# 恢复
|
||
requests.post(f"{BASE_URL}/accounts/{baitiao_id}/balance", json={
|
||
"new_balance": 2000.00,
|
||
"note": "恢复"
|
||
})
|
||
|
||
print("\n--- 参数校验:缺失必填字段 ---")
|
||
r = requests.post(f"{BASE_URL}/accounts", json={
|
||
"name": "",
|
||
})
|
||
test("空名称被拒绝 422", r.status_code == 422, f"status={r.status_code}")
|
||
|
||
print("\n--- 参数校验:无效类型 ---")
|
||
r = requests.post(f"{BASE_URL}/accounts", json={
|
||
"name": "测试账户",
|
||
"account_type": "invalid_type",
|
||
})
|
||
test("无效类型被拒绝 422", r.status_code == 422, f"status={r.status_code}")
|
||
|
||
print("\n--- 分期参数校验 ---")
|
||
r = requests.post(f"{BASE_URL}/debt-installments", json={
|
||
"account_id": baitiao_id,
|
||
"total_amount": 0,
|
||
"total_periods": 1,
|
||
"current_period": 1,
|
||
"payment_day": 1,
|
||
"payment_amount": 0,
|
||
"start_date": "2026-04-01",
|
||
"is_completed": False
|
||
})
|
||
test("零金额分期被拒绝 422", r.status_code == 422, f"status={r.status_code}")
|
||
|
||
|
||
# ============================================================
|
||
section("12. 账户列表的分期信息附加测试")
|
||
# ============================================================
|
||
|
||
print("\n--- 获取白条账户(验证分期信息附加) ---")
|
||
# 先给白条创建一个分期
|
||
r = requests.post(f"{BASE_URL}/debt-installments", json={
|
||
"account_id": baitiao_id,
|
||
"total_amount": 2000.00,
|
||
"total_periods": 6,
|
||
"current_period": 2,
|
||
"payment_day": 15,
|
||
"payment_amount": 333.33,
|
||
"start_date": "2026-01-15",
|
||
"is_completed": False
|
||
})
|
||
test("白条分期重建 201", r.status_code == 201)
|
||
|
||
r = requests.get(f"{BASE_URL}/accounts")
|
||
accounts = r.json()
|
||
baitiao_acc = next((a for a in accounts if a["id"] == baitiao_id), None)
|
||
test("白条账户有分期附加信息", baitiao_acc is not None and baitiao_acc.get("installments") is not None)
|
||
|
||
# 存款账户不应有分期信息
|
||
wechat_acc = next((a for a in accounts if a["id"] == wechat_id), None)
|
||
if wechat_acc:
|
||
test("微信账户有分期字段(空列表)", wechat_acc.get("installments") is not None)
|
||
test("微信分期列表为空", len(wechat_acc.get("installments", [])) == 0)
|
||
|
||
|
||
# ============================================================
|
||
section("13. 历史分页测试")
|
||
# ============================================================
|
||
|
||
print("\n--- 历史分页 ---")
|
||
# 先给招商银行做多次变更
|
||
for i, (bal, note) in enumerate([
|
||
(45000, "存入"),
|
||
(42000, "消费"),
|
||
(50000, "转入"),
|
||
(48000, "理财"),
|
||
(52000, "收益"),
|
||
]):
|
||
requests.post(f"{BASE_URL}/accounts/{bank_id}/balance", json={
|
||
"new_balance": bal,
|
||
"note": note
|
||
})
|
||
|
||
r = requests.get(f"{BASE_URL}/accounts/{bank_id}/history", params={"page": 1, "page_size": 3})
|
||
test("历史分页第1页 200", r.status_code == 200)
|
||
page1 = r.json()
|
||
test("每页3条", len(page1.get("records", [])) == 3, f"实际: {len(page1.get('records', []))}")
|
||
test("总记录6条", page1.get("total") == 6, f"实际: {page1.get('total')}")
|
||
|
||
r = requests.get(f"{BASE_URL}/accounts/{bank_id}/history", params={"page": 2, "page_size": 3})
|
||
test("历史分页第2页 200", r.status_code == 200)
|
||
page2 = r.json()
|
||
test("第2页3条", len(page2.get("records", [])) == 3, f"实际: {len(page2.get('records', []))}")
|
||
|
||
# 验证第1页和第2页没有重复
|
||
page1_ids = {r["id"] for r in page1["records"]}
|
||
page2_ids = {r["id"] for r in page2["records"]}
|
||
test("两页记录不重复", len(page1_ids & page2_ids) == 0)
|
||
|
||
|
||
# ============================================================
|
||
section("14. 花呗还款日期计算验证")
|
||
# ============================================================
|
||
|
||
print("\n--- 验证还款日期计算 ---")
|
||
today = date.today()
|
||
r = requests.get(f"{BASE_URL}/debt-installments")
|
||
for inst in r.json():
|
||
if inst["is_completed"]:
|
||
continue
|
||
next_date_str = inst.get("next_payment_date")
|
||
days_until = inst.get("days_until_payment")
|
||
if next_date_str:
|
||
next_date = date.fromisoformat(next_date_str)
|
||
expected_days = (next_date - today).days
|
||
test(f"分期#{inst['id']}天数计算正确", days_until == expected_days,
|
||
f"计算: {days_until}, 预期: {expected_days}")
|
||
|
||
|
||
# ============================================================
|
||
section("15. 保留测试数据(跳过清理)")
|
||
# ============================================================
|
||
|
||
print("\n--- 保留测试数据供页面展示 ---")
|
||
r = requests.get(f"{BASE_URL}/accounts")
|
||
remaining_accounts = len(r.json())
|
||
test("账户数据已保留", remaining_accounts > 0, f"保留: {remaining_accounts} 个账户")
|
||
|
||
r = requests.get(f"{BASE_URL}/debt-installments")
|
||
remaining_installs = len(r.json())
|
||
test("分期数据已保留", remaining_installs >= 0, f"保留: {remaining_installs} 个分期")
|
||
|
||
|
||
# ============================================================
|
||
# 最终报告
|
||
# ============================================================
|
||
print(f"\n{'='*60}")
|
||
print(f" 测试报告")
|
||
print(f"{'='*60}")
|
||
print(f" 通过: {passed}")
|
||
print(f" 失败: {failed}")
|
||
print(f" 总计: {passed + failed}")
|
||
if errors:
|
||
print(f"\n 失败项:")
|
||
for e in errors:
|
||
print(f" - {e}")
|
||
print(f"{'='*60}")
|
||
|
||
if failed > 0:
|
||
sys.exit(1)
|
||
else:
|
||
print("\n 全部测试通过!")
|
||
sys.exit(0)
|