# Fonrey 登录模块测试用例文档(可自动化) > 文档版本:v2.0 > 适用范围:`PRD/登录管理/用户登录管理模块PRD.md` v3.0、`TECH_STACK/登录管理技术方案.md` v4.1、`DATA_MODEL/DATA_MODEL_LOGIN.md`、`TECH_STACK/API_CONTRACT.md` > 用例编号范围:`TC-FON-000001` ~ `TC-FON-000048`、`TC-FON-000153` ~ `TC-FON-000172`(全局唯一,共 68 条) > 编号规范:`TEST_CASES/TEST_CASE_ID_SPEC.md` --- ## 变更历史 | 日期 | 变更人 | 变更内容 | |---|---|---| | 2026-04-30 | Atlas | 补充“变更历史”章节(文档治理) | | 2026-05-02 | Vulcan | 对齐 PRD v3.0 / 登录技术方案 v4.1 / DATA_MODEL_LOGIN:新增 20 条登录模块补充用例(TC-FON-000153~000172),覆盖 API 契约统一 envelope、`/api/auth/password/change-initial/`、管理员手动解锁、短信 OTP 明文不落库、历史密码保留 3 条、验证码登录错误作废文案、微信扫码预留端点不开放、`/api/auth/wechat/*` 路由未注册、登出接口与客户端会话清理联动等关键口径;总用例数 48→68 | ## 1. 目标与原则 1. 本文档用于让工程师直接生成自动化测试代码(API 集成测试 + Web E2E)。 2. 每个测试用例均包含**唯一ID**和**步骤ID**,可直接用于失败定位与测试报告。 3. 用例覆盖登录模块 MVP 正式范围: - Story 1:Tenant 识别 - Story 2:手机号+密码登录 - Story 3:短信找回密码 - Story 5:短信验证码登录 4. Story 4(找回用户名)已废弃,不实现。 5. Story 6(微信扫码)为预留,不实现,仅验证禁用态。 --- ## 2. 自动化执行与报告要求(工程实现必须遵循) - 执行层: - API 集成:`pytest + pytest-django + TenantClient` - Web E2E:`playwright` - 每步必须输出:`run_id / test_case_id / step_id / status / expected_result / actual_result / error_message` - 失败时必须附带: - Web:截图路径 - API:请求响应快照 + 关键日志路径 --- ## 3. 全量测试用例清单(68条) ### 3.0 登录模块 API 端点口径(以 `TECH_STACK/登录管理技术方案.md` §五 + `TECH_STACK/API_CONTRACT.md` 为准) - `POST /api/auth/tenant/verify/` - `GET /api/auth/captcha/` - `POST /api/auth/captcha/verify/` - `POST /api/auth/login/` - `POST /api/auth/login/phone/` - `POST /api/auth/recover/password/request/` - `POST /api/auth/recover/password/verify/` - `POST /api/auth/recover/password/reset/` - `POST /api/auth/password/change-initial/` - `POST /api/auth/logout/` > 注:测试代码生成与接口调用必须使用以上路径。 ## A. Tenant 识别(Story 1) ### TC-FON-000001 Tenant Code 页面首启展示 - 级别:E2E - 前置:本地无 Tenant Code 缓存 - 步骤: - `TC-FON-000001-S01` 启动应用/打开登录入口页 - `TC-FON-000001-S02` 检查是否进入 Tenant 识别页 - `TC-FON-000001-S03` 校验页面元素(Logo、文案、输入框、确认按钮) - 预期:显示 Tenant 识别页且元素完整 ### TC-FON-000002 Tenant Code 输入去空格与粘贴 - 级别:E2E - 前置:在 Tenant 识别页 - 步骤: - `TC-FON-000002-S01` 粘贴 ` 202500010001 ` - `TC-FON-000002-S02` 点击确认 - `TC-FON-000002-S03` 观察发送请求参数 - 预期:请求中的 tenant_code 为 `202500010001` ### TC-FON-000003 Tenant Code 非12位拦截 - 级别:E2E - 前置:Tenant 识别页 - 步骤: - `TC-FON-000003-S01` 输入 `20250001` - `TC-FON-000003-S02` 点击确认 - `TC-FON-000003-S03` 检查错误提示 - 预期:提示“识别码须为12位数字”,不发请求 ### TC-FON-000004 Tenant 验证成功流程 - 级别:API+E2E - 前置:合法 tenant_code 存在 - 步骤: - `TC-FON-000004-S01` 调用 `POST /api/auth/tenant/verify/` - `TC-FON-000004-S02` 校验 `valid=true` 且返回租户品牌信息 - `TC-FON-000004-S03` 前端跳转登录页并展示“正在登录:XX房产” - 预期:成功跳转并写入本地缓存 ### TC-FON-000005 Tenant 验证失败(无效识别码) - 级别:API+E2E - 前置:tenant_code 不存在 - 步骤: - `TC-FON-000005-S01` 调用 `POST /api/auth/tenant/verify/` - `TC-FON-000005-S02` 校验 `valid=false` 与错误码 - `TC-FON-000005-S03` 校验前端错误提示与不落缓存 - 预期:提示“识别码无效...”,允许重试 ### TC-FON-000006 Tenant 验证网络异常重试 - 级别:E2E - 前置:模拟网络失败 - 步骤: - `TC-FON-000006-S01` 点击确认触发请求失败 - `TC-FON-000006-S02` 检查“网络连接失败”提示 - `TC-FON-000006-S03` 点击重试并恢复 - 预期:重试可再次发起请求 ### TC-FON-000007 非首启跳过识别页 - 级别:E2E - 前置:本地已有合法 Tenant Code - 步骤: - `TC-FON-000007-S01` 打开应用 - `TC-FON-000007-S02` 检查是否直接进入登录页 - `TC-FON-000007-S03` 检查租户品牌信息回填 - 预期:跳过识别页 ### TC-FON-000008 切换公司入口流程 - 级别:E2E - 前置:已在登录页 - 步骤: - `TC-FON-000008-S01` 点击“切换公司” - `TC-FON-000008-S02` 校验二次确认文案 - `TC-FON-000008-S03` 确认后检查缓存清除并回到识别页 - 预期:缓存清除成功并跳回识别页 ### TC-FON-000009 Tenant 验证接口无需鉴权 - 级别:API - 前置:未登录 - 步骤: - `TC-FON-000009-S01` 不带 token 调用验证接口 - `TC-FON-000009-S02` 校验响应状态 - `TC-FON-000009-S03` 校验业务结构 - 预期:接口可访问(非401/403) ### TC-FON-000010 Tenant 验证接口IP限流 - 级别:API - 前置:同IP连续请求 - 步骤: - `TC-FON-000010-S01` 1分钟内发起11次请求 - `TC-FON-000010-S02` 校验前10次正常 - `TC-FON-000010-S03` 校验第11次被限流 - 预期:触发每分钟≤10次限制 --- ## B. 密码登录(Story 2) ### TC-FON-000011 密码登录页元素完整 - 级别:E2E - 步骤:`S01` 打开密码登录页;`S02` 检查手机号/密码/滑块/登录按钮;`S03` 检查忘记密码入口 - 预期:元素齐全 ### TC-FON-000012 手机号输入仅数字11位 - 级别:E2E - 步骤:`S01` 输入含字母字符;`S02` 观察自动过滤;`S03` 检查长度限制 - 预期:仅数字,最长11位 ### TC-FON-000013 密码明文/密文切换 - 级别:E2E - 步骤:`S01` 输入密码;`S02` 点击眼睛图标显示明文;`S03` 再次点击恢复密文 - 预期:切换正常 ### TC-FON-000014 三项未完成时登录按钮置灰 - 级别:E2E - 步骤:`S01` 只填手机号;`S02` 再填密码;`S03` 未完成滑块时检查按钮状态 - 预期:按钮不可点击 ### TC-FON-000015 滑块验证失败不计入密码错误次数 - 级别:API+E2E - 步骤: - `TC-FON-000015-S01` 调用 `GET /api/auth/captcha/` 获取 challenge - `TC-FON-000015-S02` 调用 `POST /api/auth/captcha/verify/` 提交错误轨迹 - `TC-FON-000015-S03` 检查滑块失败提示与刷新,且登录失败计数未增加 - 预期:不计入账号锁定计数 ### TC-FON-000016 滑块验证成功状态保持至提交 - 级别:E2E - 步骤:`S01` 完成滑块;`S02` 检查“验证通过”状态;`S03` 立即点登录 - 预期:状态有效并允许提交 ### TC-FON-000017 登录前端校验-手机号为空 - 级别:E2E - 步骤:`S01` 留空手机号;`S02` 点登录;`S03` 检查提示 - 预期:提示“请输入手机号” ### TC-FON-000018 登录前端校验-手机号不足11位 - 级别:E2E - 步骤:`S01` 输入10位;`S02` 点登录;`S03` 检查提示 - 预期:提示“请输入完整的11位手机号” ### TC-FON-000019 登录前端校验-密码为空 - 级别:E2E - 步骤:`S01` 填手机号与滑块通过;`S02` 密码留空;`S03` 点登录 - 预期:提示“请输入密码” ### TC-FON-000020 登录前端校验-未完成滑块 - 级别:E2E - 步骤:`S01` 填手机号密码;`S02` 不做滑块;`S03` 点登录 - 预期:提示“请完成滑块验证” ### TC-FON-000021 密码登录成功(is_initial_password=False) - 级别:API+E2E - 步骤: - `TC-FON-000021-S01` 调用 `POST /api/auth/login/` 提交正确手机号/密码与 `captcha_pass_token` - `TC-FON-000021-S02` 校验返回 token 与 `is_initial_password=false` - `TC-FON-000021-S03` 校验跳首页欢迎语 - 预期:登录成功进入首页 ### TC-FON-000022 密码登录成功(is_initial_password=True) - 级别:API+E2E - 步骤:`S01` 使用初始密码登录;`S02` 校验返回标志true;`S03` 校验跳转强制改密页 - 预期:不可访问其他页面 ### TC-FON-000023 密码错误提示统一 - 级别:API+E2E - 步骤:`S01` 提交错误密码;`S02` 校验错误文案;`S03` 校验密码框清空+手机号保留+滑块刷新 - 预期:提示“手机号或密码错误,请重新输入” ### TC-FON-000024 连续错误5次触发账号锁定 - 级别:API - 步骤:`S01` 连续5次密码错误;`S02` 校验第5次后状态locked;`S03` 校验locked_until=now+30min - 预期:账号锁定成功 ### TC-FON-000025 锁定期间登录被拒绝 - 级别:API+E2E - 步骤:`S01` 对locked账号发起登录;`S02` 校验提示文案;`S03` 校验登录按钮置灰 - 预期:拒绝登录 ### TC-FON-000026 30分钟后自动解锁 - 级别:API - 步骤:`S01` 构造锁定到期账号;`S02` 时间推进30分钟后重试;`S03` 校验恢复登录能力 - 预期:自动解锁 ### TC-FON-000027 账号停用登录拦截 - 级别:API+E2E - 步骤:`S01` 停用账号发起登录;`S02` 校验错误码;`S03` 校验前端提示 - 预期:提示“账号已停用,请联系您的管理员” ### TC-FON-000028 Session过期跳转登录 - 级别:E2E - 步骤:`S01` 进入受保护页面;`S02` 使session过期;`S03` 执行动作触发跳转 - 预期:跳回登录并提示“登录已过期,请重新登录” --- ## C. 首次登录强制改密(Story 2/3 公共密码组件) ### TC-FON-000029 首次登录强制改密页不可跳过 - 级别:E2E - 步骤:`S01` 初始密码登录;`S02` 尝试访问其他功能路由;`S03` 检查仍停留改密流程 - 预期:不可绕过 ### TC-FON-000030 新密码强度校验 - 级别:API+E2E - 步骤:`S01` 输入弱密码;`S02` 提交;`S03` 检查强度错误提示 - 预期:拒绝弱密码 ### TC-FON-000031 新密码不得与最近3次重复 - 级别:API - 步骤:`S01` 构造历史密码3条;`S02` 提交重复密码;`S03` 校验错误码 - 预期:拒绝历史重复 ### TC-FON-000032 首次改密成功后状态更新 - 级别:API - 步骤:`S01` 提交合法新密码;`S02` 校验is_initial_password=false;`S03` 校验password_histories新增 - 预期:状态正确更新 ### TC-FON-000033 首次改密成功后直接进入系统 - 级别:E2E - 步骤:`S01` 完成改密提交;`S02` 检查成功反馈;`S03` 校验跳首页 - 预期:进入首页 --- ## D. 找回密码(Story 3) ### TC-FON-000034 忘记密码入口可达 - 级别:E2E - 步骤:`S01` 登录页点击忘记密码;`S02` 校验进入Stepper;`S03` 校验步骤一元素 - 预期:进入找回密码流程 ### TC-FON-000035 步骤一手机号格式校验 - 级别:E2E - 步骤:`S01` 输入不足11位手机号;`S02` 点获取验证码;`S03` 检查提示 - 预期:提示“请输入完整的11位手机号” ### TC-FON-000036 步骤一发送验证码成功(active账号) - 级别:API+E2E - 步骤: - `TC-FON-000036-S01` 调用 `POST /api/auth/recover/password/request/` 提交 active 手机号 - `TC-FON-000036-S02` 校验进入 60 秒倒计时 - `TC-FON-000036-S03` 校验 `sms_otp_records` 写入 `scene=password_reset` 且有效期 10 分钟 - 预期:发送成功并记录正确 ### TC-FON-000037 步骤一防枚举响应(不存在/停用账号) - 级别:API - 步骤:`S01` 分别提交不存在和停用手机号;`S02` 校验响应文案一致;`S03` 校验不泄露账号状态 - 预期:统一提示“如该手机号已注册...” ### TC-FON-000038 找回密码短信发送频控(5次/小时) - 级别:API - 步骤:`S01` 同手机号发送6次;`S02` 校验前5次可用;`S03` 校验第6次超限 - 预期:提示“发送次数过多,请1小时后再试” ### TC-FON-000039 步骤二验证码正确进入步骤三 - 级别:API+E2E - 步骤: - `TC-FON-000039-S01` 调用 `POST /api/auth/recover/password/verify/` 提交正确 6 位验证码 - `TC-FON-000039-S02` 校验颁发 `sms_reset_token`(15 分钟) - `TC-FON-000039-S03` 页面进入步骤三 - 预期:通过校验并进入重置页 ### TC-FON-000040 步骤二验证码错误与5次作废 - 级别:API - 步骤:`S01` 连续输入错误验证码5次;`S02` 检查前4次提示错误;`S03` 第5次后验证码作废 - 预期:提示“验证码已失效,请重新获取” ### TC-FON-000041 步骤二验证码过期 - 级别:API - 步骤:`S01` 使用超时验证码提交;`S02` 校验错误码;`S03` 校验提示文案 - 预期:提示“验证码已过期,请重新获取” ### TC-FON-000042 步骤三token无效或过期 - 级别:API+E2E - 步骤:`S01` 使用无效sms_reset_token访问步骤三;`S02` 校验错误提示;`S03` 跳回步骤一 - 预期:提示“操作已超时,请重新发起找回密码” ### TC-FON-000043 步骤三重置成功后会话失效 - 级别:API - 步骤: - `TC-FON-000043-S01` 调用 `POST /api/auth/recover/password/reset/`(携带有效 `sms_reset_token`)重置密码 - `TC-FON-000043-S02` 校验 `is_initial_password=false` - `TC-FON-000043-S03` 校验该用户历史 session 失效 - 预期:需重新登录 ### TC-FON-000044 重置成功后用新密码登录 - 级别:E2E - 步骤:`S01` 完成找回密码全流程;`S02` 跳回登录页;`S03` 用新密码登录成功 - 预期:登录成功,提示“密码已重置,请使用新密码登录” --- ## E. 验证码登录(Story 5) ### TC-FON-000045 登录方式Tab切换与状态重置 - 级别:E2E - 步骤:`S01` 从密码登录切换到验证码登录;`S02` 检查表单区切换;`S03` 校验原输入与滑块状态清空 - 预期:状态重置正确 ### TC-FON-000046 未完成滑块禁止获取登录验证码 - 级别:E2E - 步骤:`S01` 进入验证码登录Tab;`S02` 直接点获取验证码;`S03` 检查提示 - 预期:提示“请先完成滑块验证” ### TC-FON-000047 登录验证码发送与频控(10次/小时,独立于找回密码) - 级别:API - 步骤:`S01` 发送登录验证码11次(scene=login);`S02` 校验第11次超限;`S03` 校验找回密码scene不受影响 - 预期:login场景10次/小时,scene隔离计数 ### TC-FON-000048 验证码登录成功/失败/锁定限制 - 级别:API+E2E - 步骤: - `TC-FON-000048-S01` 调用 `POST /api/auth/login/phone/`,正确 OTP 登录成功,返回 token 与 `is_initial_password` - `TC-FON-000048-S02` 调用 `POST /api/auth/login/phone/`,错误 OTP 提示“验证码有误”,5 次后作废 - `TC-FON-000048-S03` 账号 locked 时调用 `POST /api/auth/login/phone/` 同样被拒绝 - 预期:三类行为均符合 PRD --- ## F. 补充用例(PRD v3.0 / 技术方案 v4.1 / DATA_MODEL / API_CONTRACT 对齐) ### TC-FON-000153 首次登录改密提交接口成功 - 级别:API - 前置:账号 `is_initial_password=true`,已完成登录并具备改密会话 - 步骤: - `TC-FON-000153-S01` 调用 `POST /api/auth/password/change-initial/` 提交合法新密码 - `TC-FON-000153-S02` 校验返回成功,`is_initial_password=false` - `TC-FON-000153-S03` 校验 `password_histories` 新增记录 - 预期:首次改密成功落库,账号脱离初始密码状态 ### TC-FON-000154 首次登录改密弱密码拦截 - 级别:API+E2E - 前置:账号处于首次改密页 - 步骤:`S01` 输入不满足复杂度的新密码;`S02` 提交改密;`S03` 校验错误码/错误提示 - 预期:返回 `AUTH_PASSWORD_WEAK`,拒绝提交 ### TC-FON-000155 首次登录改密禁止复用最近3次历史密码 - 级别:API - 前置:`password_histories` 已有最近 3 条 - 步骤:`S01` 提交与最近历史重复的新密码;`S02` 校验错误响应;`S03` 校验密码未更新 - 预期:拒绝历史重复密码,历史记录不新增 ### TC-FON-000156 首次改密成功后会话保持并直达首页 - 级别:E2E - 前置:初始密码登录进入强制改密页 - 步骤:`S01` 完成改密提交;`S02` 校验未二次登录;`S03` 校验直接进入首页 - 预期:沿用当前会话进入系统(不强制重新登录) ### TC-FON-000157 找回密码成功后不再触发首次改密 - 级别:API+E2E - 前置:账号原为初始密码状态,执行找回密码三步成功 - 步骤: - `TC-FON-000157-S01` 调用 `POST /api/auth/recover/password/reset/` 成功后校验 `is_initial_password=false` - `TC-FON-000157-S02` 返回登录页使用新密码登录 - `TC-FON-000157-S03` 校验直接进入首页而非首次改密页 - 预期:找回密码后视为已完成身份核验,不再触发强制改密 ### TC-FON-000158 主动登出销毁会话与登录凭证 - 级别:API+E2E - 前置:已登录 - 步骤: - `TC-FON-000158-S01` 调用 `POST /api/auth/logout/` - `TC-FON-000158-S02` 校验服务端会话失效(后续受保护请求无效) - `TC-FON-000158-S03` Electron 客户端侧校验登录凭证清理与跳转登录页 - 预期:登出后不可复用原凭证继续访问系统 ### TC-FON-000159 管理员手动解锁账号 - 级别:API - 前置:账号因连续密码错误达到阈值已处于 `locked` - 步骤:`S01` Tenant Admin 在后台执行手动解锁;`S02` 校验 `user_accounts.status=active` 且 `locked_until` 清空;`S03` 立即发起登录请求并成功 - 预期:管理员可提前解锁,无需等待 30 分钟自动解锁 ### TC-FON-000160 找回密码步骤一防枚举且无效账号不落短信记录 - 级别:API - 前置:准备“未注册手机号”“停用账号手机号” - 步骤:`S01` 分别调用 `POST /api/auth/recover/password/request/`;`S02` 校验外显响应一致;`S03` 校验 `sms_otp_records` 未新增对应记录 - 预期:外显统一且不泄露账号状态,不产生无效 OTP 记录 ### TC-FON-000161 短信验证码仅哈希存储(禁止明文入库) - 级别:API - 前置:触发找回密码或验证码登录发码 - 步骤:`S01` 查询 `sms_otp_records` 最新记录;`S02` 校验存在 `otp_hash`;`S03` 校验无 OTP 明文字段/日志明文 - 预期:满足 DATA_MODEL 安全要求(OTP 明文不落库) ### TC-FON-000162 找回密码验证码错误5次后作废并持久化状态 - 级别:API - 前置:已生成有效 `scene=password_reset` OTP - 步骤:`S01` 连续提交错误验证码 5 次;`S02` 校验第 5 次后提示“验证码已失效,请重新获取”;`S03` 校验记录 `verify_attempts=5` 且 `is_used=true` - 预期:OTP 作废口径与数据状态一致 ### TC-FON-000163 OTP 两场景有效期差异校验(10 分钟 / 5 分钟) - 级别:API - 步骤: - `TC-FON-000163-S01` 发起 `scene=password_reset`,校验 `expires_at=created_at+10分钟` - `TC-FON-000163-S02` 发起 `scene=login`,校验 `expires_at=created_at+5分钟` - `TC-FON-000163-S03` 校验两场景限流计数独立 - 预期:有效期与频控均符合技术方案与数据模型 ### TC-FON-000164 验证码登录错误5次后作废并提示重新获取 - 级别:API+E2E - 前置:已发送 `scene=login` 验证码 - 步骤:`S01` 连续输入错误 OTP 5 次;`S02` 校验第 5 次提示“验证码已失效,请重新获取”;`S03` 再次提交原 OTP 必须失败 - 预期:验证码登录错误上限与作废文案符合 PRD ### TC-FON-000165 登录审计 `login_attempts.failure_reason` 写入准确 - 级别:API - 步骤: - `TC-FON-000165-S01` 触发一次密码错误,校验记录 `wrong_password` - `TC-FON-000165-S02` 触发一次滑块失败,校验记录 `wrong_captcha` - `TC-FON-000165-S03` 触发一次 OTP 错误,校验记录 `wrong_otp` - 预期:失败原因枚举写入正确,便于审计与风控 ### TC-FON-000166 锁定账号验证码登录返回标准错误码 - 级别:API - 前置:账号已 `locked` - 步骤:`S01` 调用 `POST /api/auth/login/phone/`;`S02` 校验 HTTP 423;`S03` 校验错误码 `AUTH_ACCOUNT_LOCKED` - 预期:账号维度锁定策略对验证码登录同样生效 ### TC-FON-000167 Tenant 校验限流错误契约 - 级别:API - 前置:同 IP 1 分钟内第 11 次请求 - 步骤:`S01` 触发 `POST /api/auth/tenant/verify/` 限流;`S02` 校验 HTTP 429;`S03` 校验 `code=AUTH_TENANT_RATE_LIMITED` 且错误体字段完整 - 预期:限流错误符合 API_CONTRACT 与技术方案 ### TC-FON-000168 API 失败响应统一 envelope 契约 - 级别:API - 前置:构造任一登录失败场景(如密码错误) - 步骤:`S01` 调用失败接口;`S02` 校验响应包含 `ok=false`、`error`、`code`、`meta.request_id`、`meta.timestamp`;`S03` 校验字段类型正确 - 预期:失败响应结构符合 `TECH_STACK/API_CONTRACT.md` ### TC-FON-000169 密码登录失败错误码与状态码契约 - 级别:API - 前置:账号存在,密码错误 - 步骤:`S01` 调用 `POST /api/auth/login/`;`S02` 校验 HTTP 401;`S03` 校验 `code=AUTH_INVALID_CREDENTIAL` 与统一错误结构 - 预期:失败状态码与错误码稳定、可机器判定 ### TC-FON-000170 找回密码重置凭证无效错误契约 - 级别:API - 前置:`sms_reset_token` 无效或过期 - 步骤:`S01` 调用 `POST /api/auth/recover/password/reset/`;`S02` 校验 HTTP 400;`S03` 校验 `code=AUTH_SMS_RESET_TOKEN_INVALID` - 预期:错误码与文案符合技术方案 ### TC-FON-000171 登录页微信扫码入口禁用态验证 - 级别:E2E - 步骤:`S01` 打开登录页;`S02` 校验“微信扫码登录 - 即将开放”为灰态不可点击;`S03` 校验无跳转行为 - 预期:MVP 仅展示禁用入口,不提供可用登录能力 ### TC-FON-000172 微信预留端点未开放(qrcode/callback) - 级别:API - 步骤:`S01` 调用 `GET /api/auth/wechat/qrcode/`,校验 HTTP 404 或路由未注册;`S02` 调用 `POST /api/auth/wechat/callback/`,校验 HTTP 404 或路由未注册;`S03` 校验未返回可用二维码数据且未签发任何登录态 - 预期:MVP 阶段微信相关预留端点均不开放 --- ## 4. 工程实现指引(给测试开发工程师) 1. **目录建议** - `tests/integration/login/test_tc_fon_000001_000048_and_000153_000172.py` - `tests/e2e/login/test_tc_fon_000001_000048_and_000153_000172.spec.ts` 2. **命名规范** - 函数名必须带用例ID,例如:`def test_tc_fon_000024_account_lock_after_5_failures():` 3. **步骤日志** - 每步执行前后打印 step_id;断言失败时把 step_id 写入异常消息 4. **报告聚合** - 生成 `reports/login_run_.json` + `reports/login_run_.html` 5. **CI 门禁** - `TC-FON-000001` ~ `TC-FON-000048` 与 `TC-FON-000153` ~ `TC-FON-000172` 全量通过才允许合并 --- ## 5. 变更规则 - 新增登录用例:从 `TC-FON-000173` 开始递增 - 后续房源/客源模块:继续用同一全局序列,不得重号 - 禁止删除历史用例ID;可标记 `deprecated` 但保留编号与历史报告可追溯性