1
Testing and Troubleshooting
biss edited this page 2026-07-24 12:00:48 +08:00
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.

测试与故障排查

本页用于开发验证和运行故障定位。先确定当前使用的服务地址、运行环境和数据库目标,再执行检查。

1. 自动化测试

全部测试:

dotnet test .\Eis.slnx

Release 配置:

dotnet test .\Eis.slnx --configuration Release

指定项目:

dotnet test .\tests\Eis.Infrastructure.Tests\Eis.Infrastructure.Tests.csproj

筛选:

dotnet test .\Eis.slnx --filter FullyQualifiedName~DatabaseInitializerTests

测试覆盖:

  • 空库 v20 初始化;
  • 数据库维护安全;
  • 认证状态后端;
  • 密码和 TOTP 历史兼容;
  • 文书防伪;
  • 缓存;
  • 公告内容处理;
  • Excel
  • 地区数据;
  • 成绩统计;
  • 招生公示和迁移能力。

xUnit 使用独立临时 SQLite 数据库,不应连接或修改生产库。

2. 前端验证

生产构建:

Set-Location .\src\Eis.Web\ClientApp
npm ci
npm run build

开发服务器:

npm run dev

检查:

  • 控制台无模块加载错误;
  • /api 请求代理到 4173
  • 直接打开和刷新 Vue 子路由正常;
  • 401 后进入登录流程;
  • 不同角色菜单正确;
  • 移动端布局可操作;
  • wwwroot/vue-app 由构建生成。

项目当前没有单独的前端单元测试脚本,因此前端变更至少要通过 npm run build 和相关页面人工验证。

3. 发布烟测

pwsh.exe -NoLogo -NoProfile -NonInteractive -File .\scripts\smoke-dotnet-native.ps1

脚本会:

  • 发布 Eis.Web
  • 在系统临时目录创建一次性 SQLite 数据库;
  • 使用随机本机端口启动发布物;
  • 检查健康状态、首页和必要静态资源;
  • 使用临时超级管理员登录;
  • 确认未知 API 返回 404
  • 停止进程并清理临时数据。

烟测不会使用仓库 data/exam.sqlite

4. 手工烟测清单

公开页面

  • 首页返回 200
  • 公告列表和详情可用;
  • 未发布内容不可见;
  • 验真码成功和失败状态清楚;
  • 无效 /api/... 返回 JSON 404。

认证

  • 正确密码登录;
  • 错误密码被拒绝;
  • Cookie 为 HttpOnly
  • 登出后受保护接口不可用;
  • TOTP 动态码和恢复码可用;
  • 恢复码只能使用一次;
  • 会话过期后重新登录。

数据范围

  • 班级管理员看不到其他班;
  • 校级管理员看不到其他学校;
  • 招生学校看不到其他学校投档;
  • 考生只能查看本人数据;
  • 手工调用隐藏端点仍被服务端拒绝。

关键流程

  • 批量申领报名号;
  • 首次登录;
  • 资料和报名审批;
  • 缴费确认;
  • 编排预检和正式应用;
  • 成绩导入预览和确认;
  • 成绩发布和复议;
  • 志愿、投档、正式录取;
  • 报到扫描预览和确认;
  • 每轮补录与公开公示。

5. 健康检查解释

/health/live 无法访问

可能原因:

  • 进程未启动;
  • ASPNETCORE_URLS 不是预期地址;
  • 端口被占用;
  • 容器端口未映射;
  • 应用在初始化数据库或认证 Redis 时已经退出。

先查看应用标准输出、容器日志或服务管理器日志。

/health/migration 中缓存为 disabled

没有配置 REDIS_URL,应用使用本机缓存。这在单实例开发环境正常。

缓存为 unavailable

普通 Redis 配置存在但暂时连接失败,应用回退到本机缓存。检查:

  • URL 和 TLS scheme
  • DNS、端口和防火墙;
  • 容器是否错误使用 127.0.0.1
  • Redis 认证;
  • REDIS_CONNECT_TIMEOUT_MS

认证后端为 memory

未配置 Redis 认证状态。单实例可用,但重启会要求重新登录;多实例部署不应使用。

6. 应用启动失败

生产环境缺少 TOTP 密钥

错误含义:原生认证已启用,TOTP_ENCRYPTION_KEY 少于 32 字符。

处理:通过秘密管理注入新的稳定密钥,不要把密钥写进仓库。

生产环境缺少文书密钥

DOCUMENT_VERIFICATION_SECRET 必须至少 32 字符,并与 TOTP 密钥不同。

默认尝试连接 MySQL

Production 下未设置 DATABASE_CLIENT 时默认使用 MySQL。若这是单机 SQLite 部署,显式设置:

DATABASE_CLIENT=sqlite
SQLITE_PATH=/明确的持久化路径/exam.sqlite

MySQL 配置不完整

设置 DATABASE_URL,或完整设置主机、用户和数据库名。检查 .env 是否位于应用根目录,以及部署平台是否注入了空或错误同名变量。

Redis 认证状态与缓存使用同一 DB

设置不同的 REDIS_SESSION_DB,或使用独立 REDIS_SESSION_URL

数据库结构版本过低

当前要求 v20。停止应用,备份完整数据库并执行明确升级流程。不要直接 seed/reset 生产库。

7. 前端页面问题

4173 页面显示旧版本

后端托管的是上次 Vite 构建产物。重新运行:

Set-Location .\src\Eis.Web\ClientApp
npm run build

不要手工修改 wwwroot/vue-app

5173 API 请求失败

确认:

  • ASP.NET Core 正在 127.0.0.1:4173 运行;
  • Vite 使用仓库中的 vite.config.js
  • 请求路径以 /api/health/js 开头;
  • 没有另一个服务占用 4173

刷新子页面 404

开发时应访问 Vite 的 5173 或 ASP.NET Core 的 4173。生产反向代理不要自行把 /api/* 改写为 SPA 首页;其他前端路由应转发给 ASP.NET Core 的资源回退逻辑。

登录后回到首页

可能是:

  • 会话请求失败;
  • 用户角色与目标路由不匹配;
  • 考生仍需修改初始密码或完善资料;
  • Cookie 未随请求发送;
  • 多实例未共享 Redis Session。

打开浏览器网络面板检查 /api/auth/me,不要只反复刷新。

8. 数据库问题

SQLite 数据“丢失”

先确认实际绝对路径:

  • 仓库启动:通常是 data/exam.sqlite
  • 发布目录:相对路径可能按应用根目录解析;
  • Docker/app/data/exam.sqlite
  • 测试:系统临时目录中的一次性文件。

最常见原因是启动时使用了另一个工作目录或环境变量,创建了新的空 SQLite 文件。

Docker 重建后数据不见

检查是否执行过:

docker compose down --volumes

以及 Compose 是否仍挂载 exam-information-data:/app/data

MySQL 外部修改暂时看不到

应用会复用只读快照,外部直写默认最长 30 秒后可见。应用自身写入会立即失效。不要把直接改数据库作为正常业务操作。

工具拒绝操作

这是安全边界。按数据库与数据工具确认目标、dry-run、备份和 --confirm-target,不要先使用 --force 试错。

9. Redis 和缓存问题

写入后公开页面仍旧

确认写操作是否触发正确命名空间失效。公开公告、招生公示和可见性变更应失效 public;成绩录入、发布、导入、归档和复议应失效 results

多实例随机掉登录

各实例可能使用本机内存会话或连接不同 Redis。确认:

  • 所有实例 REDIS_SESSION_URL/DB 相同;
  • REDIS_SESSION_PREFIX 相同;
  • TOTP 加密密钥相同且稳定;
  • 实例没有因配置缺失退回内存。

Redis Cluster 报逻辑 DB 错误

Cluster 常只支持 DB 0。让普通缓存和认证状态使用两个独立 Redis 端点,不要依赖 DB 0/1 分隔。

10. Excel 导入问题

返回具体行错误

按行修复后重新上传。常见原因:

  • 必填列空;
  • 标识 ID 被改动;
  • 日期或数字格式不合法;
  • 目标学校、班级、考试不存在;
  • 重复唯一值;
  • 数据超出当前管理员范围;
  • 使用了旧版本模板。

预览成功但数据库没变化

预览阶段本来就不写数据库。需要在页面核对摘要后执行明确确认。

部分数据成功、部分失败

关键批量写入设计为原子事务。若页面显示部分变化,先确认是否查看了旧缓存、多个批次或之前已有的数据,再检查服务日志和审计记录。

11. 成绩与录取问题

管理员已录入但考生看不到

录入和发布是不同状态。确认整场或对应成绩是否正式发布。

无法修改成绩

检查:

  • 考试是否归档;
  • 当前账号是否超级管理员;
  • 是否处于导入预览阶段;
  • 复议流程是否允许当前动作。

考生无法填志愿

检查:

  • 考试是否启用招生;
  • 成绩是否全部发布;
  • 是否在填报阶段;
  • 是否达到提交上限;
  • 指标资格和计划是否已经生效。

无法补录

检查上一轮报到是否已由所有相关学校提交并完成审批,缺额是否存在,以及当前录取阶段是否允许启动下一轮。

12. 日志与问题报告

报告问题时提供:

  • 应用版本或 Git 提交;
  • 操作系统和部署方式;
  • .NET、Node、浏览器版本;
  • ASPNETCORE_ENVIRONMENT
  • 数据库类型和结构版本,不提供密码;
  • Redis 是否配置及状态,不提供完整凭据;
  • 复现步骤;
  • 预期与实际结果;
  • 浏览器控制台和网络状态;
  • 服务端异常前后日志;
  • 是否能在临时测试库复现。

不要在问题报告中粘贴:

  • .env 全文;
  • 数据库密码;
  • TOTP 密钥;
  • 恢复码;
  • Session Cookie
  • 完整证件号、手机号或未脱敏考生数据。

13. 提交前最终检查

dotnet test .\Eis.slnx
pwsh.exe -NoLogo -NoProfile -NonInteractive -File .\scripts\publish.ps1
pwsh.exe -NoLogo -NoProfile -NonInteractive -File .\scripts\smoke-dotnet-native.ps1
git diff --check
git status --short

如果改动只涉及 Wiki,至少检查 Markdown 链接、命令路径和当前源码配置是否一致。