待办清单

db-testing 与 app-testing 落地后剩下的事:收尾、待拍板的决策、存量迁移,以及目录布局采纳后的实施。勾选状态只保存在当前浏览器里。

建议顺序

  1. 收尾已完成:#535、#536、#545 都已合并,每晚任务在 PostgreSQL 和 MySQL 上都已转绿(A1–A4);B7 随 #546 于 10-07 合并。
  2. 决策已定:D1–D5 于 10-06 定下,结论写在第二节。
  3. 先做:C1(布局规则与生成器,后面的迁移都按它放文件)、B2(answerApi 改为失败)。
  4. 接着:C2 三个模板一起迁移;B8 定下测试库怎么准备,再做 B9。
  5. 可以并行:B3 插件模式(它挡着 B4)、B1 client 测试迁移、B5;B1、B4 迁出的文件直接按新布局放。
  6. 随时可做:A7–A11 这些零散问题,A5 单独排期。数据库层的 #545 遗留里,E1 最值得做,其余优先级低。

一、收尾

A1–A4、A6 已完成,每晚任务已转绿。A5 未修;A7–A11 是这两天排查时新发现的问题。

A1

合并 #535

页面测试改用 app-testing/client:全局 Skill 的示例改用 renderWithApp,不再 mock;create-plugin 给有 client 代码的插件加上页面测试依赖和 jsdom 的 vitest.config.ts。合并提交 e23c66d4。

已完成
A2

合并 #536

notification 示例对非法 task id 返回 403,大写 id 在所有方言上都能查到。修好 10-05 每晚 PostgreSQL 的唯一失败。合并提交 b0a59544。

已完成
A3

修 MySQL 每晚失败:合并 #545

openapi-repository.test.ts:312 在 MySQL 上多出 status。根因在 inspector:MySQL 把字面量默认值报成裸值,读回后丢失。db-mysql 和 db-oceanbase 已修,db-testkit 新增 builder/string-defaults 契约。10-06 合并,合并提交 8a6a2961;评审后没在 PR 里做的事记在 PR #545 遗留问题,要动手的几项列在下面第五节 E1–E4。

已完成
A4

确认每晚 Database tests 两个方言都转绿

10-06 22:19 UTC 的每晚运行(8a6a2961,#545 合并后第一次)PostgreSQL 和 MySQL 都通过。之后每晚任务不绿,就是新引入的问题。

已完成
A5

Oracle 修改 CLOB 列(ORA-22859)

Knex 的 MODIFY 带类型,Oracle 拒绝。修好后去掉 packages/libs/db-oracle/tests/integration/adapter.ts 里的 textAlterations: 'unsupported'。改动在 @nocobase/db 层,建议单独排期。

待做
A6

全局 Skill 的页面测试示例改用 renderWithApp

已随 #535 合并。示例照原样在 app-plugin-hub 里跑过,3/3 通过。

已完成
A7

@nocobase/db:Repository 校验 uuid 过滤条件时接受任意字符串

非法 uuid 在 PostgreSQL、Kingbase、MSSQL 上仍会让其他 uuid 查询返回 500。#536 只修了 notification-example 一处。

根因待做
A8

articles 迁移测试的两处覆盖

content 默认值改为经 Repository 插入后在每个方言上断言;期望失败的插入只省略 title。来自 #536 的 review。

小
A9

MissingTranslationError 报错的命名空间不对

i18next 传给 missingKeyHandler 的是回退链里最后一个命名空间,报错显示 @nocobase/i18n,而不是页面实际读的那个(packages/libs/i18n/src/testing/runtime.ts)。

小
A10

SQLite 上整数默认值读回成字符串

integer('quantity').defaultTo(0) 在 SQLite 上读回 '0',其他方言是 0。#545 的契约因此只覆盖字符串和 enum。

待做
A11

本地跑不起 OceanBase 集成套件

Docker 默认 nofile=1024,OceanBase 要求 ≥ 20000。packages/libs/db-oceanbase/docker-compose.yml 加 ulimits: nofile: 65536 即可;CI 不受影响。同一件事也记在 PR #545 遗留问题第 7 条。

小

二、决策(10-06 已定)

五项都已定下,结论落到 B2、B7、B8、B9 和 C 组。

D1

采纳测试目录布局

10-06 已定:采纳。按源码目录分 tests/client|server|database|cli|project,用 Vitest projects 决定环境;按 C1–C3 实施。

已定
D2

answerApi 的 handler 返回 undefined 时让请求失败

10-06 已定:改代码。与原设计一致,漏写的分支会立刻暴露。实施见 B2。

已定
D3

E2E 的测试库由启动应用的一方准备

10-06 已定。Playwright 不启动应用,只访问 APP_URL。本地开发用自己的 pnpm dev 应用;每晚任务在启动构建产物前用 createTestAppConfig() 分配测试库,先验证它能否在普通 Node 脚本里用。实施见 B8。

已定
D4

E2E 进每晚任务;hub 暂不加 Playwright

10-06 已定。default、examples 的 E2E 进每晚任务,放一个通用冒烟样例;hub 暂不加,在 PR 里说明。实施见 B9。

已定
D5

tests/playwright/ 随模板发布

10-06 已定:发布,原来的 ai-local-server.test.ts 删除;通用冒烟样例随 B9 加入。

已定

三、存量迁移与缺口

B3 挡着 B4,B6 要等 B1 和 B4 迁完,B9 要等 B7 和 B8。

B1

client 测试迁移:59 个文件改用 renderWithApp

19 个包从整层 vi.mock('@nocobase/app-client') 迁走。先迁小包;三个模板的 page-harness.test.tsx 与 app-skills 前端测试参考放一个 PR;hub 的 client-pages.test.tsx 最后。量大的:ai-employee 12、app-template-examples 9、repository-example 7。

可开始
B2

answerApi 遇到 undefined 时让请求失败

handler 没有返回值时抛出,让发起请求的调用失败。逐个确认现有用法(hub 的 api-keys-page.test.tsx、全局 Skill 示例、app-testing 自己的测试),同步快速开始和 Skill 的说明。@nocobase/app-testing 带 changeset。

小可开始
B3

createAppTest 插件模式

只给插件列表、由 app-testing 提供最小应用。待定:插件配置的来源,倾向由各插件在 ./testing 导出默认测试配置(如 testAuthConfig())。先用 authz-default-access 试点。

挡 B4可开始
B4

server 测试迁移:74 个文件改用 createAppTest

27 个包手工搭 ServiceContainer 的测试,包括 departments-example/tests/helpers.ts(396 行);workflow 和 hub 最后。

等 B3
B5

describeMigration 支持 plugins: [otherPlugin]

取代用相对路径引用别的插件迁移目录。

可开始
B6

收紧检查

禁止插件测试手工搭 ServiceContainer、整层 mock @nocobase/app-client。

等 B1、B4
B7

Playwright 测试迁到 tests/playwright/

10-07 随 #546 合并(6e30789a)。default、examples 两个模板一起改:Vitest 排除 tests/playwright/**(hub 为了三个模板的 vitest.config.ts 一致也加了),改 testDir 和 tsconfig.node.json;删除 ai-local-server.test.ts;模板 README 和 app-skills 里写 e2e/ 的地方一起改。tests/playwright/ 暂时为空,ESLint 的 Node 环境随 B9 按实际 lint 结果决定。

已完成
B8

每晚任务给被测应用准备测试库

启动构建产物前,用 createTestAppConfig() 按 NOCOBASE_TEST_DB_DIALECT 分配测试库,把配置交给 APP_CONFIG_FILE。app-testing/server 会加载 vitest,在普通 Node 脚本里引用可能失败,先验证;失败就加一个不依赖 vitest 的入口(如 ./config)。

可开始
B9

通用 E2E 冒烟样例和每晚 E2E 任务

default、examples 的 tests/playwright/ 各放一个冒烟测试(读 APP_URL:/api/healthz 通过、首页能打开),随模板发布。每晚任务:pnpm build,按 B8 准备测试库并启动构建产物,等 /api/healthz 通过,装 Chromium,带上 APP_URL 跑 test:e2e。hub 暂不加 Playwright,在 PR 里说明。

等 B7、B8

四、目录布局实施(D1 已采纳)

分三个 PR,按顺序来。

C1

PR 1:规则与生成器

#551:AGENTS.md 的 Test Layout;create-plugin 的样板测试按目录放并改名(如 tests/database/migrations.test.ts、tests/cli/info.test.ts),只有 server/CLI 的插件也生成只含 node 项目的 vitest.config.ts(顺带拿到 30 秒的共享超时),同步 template/AGENTS.md 和生成器测试,带 changeset。生成的两个插件在仓库里实跑 check 通过。

拆出去的两项:app-skills 的 references/testing.md 描述的是应用,模板到 C2 才搬,随 C2 一起改;skills/nocobase-plugin-development 里 references/database.md 对 tests/database.test.ts 的引用,等 @nocobase/create-plugin 发版后单独开 PR。

#551 待合并
C2

PR 2:三个模板一起迁移

按映射表搬 149 个测试文件;vitest.config.ts 改 projects、删环境注释;app-skills 的 references/testing.md 与前端测试参考改成新布局;同步 check-db-test-portability.mjs 的 EXEMPT 路径;各跑一次 check。

等 C1
C3

PR 3:插件和示例逐步迁移

先把 authorization-example/tests/e2e/ 拆开:practice.test.tsx 是 jsdom 测试,进 tests/client/,其余三个进 tests/server/;其余碰到哪个改哪个,可与 B1、B4 合并做。

等 C1

五、PR #545 遗留(数据库层)

来自 PR #545 遗留问题。遗留第 7 条(本地 OceanBase 的 open files)就是 A11,不再重复列。第 5、6 条是已接受的取舍和 OceanBase 自身限制,只备查:视图上字面量 'uuid()' 读不出默认值;带负数 time 默认值的表不能建视图。

E1

db-mysql 与 db-oceanbase 的默认值判断逻辑抽到共享位置

两边各有一份字符类型列表、补引号函数和时间类型判断,需要同步维护。这次的缺陷就是两个 inspector 各自写错。跨包重构,单独开 PR。遗留第 4 条。

最值得做待做
E2

MariaDB 识别不只依赖 version() 里的 -MariaDB

版本字符串被改写时(--version 选项、代理、部分托管服务)会走 MySQL 路径,默认值被多加一层引号,无默认值的可空 varchar 读出字符串 "NULL"。可改查 @@version_comment,或按默认值的报告形式判断。场景少见。遗留第 1 条。

少见待做
E3

version() 改为每个连接读一次

现在每列查一次。缓存到 inspector 上后,可以去掉 server_version 字段,mysqlDefaultLiteral 的签名也随之简化。遗留第 2 条。

简化,低优先级
E4

OceanBase 每张表多一次串行 SHOW CREATE TABLE

解析集合时(应用启动、OpenAPI 文档重建)每张表多一次往返,且和 constraints、indexes、checks 查询串行。可以并行,或按表缓存。先测量实际影响再决定。遗留第 3 条。

先测量

附:新会话交接模板

开新会话跟进某一项时,把下面这段贴给它,再补上那一项的现象和步骤。方案文档是共同的背景。

任务:完成 NocoBase 3 测试基础设施待办 <编号>:<标题>。

背景:方案 https://pages.chenos.dev/view.html?p=/nocobase/testing-infrastructure.md(“落地路线”一节),
待办 https://pages.chenos.dev/nocobase/testing/todo.html。
本地文件在 /home/chenos/NocoBase/pages/nocobase/ 下,它是私有仓库 chenos/pages,改完要提交并推送。

要求:
- 按仓库 AGENTS.md 开 fix/<name> 或 feat/<name> 分支和 PR,带 changeset,提交信息和 PR 描述不加 AI 署名。
- 改了 packages/libs/db 或 db-<dialect>,先读 packages/libs/db-testkit/docs/integration-testing.md。
- 方言测试一次只跑一个,不要并行或挂后台。
- PR 开出来后告诉我链接,先别合并;完成后在方案的落地路线和这份待办里更新状态。