测试与 CI
测试与 CI
Section titled “测试与 CI”CI 由 GitHub Actions 运行,主要包含静态检查、类型检查、测试、构建、自动格式修复和文档部署。CircleCI 看门狗(.circleci/)镜像检查管线:当 GitHub Actions 对某个 commit 全部失败时(例如 GitHub 平台故障),CircleCI 会自动接管全量静态分析、多数据库测试矩阵与文档检查。构建、发布与部署仍仅由 GitHub Actions 负责。仓库本地自动化以 Taskfile.yml 为主入口。
Taskfile 主入口
Section titled “Taskfile 主入口”task checktask testtask buildtask citask check 覆盖 Ruff、Ruff format check、Markdown lint、Turbo lint、Pyright、ty 和 Turbo type check。task test 覆盖根 pytest、lingc-cli pytest 和 docs Vitest。task ci 会按顺序运行 check、test 和 build。
Python / code 聚焦检查
Section titled “Python / code 聚焦检查”uv run -m ruff check . --output-format=githubuv run -m ruff format --check .uv run -m pyrightuv run -m ty check --output-format githubuv run -m pytest如果只改了某个模块,可以先跑相关测试文件,再按需要扩大范围。
运行时冒烟测试
Section titled “运行时冒烟测试”修改钩子、适配器或启动流程后,仅静态检查不够。应执行下方三阶段真实启动冒烟测试,以捕获前向引用签名错误、导入顺序问题、schema 写入泄漏和 CLI 回归问题。
阶段 1 — 开发环境
Section titled “阶段 1 — 开发环境”通过 ENVIRONMENT=dev 选择开发环境,让 NoneBot2 载入 .env + .env.dev 并启动机器人:
uvx --from nb-cli nb.exe run需观察到 Application startup complete. 并至少完成一个事件周期。如需限制运行时间,可用 timeout 包裹命令(例如 timeout 10s);超时杀死进程时返回退出码 124,属于预期行为。若进程在启动完成前退出,请增加超时时间。
阶段 2 — 生产环境(清理 localstore)
Section titled “阶段 2 — 生产环境(清理 localstore)”验证机器人能从干净的 localstore 状态启动,证明启动过程不写 schema 且能在全新部署下存活。
-
删除项目下所有 localstore 管理的目录:
Terminal window rm -rf config/nonebot_plugin_lingchu_bot/ \data/nonebot_plugin_lingchu_bot/ \data/nonebot_plugin_orm/ \cache/nonebot_plugin_lingchu_bot/这四个路径由
nonebot_plugin_localstore解析(在.env中设置LOCALSTORE_USE_CWD=true)。仓库根目录的config/、data/、cache/是本地开发产物,可丢弃。 -
设置
ENVIRONMENT=prod让 NoneBot2 载入.env+.env.prod并启动机器人:Terminal window ENVIRONMENT=prod uvx --from nb-cli nb.exe run -
验收标准:进程到达
Application startup complete.且无硬错误。LLM configuration missing or invalid; AI is unavailable告警可接受;任何 traceback、schema 写入或迁移副作用都是硬错误。
CI/CD 冒烟测试
Section titled “CI/CD 冒烟测试”除手动的运行时冒烟测试外,CI/CD 在 build job 之后、部署之前运行自动化的冒烟测试阶段,验证构建产物镜像能够启动 NoneBot、注册运行时钩子、初始化核心服务并生成 JUnit 报告。
阶段位置与依赖关系
Section titled “阶段位置与依赖关系”smoke-test在👷 CI-builds的buildjob 之后运行,仅在构建成功时触发。docs-smoke在📚 Docs Deploy的 docs build 之后运行,仅在文档构建成功时触发。
任意冒烟检查失败时,工作流会立即终止,不会进入部署环节。job 会上传产物 smoke-test-results.xml,方便查看失败断言与 traceback。
可以使用以下命令在本地执行同样的冒烟检查:
# 使用 Docker Compose 构建并运行冒烟测试容器task smoke
# 以 CI 模式运行并输出 JUnit XML 报告task ci:smoke
# 等效的原始 Docker Compose 命令docker compose --profile smoke up --build --abort-on-container-exit smoke-test项目通过 SQLALCHEMY_DATABASE_URL 环境变量支持 4 个数据库后端测试,遵循 NoneBot 数据库测试最佳实践。
本地多数据库测试
Section titled “本地多数据库测试”默认使用 SQLite 进行测试。要在 PostgreSQL / MySQL / MariaDB 上本地测试:
- 安装数据库驱动(已在
test依赖组中):
uv sync --all-groups-
启动数据库服务器(通过 Docker 或本地安装)。
-
设置
SQLALCHEMY_DATABASE_URL环境变量并运行测试:
# PostgreSQLexport SQLALCHEMY_DATABASE_URL="postgresql+psycopg://postgres:postgres@localhost:5432/postgres"uv run -m pytest
# MySQLexport SQLALCHEMY_DATABASE_URL="mysql+aiomysql://mysql:mysql@localhost:3306/mymysql"uv run -m pytest
# MariaDB(使用 mysql+aiomysql,SQLAlchemy 通过 VERSION() 自动检测 MariaDB)export SQLALCHEMY_DATABASE_URL="mysql+aiomysql://mariadb:mariadb@localhost:3306/mymariadb"uv run -m pytest- 测试前运行迁移:
uv run nb orm upgradeCI 多数据库矩阵
Section titled “CI 多数据库矩阵”CI 跨 4 个数据库引擎跑 8 个任务,覆盖 LTS 与最新版:
- SQLite(默认,无需额外服务;版本由 Python
sqlite3/aiosqlite决定) - PostgreSQL 16(
postgres:16-alpine,支持至 2028-11)与 PostgreSQL 18(postgres:18-alpine,最新版) - MySQL 8.4 LTS(
mysql:8.4,支持至约 2032)与 MySQL 9.7 LTS(mysql:9.7,支持至约 2034) - MariaDB 11.4 LTS(
mariadb:11.4,支持至 2029-05)与 MariaDB 11.8 LTS(mariadb:11.8,支持至 2028-06)
每个矩阵条目携带 engine + image 字段;服务容器通过 ${{ matrix.db.engine == '<engine>' && matrix.db.image || '' }} 选择镜像,使同一引擎的多个版本可在一个矩阵中共存。fail-fast: false 策略确保即使一个数据库失败,所有数据库仍会被测试。
Docs / frontend 聚焦检查
Section titled “Docs / frontend 聚焦检查”文档站使用 pnpm、Astro Starlight、Vitest、Playwright、ESLint 和 Turbo:
pnpm --filter docs lintpnpm --filter docs testpnpm --filter docs run test:e2e:hookpnpm --filter docs run test:e2epnpm --filter docs check-typespnpm turbo run build --filter=docsVitest 覆盖 apps/docs/src/__tests__ 下的组件和库行为。Playwright 测试放在 apps/docs/e2e,覆盖浏览器级文档导航。本地 hook 在 docs 变更时运行 Chromium 冒烟命令(test:e2e:hook);CI 运行全部配置的 Playwright 浏览器项目,并上传 HTML report 与 trace 产物。
编写 Playwright 测试时优先使用 role/text locator 和 toBeVisible()、toHaveAttribute() 等 web-first assertion。除非变更明确需要,否则不要使用 sleep、截图断言或宽泛的视觉检查。
Markdown 检查
Section titled “Markdown 检查”pnpm exec markdownlint-cli2glob 与 ignore 列表由仓库根目录的 .markdownlint-cli2.jsonc 统一配置,无需传入路径参数。
修改可翻译字符串后运行:
task i18n如果只修改文档中的 i18n 说明,不需要重新生成 gettext catalog。
CI 工作流
Section titled “CI 工作流”🧪 Python CI:共享的detect-changes复合 action(.github/actions/detect-changes)按文件类型输出布尔标志(python/markdown/frontend/frontend-code/frontend-style/frontend-content/frontend-tsx),然后条件触发 Static Analysis(Python 或 markdown 变更时,通过task ci:static)和 Tests & Type Check(Python 变更时,跨多数据库矩阵)。Auto Fix & Format 在main/devpush 时运行。条件与 pre-commit v3 的NEEDS_LINT/NEEDS_TYPE_CHECK/NEEDS_DOCS_TEST对齐。🧪 Frontend CI:使用同一个detect-changesaction,然后条件触发 Docs Check — ESLint 在代码/样式变更时,check-types 在任意前端变更时,link validation 在内容变更时,Vitest 在代码/内容变更时。🎭 Playwright:针对apps/docs和packages变更运行 docs E2E 测试,安装浏览器依赖,并上传 Playwright report 产物。👷 CI-builds:运行task ci:build;versioned-build作业改为每日定时(北京时间 02:00,UTC0 18 * * *)——从最新 tag 同步版本、bump dev version、写回core_version、构建、归档产物、生成 provenance 并提交 tag。📚 Docs Deploy:docs 相关路径 push 到main或dev时,运行 pnpm/turbo lint、docs test 和 docs build,然后部署 GitHub Pages。
CI 失败处理
Section titled “CI 失败处理”打开失败 job 日志,定位命令、规则和行号。修复时只改导致失败的最小范围,并重新运行对应本地命令。