Payload 社区 Issue 复现指南:用 test/_community 测试套件构建最小可复现环境
Payload 社区 Issue 复现指南用 test/_community 测试套件构建最小可复现环境【免费下载链接】payloadPayload is the open-source, fullstack Next.js framework, giving you instant backend superpowers. Get a full TypeScript backend and admin panel instantly. Use Payload as a headless CMS or for building powerful applications.项目地址: https://gitcode.com/GitHub_Trending/pa/payload本文基于 Payload 仓库根目录的 ISSUE_GUIDE.md 展开讲清楚向 Payload 提交 Issue 的标准流程如何在test/_community目录中用最小配置重建问题现场、如何用pnpm dev _community启动该套件的 Admin UI 手动复现、以及如何通过 vitest 集成测试int与 Playwright 端到端测试e2e把复现固化为可执行验证。读完后你将能够独立完成“Fork → 最小复现 → 可选测试固化 → 提交 Issue”的完整链路并理解每个测试文件、npm 脚本背后的源码级支撑。一、核心思路用最小配置隔离问题Payload 仓库对 Issue 复现的要求非常明确不要在 Issue 里贴一大段业务代码而是把问题还原成尽可能少的 collection、global 和 field。ISSUE_GUIDE.md 给出的标准流程只有三步Fork 这个仓库向test/_community目录中添加必要的 collections / globals / fields以复现你遇到的问题创建 Issue并在其中附上你 Fork 仓库的链接。文档中特别强调了一条原则原文加粗部分目标是通过减少向test/_community添加的 fields / collections 数量来隔离问题。这个文件夹不是让你把整个项目拷贝进去的地方而是用最小配置重新构建你所经历问题的地方。之所以能这样工作是因为 Payload 的测试架构允许“每个测试目录携带自己独立的一套 Payload 配置”测试框架可以针对该配置单独启动一个完整的 Payload 实例数据库、Admin UI、API 一应俱全。test/_community就是官方留给社区的、开箱即用的这个“空壳”。二、test/_community 的文件结构与各文件职责ISSUE_GUIDE.md 给出的目录骨架如下. ├── config.ts ├── int.spec.ts ├── e2e.spec.ts └── payload-types.ts各文件的职责与约束config.ts—— 这套测试用的细粒度granularPayload 配置应当尽量轻。文档建议参考test/下其他既有配置作为示例。int.spec.ts可选—— 由 vitest 执行的集成测试文件。任何测试文件的文件名必须以*int.spec.ts结尾否则不会被 int 项目收录。e2e.spec.ts可选—— 端到端测试文件基于上面的 config 加载 Admin UI然后运行 Playwright 测试。payload-types.ts—— 由config.ts生成的类型文件。生成命令是pnpm dev:generate-types _community该脚本定义在根 package.json 中指向test/generateTypes.ts。当前仓库中 test/_community 目录的实际内容比骨架略多还包含schema.graphql、tsconfig.json、tsconfig.eslint.json、types.d.ts以及collections/Posts、collections/Media、globals/Menu等示例 collection/global这些都是供你直接参照修改的示例配置。2.1 config.ts轻量配置的写法以仓库现成的 test/_community/config.ts 为例import { buildConfigWithDefaults } from ../buildConfigWithDefaults.js import { devUser } from ../credentials.js import { MediaCollection } from ./collections/Media/index.js import { PostsCollection, postsSlug } from ./collections/Posts/index.js import { MenuGlobal } from ./globals/Menu/index.js export default buildConfigWithDefaults({ suite: _community, config: { // ...extend config here collections: [PostsCollection, MediaCollection], editor: lexicalEditor({}), globals: [ // ...add more globals here MenuGlobal, ], typescript: { outputFile: path.resolve(dirname, payload-types.ts), }, }, seed: async (payload) { await payload.create({ collection: users, data: { email: devUser.email, password: devUser.password }, }) await payload.create({ collection: postsSlug, data: { title: example post }, }) }, })几个值得注意的点均来自 test/buildConfigWithDefaults.ts 的源码你只需要传入增量配置buildConfigWithDefaults会替你补齐数据库适配器、Lexical 编辑器、secret: TEST_SECRET、telemetry: false、测试邮箱适配器等默认项并在最后调用buildConfig完成配置卫生化sanitized config。该工具函数会自动注入两个关键 endpointlocalAPIEndpoint和createReInitEndpoint。后者提供/api/re-initialize端点供 dev 流程“清库 重新 seed”见下文 3.1 节。当config.admin.autoLogin未显式设置时默认写入{ email: devpayloadcms.com }即 Admin 面板免登录可用环境变量PAYLOAD_PUBLIC_DISABLE_AUTO_LOGINtrue关闭。seed回调定义的是每次初始化时灌入的示例数据示例中创建了一个管理员用户和一条example poste2e 示例测试断言的正是这条数据。2.2 为什么要这样拆分目录ISSUE_GUIDE.md 指出把测试目录这样拆分有两个目的降低创建测试的摩擦以及能够用该特定配置独立启动 Payload。因此你的起点就是修改test/_community里的文件——而不是在别处新建一套体系。三、启动该套件的 Admin UIpnpm dev _community要手动复现问题文档给出的命令是# This command will start up Payload using your config # NOTE: it will wipe the test database on restart pnpm dev _community注意文档中的警告重启会清空测试数据库。这不是随口一提——可以从根 package.json 与 test/dev.ts 的源码中得到印证pnpm dev实际执行tsx ./test/dev.ts并把第一个位置参数作为测试套件名缺省即_community例如pnpm dev _community、pnpm dev fields。dev.ts会用minimist解析参数并校验该目录是否存在不存在时直接报错退出见 test/dev.ts。默认启用 TurbopackNext.js 框架下--no-turbo可关闭--prod-server则改为对打包后的 dist 产物启动真实生产服务器。启动前会执行assertDbReachable检查数据库可达与runInit生成数据库 schema 等初始化步骤。关于“清库”test/dev.ts 中PAYLOAD_DROP_DATABASE除非显式设为false否则一律为true随后若未传--seedfalsedev 脚本会向运行中的服务发起POST /api/re-initialize触发清库 seed见 test/dev.ts。所以每次重启后你看到的是“干净库 seed 数据”的确定状态——这对复现是特性而非缺陷。四、运行集成测试Payload API 测试ISSUE_GUIDE.md 明确指出Issue 不强制附带失败的测试——带上 Fork 仓库的复现步骤目前已经足够。但如果想更深一步仓库提供了两种运行 int 测试的方式4.1 精细运行单个调试在 VS Code 中安装 Vitest Plugin 后可以在侧边栏逐条运行测试点击debug按钮会以调试模式运行该测试允许打断点单步排查。4.2 命令行批量运行运行test/_community/int.spec.ts中全部 int 测试pnpm test:int _community从 vitest.config.ts 可以看到 int 项目的具体约束这解释了文档中几条规则从何而来include: [test/**/*int.spec.ts]——文件名必须以*int.spec.ts结尾才会被收集与文档要求一致fileParallelism: false——测试文件串行执行因为每个套件要独占一个测试数据库hookTimeout: 90000、testTimeout: 90000——初始化 Payload 实例较慢单测试超时给到 90 秒setupFiles: [./test/vitest.setup.ts]提供全局测试环境。4.3 int.spec.ts 的模板写法现成的 test/_community/int.spec.ts 展示了标准骨架test.suite({ config: ./config.ts })(_Community Tests, () { test.beforeEach(async ({ restClient }) { // 每次测试前登录 /users/login 获取 JWT token const data await restClient.POST(/users/login, { ... }).then((res) res.json()) token data.token }) test(local API example, async ({ payload }) { const newPost await payload.create({ collection: postsSlug, data: { title: LOCAL API EXAMPLE } }) expect(newPost.title).toEqual(LOCAL API EXAMPLE) }) test(rest API example, async ({ restClient }) { const data await restClient .POST(/${postsSlug}, { body: ..., headers: { Authorization: JWT ${token} } }) .then((res) res.json()) expect(data.doc.title).toEqual(REST API EXAMPLE) }) })要点test.suite({ config: ./config.ts })声明本文件使用本目录的 config 来启动一套独立的 Payload模板同时演示了两条 API 通路payload.*Local API进程内调用与restClientREST API需携带Authorization: JWT token头beforeEach中通过 REST 登录拿 token 的模式正是你在复现权限、字段、hook 相关 bug 时应该沿用的基线。五、运行 E2E 测试Admin Panel UI 测试E2E 测试面向 Admin UI。文档建议的最低成本做法是安装 VS Code 扩展Playwright Test for VSCode与Playwright Runner然后在侧边栏 testing 面板中钻取到目标文件即test/_community/e2e.spec.ts逐条运行。从 test/playwright.config.ts 可以看到 e2e 侧的收集规则testMatch: [*e2e.spec.ts, *perf.spec.ts]、workers: 16且导出TEST_TIMEOUT_LONG本地 60 秒CI 下乘以 4供各 e2e 文件在beforeAll中设置超时。现成的 test/_community/e2e.spec.ts 演示了完整生命周期test.describe(Community, () { test.beforeAll(async ({ browser }, testInfo) { testInfo.setTimeout(TEST_TIMEOUT_LONG) // 以本目录 config 启动 Payload 并拿到 serverURL const { payload, serverURL } await initPayloadE2ENoConfig({ dirname }) url new AdminUrlUtil(serverURL, posts) const context await browser.newContext() ;({ page } await initPage({ context, serverURL })) }) test(example test, async () { await page.goto(url.list) const textCell page.locator(.row-1 .cell-title) await expect(textCell).toHaveText(example post) }) })这条链路把 Admin UI 真实加载起来并断言列表页第一行标题是 seed 出来的example post——与 test/_community/config.ts 中seed灌入的数据相互印证。复现 UI 类问题时你只需在此骨架上替换定位器与断言。六、登录凭据与 autoLogin 说明文档最后一条 Notes 提醒建议把测试凭据加入浏览器自动填充针对localhost:3000/admin因为每次 nodemon 重启后都可能要重新登录。默认凭据为邮箱devpayloadcms.com、密码test。这些值在 test/credentials.ts 中有唯一定义export const devUser { email: devpayloadcms.com, password: test, roles: [admin], } export const regularUser { email: userpayloadcms.com, password: test2, roles: [user], }注意区分两层机制buildConfigWithDefaults的admin.autoLogin让 Admin 面板免密直接进入可关闭而devUser/regularUser是 seed 时真实创建的用户账户用于 REST 登录int 测试的beforeEach或手动登录场景。复现权限类问题roles、access control时用regularUser制造“非管理员”身份是常用手段。七、操作清单小结目的操作手动复现问题修改 test/_community 内配置与 collection然后pnpm dev _community重启会清库重新生成类型pnpm dev:generate-types _community运行本套件 int 测试pnpm test:int _community或在 VS Code 中用 Vitest Plugin 单测调试运行本套件 e2e 测试在 VS Code 中用 Playwright 扩展运行test/_community/e2e.spec.ts提交 IssueFork 仓库 → 在test/_community中最小化复现 → Issue 中附 Fork 链接登录凭据devpayloadcms.com/test见 test/credentials.ts整套机制的设计意图是让社区贡献者无需理解 Payload 庞大的测试基建就能用“一个目录 最小配置 两条 spec 模板”把一个难以描述的 bug 变成可一键启动、可一键验证的复现环境——这正是 ISSUE_GUIDE.md 希望传达给每一位报告者的工作方式。【免费下载链接】payloadPayload is the open-source, fullstack Next.js framework, giving you instant backend superpowers. Get a full TypeScript backend and admin panel instantly. Use Payload as a headless CMS or for building powerful applications.项目地址: https://gitcode.com/GitHub_Trending/pa/payload创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →