Skip to content

Testing CI

dxx114514-stack edited this page Oct 2, 2026 · 3 revisions

测试与 CI

命令一览

cd backend
npm test            :: 单元 + 数据库测试(不依赖已启动的服务,104 项)
npm run lint        :: ESLint 静态检查
npm run test:server :: 黑盒测试(需服务已启动,security.test.js 24 项 + reset-login 冒烟脚本)

单元测试(npm test)

11 个测试文件、104 个用例:

文件 覆盖
scorer.test.js 自定义计分脚本解释器(39 项)
compare.test.js 输出比较 text_strict / text_relaxed / real_number(SPJ 用例在 security.test.js)
ratelimit.test.js 限流中间件
plagiarism.test.js 代码查重算法(脚本式,无 it() 断言)
exams.test.js 试卷系统逻辑
exam-import.test.js 试卷 Excel 导入解析(15 项)
exam-program.test.js 试卷内编程题(提交/计分/判题回写,15 项)
exam-leaderboard.test.js 试卷排行榜(时间窗/封榜/排名,8 项)
contests.test.js 比赛/虚拟比赛逻辑
sandbox.test.js 沙箱真实编译(g++);无 g++ 环境自动跳过 3 个用例
init-password.test.js 初始管理员口令策略(随机口令 / NoldOJ_INIT_ADMIN_PASSWORD)
  • 测试隔离:需要数据库的测试自动使用 %TEMP%\NoldOJ-test\ 独立库,不读写生产库 backend/data/NoldOJ.db,测试中断不留脏数据。
  • sandbox.test.js 真实调用 g++ 编译 C++ 并运行(正确执行、超时 TLE 拦截、编译错误诊断),Linux/Windows 均覆盖。

黑盒测试(npm run test:server)

24 项,需服务已启动,并且必须以调试模式启动(否则登录被验证码 403 拦截):

set NoldOJ_CAPTCHA_DEBUG=1
npm start

另一窗口执行 npm run test:server。

  • security.test.js:CSP/CORS/上传伪装/SPJ 逃逸/登录爆破、验证码一次性、注册限流等安全用例;测试从响应探测 CAPTCHA_DEBUG_MODE,不依赖测试进程环境变量。登录凭据可用 ADMIN_USER/ADMIN_PASS 覆盖(默认 admin/admin123,仅本文件读取)。
  • reset-login.test.js:管理员重置密码后登录流程冒烟。凭据硬编码 admin/admin123(不读 ADMIN_USER/ADMIN_PASS);除 admin 登录失败会 exit 1 外,其余步骤失败只打日志、最终 exit 0(无断言,仅作流程走通验证)。

⚠️ NoldOJ_CAPTCHA_DEBUG 与 NoldOJ_INIT_ADMIN_PASSWORD 仅限测试环境,生产/日常运行严禁设置。

ESLint

npm run lint
  • 配置:backend/eslint.config.js(eslint:recommended + globals.node;空 catch 允许、未用变量 _ 前缀豁免)。
  • 存量 77 项问题已清零,并借此修出两处真实运行时缺陷(提交详情 test_groups 未定义、problems.js 未导入 config)。
  • 提交前请保持 npm run lint 零错误。

GitHub Actions(CI)

工作流:.github/workflows/test.yml,push 到 main、任意分支的 PR(pull_request 未加分支过滤)、手动 workflow_dispatch 均触发,两个 job:

Job 内容
lint-and-test npm ci → npm run lint → npm test(104 项)
blackbox 以 NoldOJ_CAPTCHA_DEBUG=1 + NoldOJ_INIT_ADMIN_PASSWORD=admin123 后台启动服务 → curl 健康检查(最多 30 次)→ npm run test:server(24 项)→ if: always() 打印服务日志

CI 为全新 runner,数据库首次初始化会生成随机 admin 口令,因此 blackbox job 显式指定 NoldOJ_INIT_ADMIN_PASSWORD=admin123;该行为在 db.js 中实现,不设置时保持随机口令(生产行为不变)。

本地排查 CI 失败:

gh run list --limit 5
gh run view <run-id> --log-failed

相关文档

Clone this wiki locally