# 测试、隔离与验收边界

本文给出仓库实际存在的测试入口，说明各层测试能够证明什么，以及如何保护本机数据。命令供维护者在具备条件的隔离环境执行；本次文档编写没有重跑产品测试。文中历史数量仅指相应日期的保存记录，不能作为当前版本、线上部署或所有设备均可用的保证。

## 选择最小有效范围

修改账号协议时优先运行协议与原生登录测试；修改记忆模板时运行本机解析、加密存储和相应界面流程；修改下载站时核对真实浏览器视口、键盘操作和下载配置。不要仅因某个聚焦测试通过就扩大结论，也不要为只读文档更新启动整套模拟器。版本和交付边界见[版本与分发状态](https://document.thestarline.cn/app/releases.md)。

| 层级 | 主要覆盖 | 不包含的结论 |
| --- | --- | --- |
| 静态检查与编译 | 类型、语法、依赖、资源打包 | 真实登录、投递和可用界面 |
| 单元与本地集成 | PKCE、状态机、权限、持久化、错误恢复 | 公网平台配置与跨网络表现 |
| 模拟器 UI | 元素位置、流程、键盘、无障碍树 | 实体相机、蜂窝网络、正式推送 |
| 授权真机验收 | 目标设备上的完整真实流程 | 未测系统版本、其他平台和永久稳定性 |
| 商店与生产回执 | 上传、提审、审核、发布各自状态 | 未在回执中确认的后续步骤 |

## 服务端测试

身份服务测试必须在 Account 当前维护仓库执行，App 工作树的 `identity/` 副本存在历史漂移。MySQL 集成测试使用固定的独立开发库：回环端口 `3310`、库名 `identity_dev`，随机生成 `t` 加 12 位十六进制与下划线的表前缀，结束时只删除该命名空间；不要把它改指生产库或现有业务库。非生产 SMTP 适配器测试另需 Mailpit 端口 `9125`、API `9135`。这只验证备用适配器，不代表当前生产 SES 邮件或阿里云短信已经送达。

```sh
cd identity
npm test
npm run typecheck
npm run build
npm --prefix client test
npm --prefix client run typecheck
npm --prefix client run build
```

`npm test` 实际调用单并发的 `tests/*.test.ts`。当前主源码还应覆盖 PII 加密／旧数据审批／错误密钥拒绝、captcha、手机号与邮件投递、管理策略、资料和手机授权等新增模块，不能只运行旧副本的文件集合。`tests/pii.test.ts` 用合成数据验证迁移；`tests/captcha.test.ts` 验证专用依赖注入，正常开发服务不提供同等绕过开关。旧注册 fixture 缺少 captcha，主仓库也没有 App 副本的本地聊天登记脚本，不能作为现成浏览器端到端前置条件。

协议测试包含软件认证器产生的真实密码学证明，但软件认证器是隔离 fixture，不是物理通行密钥验收。前端测试使用 DOM 测试环境，仍需浏览器核对表单、焦点、系统确认框和实际回调。依赖安装与构建可能访问包源，应在受控开发环境执行。详细场景、断网与双端期望见[测试矩阵](https://document.thestarline.cn/app/qa-matrix.md)。

聊天服务测试以 Node 测试运行器执行，测试自行构造合成用户、临时 SQLite 和本机 HTTP 监听。原生登录测试用合成身份响应覆盖进程重建、state、PKCE、单次票据和失败边界，不会完成真实 Account 登录。

```sh
cd chat-service
node --test tests/native-auth.test.mjs
node --test tests/city-location.test.mjs tests/city-stickers.test.mjs
node --test tests/enterprise-onboarding.test.mjs tests/enterprise.test.mjs tests/enterprise-auth.test.mjs
npm test
```

最后一条是完整聊天回归；只在变更影响范围与可用资源需要时执行。服务端状态、权限、APNs 请求格式测试通过，仍不能证明真实通知到达或两端实际接通。

## iOS 原生测试

无需启动 iOS 模拟器的登录聚焦检查入口是：

```sh
zsh ios-app/scripts/test-native-auth.sh
```

该脚本将实际授权、API、Keychain 和模型源文件复制到临时 Swift 包，单并发运行 `ChatNativeAuthTests`，结束删除临时包。测试覆盖随机 verifier、RFC 7636 向量、可信目的地、持久化失败、独立 Keychain 恢复、冷回调、取消、过期、重放、并发、迟到响应和网络重试。它不是完整 iOS 应用构建。

需要界面验证时，先创建专用 QA 模拟器并把 `QA_SIMULATOR_UDID` 设为它的标识，再串行运行指定用例：

```sh
xcodebuild -project ios-app/StarlineWorkbench.xcodeproj \
  -scheme StarlineWorkbench \
  -destination "platform=iOS Simulator,id=$QA_SIMULATOR_UDID" \
  -parallel-testing-enabled NO \
  -only-testing:StarlineWorkbenchUITests/NavigationUITests/testSignedOutProfileOpensAccountWebsiteDirectly \
  test
```

该用例核对系统“继续”提示和正式 Account 登录表单。不得把出现表单写成“真实账号已登录”。完整验收还需用户在真实表单完成身份验证、授权后回到 App、重开恢复、取消保留原会话，并核对 iPhone 与审核所涉 iPad。安装前不卸载已有 App，不清除 Keychain 或记忆。

## Android 测试

以下任务不要求启动设备，适合先验证 JVM 状态机和 APK 打包。资源受限环境可使用单 worker、限制堆与 Kotlin 进程内编译：

```sh
cd android-app
./gradlew :app:testDebugUnitTest :app:assembleDebug :app:assembleDebugAndroidTest \
  --max-workers=1 \
  -Dorg.gradle.jvmargs=-Xmx1g \
  -Pkotlin.compiler.execution.strategy=in-process
```

`NativeAuthTest` 覆盖 PKCE、state、过期、取消、事务替换与退出竞态。必须核对构建使用的 `starlineChatBaseUrl`，因为默认地址是正式聊天服务。需要隔离网络时采用[本地开发](https://document.thestarline.cn/app/development.md)中的显式覆盖。

设备测试只在已选定且允许使用的 QA 设备上运行，避免同时连接多台导致误选：

```sh
./gradlew :app:connectedDebugAndroidTest \
  -Pandroid.testInstrumentationRunnerArguments.class=cn.thestarline.workbench.NativeAuthSessionTest \
  --max-workers=1 \
  -Dorg.gradle.jvmargs=-Xmx1g \
  -Pkotlin.compiler.execution.strategy=in-process
```

该测试类使用独立文件、缓存、设置命名空间和设备回环 HTTP fixture，覆盖加密 pending、会话恢复、401 清理、503 保留与退出后的迟到结果。设备测试重建 AppState 的证明范围与系统真正杀进程后的回跳不同，后者要保留独立的端到端记录。

## 医疗健康、本机数据与视觉验收

保存记录 `docs/qa-memory-medical-health-2026-10-21.md` 描述了双端医疗模板的历史验收：八项可选字段、两段各 2000 字多行内容、搜索、编辑、附件、重开读取和删除合成记录。iOS 当时记录 37 项本机测试以及原生 UI 流程；Android 当时记录 69 项单元测试与两项设备流程。这些数量属于特定快照，本次没有复跑，也未覆盖全部 OS、实体设备、全部字号或跨设备同步。

新测试只创建自己的合成记录，不读取真实用户记忆正文、token 或验证码。对数据保护的比较可以核对密文哈希与文件数量，不把密文或 Keychain 内容复制到公开报告。视觉验收应检查窄屏、长字段、键盘、大字号、保存按钮、底栏与弹窗位置；图标采用统一 SVG 尺寸、线宽和颜色，不用装饰 Emoji 替代。预览持续展示，不设置自动关闭时限。

## 如何记录结果

每次写清提交或工作区基线、命令、目标设备与系统、环境、退出码、失败数、产物位置和未测范围。出现失败保留首个有效错误与日志，修复后重跑相关用例；不要删掉失败记录，只保留成功截图。历史 Android 生产记录已经证明一次真实账号授权自动返回与 force-stop 后冷启动恢复，设备会话为 24 小时；它不代表连续运行 24 小时或永久登录。iOS 完整真实账户闭环、正式分发、推送与跨网通话仍分别待验收。故障分层方法见[故障定位](https://document.thestarline.cn/app/troubleshooting.md)。
