技术文档

分层测试与双端验收矩阵

本页将源码检查、自动测试、界面验证、真实设备与生产验收分开。矩阵中的“期望”是测试断言或必须满足的产品边界,不表示本轮已经运行。历史记录按其日期和目标保留;所有新增执行都应记录当前基线、设备、环境、命令、结果与剩余范围。基础命令见测试,模块入口见模块地图。

环境与证据约定

每个场景至少记录 App 平台、构建、OS、网络、Account/聊天环境、合成账号代号和前置关系。正常、拒绝、断网与重启不能混为同一用例。一次失败若发生在环境准备阶段,应记为“前置条件未满足”,不能删掉或改成测试跳过后再宣称功能通过。

证据层 能确认 不能替代
源码与配置 路由、类型、校验、状态机、默认值 实际运行配置与业务结果
单元/本地集成 可重复的输入、状态和权限断言 真实平台回调与公网服务
系统 UI 测试 指定设备的元素、焦点和操作路径 其他屏幕、OS、硬件和商店环境
授权真机闭环 指定账号、设备与网络的实际结果 永久登录、所有地区或所有用户
正式回执 上传、提审、审核与发布的各自阶段 未记录的后续动作

Account 自动测试使用专用 identity_dev MySQL 与随机表前缀;聊天测试使用内存库或临时 SQLite;原生设备测试使用自己的文件和设置命名空间。禁止把生产 token、真实记忆、私人聊天或现有设备数据作为通用夹具。测试前后可核对密文数量和摘要,不读取正文证明“没有修改”。

登录与设备会话

场景 正常与拒绝 断网/重启及双端期望 验证方法
发起原生授权 随机 verifier、S256、保存 pending 后才开浏览器;错 URL 或存储失败拒绝打开 连点只创建当前事务;退出后的迟到响应不重新登录 iOS ChatNativeAuthTests、Android NativeAuthTest、服务端 native-auth 测试
state 与 ticket 正确 proof 单次换票;缺失、错误、重复、取消、过期均不替换原有效账号 回调不能从另一环境或设备拼接;重放不产生第二个 session 服务端验证与两端隔离状态机断言
网页到 App 系统浏览器显示正确 Account、用户完成授权、自动回 App 真正替换进程后回跳;需保存完整阶段与设备时间线 授权真机人工闭环;iOS 系统“继续”提示单独观察
会话恢复 /me 成功恢复资料;401 清理当前凭据 503、超时和临时离线保留凭据;恢复网络后重试 Android NativeAuthSessionTest;iOS 授权与 Keychain 测试,加真机恢复
退出竞态 本机退出并停止轮询、通话和待处理授权 服务端退出失败不能显示为已撤销全部会话;旧请求不能回写新账号 测试迟到响应、同机账号切换及离线退出

iOS 会保存待换票 ticket 与 API 来源,Android pending 没有相同字段,不能把 iOS 的“换票时中断可重试”结论直接套用 Android。Android 当前没有 Debug 本地 Account 信任例外,隔离普通 API 可测,隔离浏览器原生登录仍需受控测试配置。聊天会话 24 小时,无 refresh-token 路由;不得用修改系统时钟或共享真实 token 代替可控时钟测试。

联系人、消息与在线状态

模块与场景 正常期望 拒绝/断网/重启/双端期望 验证入口
好友申请 唯一好友 ID 或当前临时码发申请,对方同意后可私聊 自己、未知、过期码、限流与屏蔽拒绝;重开后关系仍一致 chat.test.mjs、management.test.mjs,两合成账号与第三观察账号
群成员 群主邀请、改名、移除;成员按权限读取 非成员不可读;被移除后不可发送或拿新媒体凭证;新成员历史边界正确 group.test.mjs、通话成员变化测试
文本去重 成功写入一条并产生当前用户事件 丢响应后使用原 clientId 重试只保留一条;换内容/换范围复用 ID 拒绝 chat.test.mjs、MessageSendIdCoordinatorTest、iOS 聊天测试
已读与删除 已读位置单向前进;本人删除只改变自己的视图 旧读位置不倒退;恢复聊天不恢复删除前历史;双方结果分别核对 服务端权限断言、双端可见列表与历史分页
事件同步 消费普通事件 ID 并重新读取资源 断线保留已处理游标;重建快照不漏消息;不把消息 ID 或 MLS sequence 当普通事件游标 chat.test.mjs 与真实网络中断后列表核对
媒体 上传者可读,发送引用后授权接收者可读 未发送、外人、删除可见历史后不能越权;重开不丢引用;大文件拒绝 media.test.mjs、profile.test.mjs 与下载字节摘要
新事 好友、指定人、已登录公开、仅本人各自可见 解除关系、屏蔽、隐藏、删除立即影响读取;视频 Range 边界正确 moments.test.mjs,至少三合成账号逐项比对
城市贴纸 内置 ID 与三端素材一致,设备城市优先 权限拒绝用 IP 或手选;离开会话/换账号丢弃迟到结果;坏素材不伪造成功 city-location、city-stickers 服务端测试和原生城市测试

消息行应同时观察发送者和接收者,不能只凭本机气泡出现判断服务端成功,也不能凭 HTTP 200 判断对方已读。断网测试分别覆盖发送前、服务端提交后丢响应、媒体已上传但消息未发送三个时点;记录相同 clientId 的行为,避免测试本身重复点击产生另一条合法新消息。

位置、通话与系统能力

场景 期望 需要独立验证
实时位置 用户明确开始;PUT 只更新已开启共享;停止、离群或权限变化处理采集与服务端记录 两端前后台、粗略权限、最后更新时间、断网后旧坐标与手动停止
通话状态 成员才能发起/接听;重试不新建通话;响铃超时、忙、拒绝、挂断与群离开终态正确 calls 与 call-media 测试;至少两设备逐角色检查
媒体连接 只有 active 当前参与者可获得短时房间 token 麦克风、扬声器、蓝牙、摄像头切换、双向画面与声音、网络切换
系统来电 正确签名环境、topic、session 与设备注册 APNs 真正到达、锁屏展示、后台、取消来电、多设备竞争接听
相机与文档 只读取用户选择的内容,拒绝后仍有可用替代入口 实体相机、无相机、永久拒绝、系统撤权、文件授权失效
MLS 独立协议 密钥包、Welcome、Commit、ack、激活、密文重试与发件人校验 iOS 独立传输与 Rust 测试;不能写成主聊天及全部附件 E2EE 通过

LiveKit 本机入房与 APNs 请求格式仅属于部分证据。媒体连接成功还应在双方分别断开与恢复、对方退群、挂断后迟到 token 等场景检查,不能让旧异步操作恢复已结束通话。普通聊天、新事、位置与推送元数据的数据可读性,应与安全边界一致。

位置退出必须单独验收:当前 iOS 退出只停止本机采集,不逐范围 DELETE 远端共享;聊天 session 注销或到期也不会自动删除 live_locations,其他仍有资格成员可能继续读取最后位置。Android 远端清理采用 bestEffort,失败时同样可能残留。用合成共享分别测试退出、到期、DELETE 成功与失败,记录本机是否采集、远端是否仍有记录、其他成员能否读取,不能把一项成功当作三项全部完成。

本机工作台、记忆与转出

场景 正常与拒绝期望 重启/离线/双端区别与验证
任务与收藏 新建、编辑、筛选、去重与最近访问按本机规则保存 离线可读写;同设备重开保持;另一设备不自动同步;LocalWorkspaceStoreTests、任务 UI 与 Android 工作台流程
记忆与附件 合法内容加密保存;空模板不落盘;字段按上限处理 重开、编辑、搜索与附件字节一致;iOS/Android 文件格式分别检查,不直接互拷
损坏或丢密钥 显示无法读取并阻止覆盖 不把损坏库当空库;不新建密钥覆盖旧密文;MemoryStoreTests 与 Android 医疗/转出测试
医疗与宠物 八项医疗字段、两段 2000 字与换行保留;宠物优先规则正确 英文缩写与动物词边界、未知旧字段、附件、超长内容分别回归;不用真实医疗记录
系统推荐 iOS 系统模型可用时生成待确认结构,不可用则本机回退 Android 固定关键词路线独立;服务器识别 API 不等于本机识别,也不等于云同步
授权转出 当前用户取得额外许可后才生成明文 JSON;取消不生成完整输出 错账号、过期、断网、文件写失败清理部分文件;当前 Account 跨服务契约未闭环,需保持待验收

视觉流程另检查 320 级窄屏布局、大字号、键盘、长文件名、长文本、列表空态、底栏、弹窗与保存按钮。无障碍标识只用于测试定位,仍需实际核对朗读标签、焦点与点击区域;关闭动画后页面必须可操作。预览不按展示时长自动关闭。

命令与执行记录

以下命令展示真实测试入口,本次未执行。服务端命令在 App 仓库;Account 测试应进入其当前维护仓库另行运行:

node --test chat-service/tests/native-auth.test.mjs chat-service/tests/chat.test.mjs
node --test chat-service/tests/media.test.mjs chat-service/tests/moments.test.mjs
node --test chat-service/tests/calls.test.mjs chat-service/tests/call-media.test.mjs chat-service/tests/live-location.test.mjs
zsh ios-app/scripts/test-native-auth.sh
cd android-app
./gradlew :app:testDebugUnitTest --max-workers=1 \
  -Dorg.gradle.jvmargs=-Xmx1g -Pkotlin.compiler.execution.strategy=in-process
cd identity
npm run typecheck
npm test
npm --prefix client test

设备用例必须先指定允许使用的 QA 目标,串行执行,不卸载现有 App,不 wipe 模拟器或清 Keychain。历史医疗 QA 记录了 iOS 37 项本机测试、Android 69 项单测及专项 UI;原生授权记录包含 iOS 16 项测试与 Android 85 项 JVM、5 项隔离设备测试。Android 另有一次真实授权与 force-stop 冷启动记录;iOS 完整真实账号回跳、审核 iPad、生产推送、跨网音视频、正式包和手表独立版仍需新的证据。

每条验收结果填写:场景 ID、当前基线、期望、实得、退出码、日志摘要、目标设备、是否改变夹具、复验结果与未覆盖项。失败记录保留并关联修复后的结果;统计数量只能帮助追溯,不能替代具体断言或成为生产功能保证。发行门禁见发行清单。

Markdown 原文完整文档文本