测试与故障排查
本页用于开发验证和运行故障定位。先确定当前使用的服务地址、运行环境和数据库目标,再执行检查。
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 链接、命令路径和当前源码配置是否一致。