Strapi E2E 测试基建实战:Playwright 本地运行、CE/EE 版本控制与并发调优完整指南
发布时间:2026/9/7 4:56:08 作者:尧图编辑部 阅读量:1,286

Strapi E2E 测试基建实战Playwright 本地运行、CE/EE 版本控制与并发调优完整指南【免费下载链接】strapi Strapi is the leading open-source headless CMS. It’s 100% JavaScript/TypeScript, fully customizable, and developer-first.项目地址: https://gitcode.com/GitHub_Trending/st/strapi本文围绕 Strapi 官方的 E2E 测试配置文档展开系统讲解如何在本机安装 Playwright 浏览器、生成test-apps测试应用、运行yarn test:e2e全量/指定域/指定浏览器测试以及如何通过STRAPI_E2E_EDITION、STRAPI_LICENSE等环境变量精确控制 Community EditionCE与 Enterprise EditionEE的运行模式。读完本文你将能够独立搭建 Strapi 的端到端测试环境理解测试应用生成、端口分配、分批并行的底层机制并掌握调试--debug、产物trace/视频与 future flags 的完整配置手段。整体架构文档说明了什么Strapi 的 E2E 体系由三层组成统一测试运行器tests/scripts/run-tests.js 是 e2e 与 CLI 测试共用的入口负责加载环境变量、创建测试应用、生成 Playwright 配置并分批执行Playwright 基础配置工厂playwright.base.config.js 中的createConfig为每个测试域domain动态生成一份playwright.config.js内嵌端口、超时、报告器与webServer启动逻辑测试域目录tests/e2e/tests 下每个顶层目录即一个测试域当前包括admin、content-manager、content-releases、content-type-builder、i18n、media-library、review-workflows、search、settings。E2E 测试的核心诉求是对一个“全新”的 Strapi 实例做断言因此运行脚本会自动完成实例的创建、依赖链接与端口分配开发者只需关心测试本身。快速开始安装 Playwright 浏览器运行 E2E 测试前必须先安装 Playwright 浏览器npx playwright install这是唯一的前置手动步骤其余依赖链接、应用生成、服务器启动均由运行器自动完成。本地运行 EnterpriseEE测试e2e 专属 .env 文件要在Enterprise 模式下运行测试套件或让yarn test:e2e在可能时自动检测EE必须把 license 写入e2e 专属的环境文件将 tests/e2e/.env.example 复制为tests/e2e/.env路径相对于 monorepo 根目录。不要把 e2e 专用变量放在 monorepo 根目录的.env中——运行器不会加载它。将STRAPI_LICENSE设置为 license 字符串其作用等同于 CI 中 GitHub Actions 的 secretstrapiLicense。.env.example的内容本身就给出了用法示例# Specify any environment variables you would like to use for your tests STRAPI_LICENSEyour_license_key从源码看这一机制的实现在 tests/scripts/run-tests.js#L63-L71运行器启动时若tests/e2e/.env存在就显式用dotenv.config({ path: ... })加载它随后立即调用applyE2eEditionEnv()统一版本环境。而 Yarn/npm 的cross-env并不会读取.env文件——只有这个dotenv加载器会这就是为什么文档强调“不要把 e2e 变量放在根目录.env”。加载完成后按目标选择命令目标命令自动设置STRAPI_LICENSE则 EE否则 CEyarn test:e2e始终 CElicense 从运行器进程剥离Strapi 保持 CEyarn test:e2e:ce始终 EE 运行器模式缺少STRAPI_LICENSE时直接退出yarn test:e2e:ee对应的 package.json 脚本定义第 76–79 行为test:e2e: node tests/scripts/run-e2e-tests.js, test:e2e:ce: cross-env STRAPI_E2E_EDITIONce node tests/scripts/run-e2e-tests.js, test:e2e:ee: cross-env STRAPI_E2E_EDITIONee node tests/scripts/run-e2e-tests.js, test:e2e:clean: node tests/scripts/run-e2e-tests.js clean其中 tests/scripts/run-e2e-tests.js 只是一个薄封装它在参数头部注入--type e2e后委托给统一运行器。默认运行yarn test:e2e完整做了什么安装浏览器及可选的 EE.env后执行yarn test:e2e运行器默认会为每个测试域如content-manager在test-apps/e2e/下准备一个 Strapi 实例每个实例由各自生成的playwright.config.js负责启动 Strapi 服务器并跑测试。测试应用会从 monorepo 自动链接依赖——因为test-apps不属于 monorepo但我们希望始终测试“最近版本”已发布或开发中的 Strapi从而让最新的代码改动可以被验证。从源码可以还原出完整的执行链路加载.env并应用版本环境run-tests.js#L63-L71e2e 类型下先dotenv再applyE2eEditionEnv()发现域fs.readdir(testRoot/tests)读取tests/e2e/tests下的顶层目录作为可选域yalc 发布publishYalc(cwd)把 monorepo 内所有包发布到本地 yalc 存储见 tests/utils/runners/shared-setup.js生成测试应用testAppsRequired Math.min(selectedDomains.length, concurrency)不足时清理旧应用并基于 tests/app-template 重新生成数据库固定为 SQLite./.tmp/data.db生成后还会删除.env中的PORT1337避免端口冲突并为每个应用做一次 git 基线提交commitE2eBaseline供后续git reset --hard恢复文件分批执行按testAppsToSpawn个一批切分域同一批内并行Promise.all批与批串行每个域绑定端口8000 indexrun-tests.js#L197并动态写出playwright.config.js内容为process.env.PORT赋值 序列化后的createConfig结果。如果测试应用行为异常例如模板改动后可清理重建yarn test:e2e:clean该目标会调用 run-tests.js 中的clean子命令对每个现存测试应用执行cleanTestApp等价于run-e2e-tests.js clean。运行指定测试--domains与参数转发只运行一个域即tests/e2e/tests下的某个顶层目录如admin、content-manageryarn test:e2e --domainsadmin文件过滤与 Playwright 专属参数--project、--grep、--reporter、--debug等必须放在跟随运行器选项之后的--之后若使用npm在那些参数前还需再多一个--例如npm run test:e2e -- --domainsadmin -- login.spec.ts。# 只在 admin 域中运行 login.spec.ts yarn test:e2e --domainsadmin -- login.spec.ts按文件过滤时仍建议用--domains限定作用域否则可能触发所有域而没有该文件的域会因“未找到测试”而失败。运行器对剩余参数的转发逻辑在 run-tests.js#L76-L118它先剥离自身的--type参数再用内层 yargs 解析-c/-d/-f/-ubuildForwardedRunnerArgs收集--之后的参数交给 Playwright。在 CI、脚本或自动化中建议在第二个--之后加--reporterline使运行结束后不必等待 HTML reporter 页面而直接退出。指定浏览器与调试模式通过 Playwright 的--project指定浏览器chromium、firefox、webkit以加速测试开发yarn test:e2e --domainsadmin -- login.spec.ts --projectchromium使用 Playwright 调试器 真实浏览器实例调试yarn test:e2e --domains admin -- --debug yarn test:e2e --domains admin -- login.spec.ts --debugplaywright.base.config.js#L123-L147 定义了三个项目chromiumDesktop Chrome含剪贴板读写权限、firefoxDesktop Firefox、webkitDesktop Safari含剪贴板读权限--project即按此名称选择。并发与并行化机制运行器使用min(选中的域数, concurrency)个测试应用test-apps/e2e/test-app-*每个绑定端口8000 index。concurrency的默认值是tests/e2e/tests/下域文件夹的数量不是--domains过滤后的数量。域被切成该大小的批批内并行、批间串行。单个域内部的 spec 文件是串行执行的——playwright.base.config.js#L72-L78 中写死workers: 1与fullyParallel: false另注意retries: process.env.CI ? 3 : 1CI 上会重试 3 次本地重试 1 次forbidOnly仅在 CI 生效。# 一次最多跑一个域日志最简单域完全串行 yarn test:e2e -c 1 # 例一次最多三个域然后下一组三个依此类推 yarn test:e2e -c 3分批切分的源码见 run-tests.js#L184-L197用reduce按testAppsToSpawn长度切片每批Promise.all并行启动各域的 Playwright 进程tests/utils/runners/browser-runner.js 用execa执行yarn playwright test --config 生成的配置仅覆盖PORT、HOST、TEST_APP_PATH三个环境变量其余继承父环境——因此你export的其它变量也能到达 Playwright 和被测应用。控制测试配置的环境变量Strapi 提供了一组 helper允许你在不改动运行器所用 Playwright 配置文件的前提下修改本机 Playwright 行为。这些变量全部在 playwright.base.config.js 中被读取getEnvNum/getEnvString/getEnvBool环境变量说明默认值PLAYWRIGHT_WEBSERVER_TIMEOUTStrapi 服务器启动超时ms160000160sPLAYWRIGHT_ACTION_TIMEOUTPlaywright 动作超时如click()1000010sPLAYWRIGHT_EXPECT_TIMEOUTexpect()断言超时1000010sPLAYWRIGHT_TIMEOUT单个测试超时9000090sPLAYWRIGHT_OUTPUT_DIRtrace/截图/视频的根目录每个域使用该目录下domain-port子文件夹设置时同时作为 JUnit 输出目录未设置时 JUnit 默认写入test-apps/junit-reports../test-results相对于每个生成的测试应用配置PLAYWRIGHT_VIDEO设为true时在测试失败重试时保存视频falsePLAYWRIGHT_REUSE_EXISTING_SERVER为true时仅本地设置CI后忽略若测试 URL 已有响应Playwright 可跳过启动 Strapi——适合你常驻一个匹配的服务实例但若版本或 license 与本次运行不一致则有风险false源码中的关键细节webServer.command是cd appDir npm run develop -- --no-watch-admin并通过env: { PORT, HOST: 127.0.0.1 }显式注入端口保证 Strapi 读到的PORT与baseURL/webServer.urlhttp://127.0.0.1:port一致playwright.base.config.js#L154-L175reuseExistingServer: process.env.CI ? false : getEnvBool(PLAYWRIGHT_REUSE_EXISTING_SERVER, false)——CI 永远全新启动本地默认也不复用playwright.base.config.js#L171-L173产物目录按${domain}-${port}隔离避免并行运行时 HTML reporter 互相覆盖playwright.base.config.js#L42-L52trace 策略为 CI 下on-first-retry、本地retain-on-failure视频开启后为on-first-retry分辨率 1280x720时区固定为Europe/Paris所有测试共享./tests/e2e/playwright-storage-state.json的 storage state由tests/utils/global-setup.ts全局写入 localStorage。Strapi 测试模板app-template测试应用基于 tests/app-template 模板生成。该目录存放预制的内容 Schema 以及各种定制例如其它插件、自定义字段或自定义端点。模板自身的 template.json 声明其为私有包其src/、config/、database/会在生成时复制进test-apps并链接 monorepo 依赖。测试代码与模板内容类型之间有显式契约tests/e2e/constants.ts 动态扫描tests/app-template/src/api/*/content-types/*生成ALLOWED_CONTENT_TYPES白名单并内置管理后台测试账号如testtesting.com/Testing123!与页面标题常量Strapi Admin、Homepage | Strapi供各域 spec 复用。约定如果你在模板中新增了任何东西内容类型、插件、自定义字段等请同步更新 tests/app-template/README.md 以及 e2e 指南中的 App template 文档。CE 与 EE 的环境变量STRAPI_E2E_EDITION完整解析版本语义取值含义ceCommunity Edition对 Strapi 设置STRAPI_DISABLE_EEtrueSTRAPI_LICENSE从运行器环境中剥离子进程无法以 EE 启动EE 专属 spec 会被跳过。eeEnterprise清除STRAPI_DISABLE_EESTRAPI_LICENSE必须存在且有效Strapi 才能以 EE 启动。解析顺序实现位于 tests/utils/e2e-edition.tsresolveE2eEdition()第 35–58 行的判定优先级为yarn test:e2e:ce→ 始终 CElicense 从本进程环境中移除yarn test:e2e:ee→ EE缺少STRAPI_LICENSE时报错退出第 67–75 行 中process.exit(1)STRAPI_E2E_EDITION显式设为ce或ee在tests/e2e/.env加载之后来自 CI 的script.sh或你的 shell——采用该版本ee但无 license 时test:e2e会带警告回退到 CE只有test:e2e:ee会硬失败否则自动STRAPI_LICENSE非空则 EE否则 CE。applyE2eEditionEnv()第 63–98 行会实际改写process.envCE 时置STRAPI_DISABLE_EEtrue并delete STRAPI_LICENSEEE 时清除STRAPI_DISABLE_EE——这正是“runner、Playwright、Strapi 三方一致”的保证。值得注意的是该文件刻意保持 JS 可解析无类型标注以便普通 Node 下require(../utils/e2e-edition.ts)直接加载。CI 上的行为CI 的测试工作流定义了两个 e2e 任务.github/workflows/tests.ymle2e_ce——没有STRAPI_LICENSEsecret复合 action 以runEE: false运行 → 脚本设置STRAPI_E2E_EDITIONcee2e_ee——env STRAPI_LICENSE: ${{ secrets.strapiLicense }}且runEE: true→STRAPI_E2E_EDITIONee且STRAPI_DISABLE_LICENSE_PINGtrue。CI 执行的是复合 action 中的script.sh.github/actions/run-e2e-tests/script.sh它在yarn test:e2e之前导出STRAPI_E2E_EDITION。本地同理export STRAPI_E2E_EDITIONce或ee后运行yarn test:e2e该显式值会被尊重。若想要纯自动模式仅凭 license 判断请unset STRAPI_E2E_EDITION。可选在同一个tests/e2e/.env中设置STRAPI_DISABLE_LICENSE_PINGtrue可让本地运行与 CI 的 EE 任务在 license 仅离线可用时保持一致。本地 Yarn 脚本速查脚本行为yarn test:e2e环境中设置了STRAPI_E2E_EDITION时按它执行ce/ee见表否则自动tests/e2e/.env或 export中有STRAPI_LICENSE则 EE否则 CE。yarn test:e2e:ce始终CElicense 从环境中剥离Strapi 无法以 EE 启动。yarn test:e2e:ee缺少STRAPI_LICENSE时快速失败否则运行器进入 EE 模式Strapi 仍需有效 license 才能以 Enterprise 启动。作为便利替代你也可以用yarn test:e2e:ce/yarn test:e2e:ee而不必手动设置STRAPI_E2E_EDITION。补充说明Playwright 的reuseExistingServer默认关闭见上文PLAYWRIGHT_REUSE_EXISTING_SERVER因此已经监听在测试端口上的进程不会被误当作本次运行的 Strapi——运行时的版本与环境严格等于e2e-edition.ts所应用的值。为 future flags 编写测试如果你在为某个尚未稳定的未来功能写测试需要在 tests/app-template/config/features.js 中添加配置。目前模板生成流程不会复制config目录但运行脚本会把 features 配置应用到生成的应用上。该机制在 tests/utils/runners/shared-setup.js 的setupTestEnvironment中实现仅当tests/app-template/config/features.js存在时才把它写入生成应用的config/features.js。当前模板的示例内容是module.exports ({ env }) ({ future: { betaMediaLibrary: env.bool(BETA_MEDIA_LIBRARY, false), }, });这正对应tests/e2e/tests/media-library/future/下针对 beta 媒体库的一批 specasset-crop、folder-creation、grid-view等——通过BETA_MEDIA_LIBRARYtrue环境变量即可启用该 future flag 跑测试。为什么选择 PlaywrightPlaywright 为现代 Web 应用提供可靠的端到端测试能力跨浏览器、跨平台、跨语言。Strapi 使用它做 JavaScript 自动化测试。若对 Playwright 的 API 不熟悉建议直接查阅其官方文档与 API 参考playwright.dev。Strapi 对 Playwright 的使用深度体现在 playwright.base.config.js 的完整生命周期托管上globalSetup写入 localStorage、webServer自动拉起被测 Strapi 实例、junit html 双报告器、trace/视频/截图按domain-port隔离测试域内则保持workers: 1串行以降低管理后台状态相互污染的概率。什么样的 E2E 测试是好测试这是“百万美元级”的问题。E2E 测试通常覆盖触及应用多个切面的完整用户流程——我们不关心过程内部发生了什么只关心用户视角和最终结果。写作时请戴上“故事帽”例如“作为一名用户我想创建一个新实体、发布该实体然后能从 Content API 取回它的数据。”Strapi 的 E2E 套件至少应覆盖产品的核心业务流程具体清单以 QA 团队定义为准不确定时请向 QA 咨询。仓库中的实际组织也印证了这一点content-manager域下有create-content.spec.ts、publish-draft-relations-warning.spec.ts等完整流程型用例admin域下则是login/signup/logout/admin-tokens等以用户故事命名的用例另有 EE 专属用例单独放在tests/e2e/tests/admin/ee/下与 CE 用例物理隔离。小结Strapi 的 E2E 基建把“全新实例”这一诉求内建于运行器yarn test:e2e一条命令即可完成 yalc 链接、SQLite 测试应用生成、端口分配8000index、批内并行/域内串行的 Playwright 执行tests/e2e/.enve2e-edition.ts提供了本地与 CI 完全一致的 CE/EE 判定链PLAYWRIGHT_*环境变量则让你在不动配置文件的前提下调超时、看 trace、录视频。维护测试时的关键入口是 tests/e2e/README.md面向贡献者的索引、tests/app-template/README.md模板契约以及本系列下一篇 App template 指南。【免费下载链接】strapi Strapi is the leading open-source headless CMS. It’s 100% JavaScript/TypeScript, fully customizable, and developer-first.项目地址: https://gitcode.com/GitHub_Trending/st/strapi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考