ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

gsd-core 受影响测试选择:如何在 PR 运行中彻底排除 install/slow 套件

gsd-core 受影响测试选择:如何在 PR 运行中彻底排除 install/slow 套件 【免费下载链接】gsd-coreGit. Ship. Done - Core项目地址https://gitcode.com/gh_mirrors/ge/gsd-core点击查看免费下载导读本文以 gsd-core 仓库中的 changeset 370-affected-tests-exclude-install-slow.md 为主体讲解该仓库的受影响测试affected-tests选择器如何在 PRPull Request场景下将install/slow两个仅推送push-only套件彻底排除在运行集合之外。读完本文你将掌握 gsd-core 的套件命名约定与suiteOf检测逻辑、pickAffectedTests单一咽喉点的三层过滤原理、空选择回退到unit的设计以及resolveRunPlan的完整运行决策表并能够在本地复现和验证这一行为。一、背景gsd-core 的套件体系与受影响测试选择gsd-core 将全部测试文件按文件名后缀标记划分为若干套件suite约定为标记位于.test.cjs之前。例如foo.security.test.cjs属于security套件foo.test.cjs无标记属于unit套件。完整的合法套件列表定义在 scripts/run-tests.cjsconst SUITES [all, unit, integration, install, security, slow, qa];其中带标记的套件由 scripts/lib/suite-detection.cjs 中的常量统一登记const MARKED_SUITES [integration, install, security, slow, qa];对应的套件级 npm 脚本在 docs/TESTING-SUITES.md 中有完整说明npm test # everything与旧行为一致 npm run test:unit # 仅 unit npm run test:integration # 仅 integration npm run test:install # 仅 install npm run test:security # 仅 security npm run test:slow # 仅 slow受影响测试affected-tests机制的目标是给定一次变更的文件集合通过require()/import依赖图计算出可能被这次变更影响的测试文件只运行这些文件从而在 PR 上获得远比全量测试快的反馈。该机制有两个入口CI 侧规则表驱动的 scripts/ci-test-scope.cjs文档明确说明这是 CI 选测的权威映射本地/PR 侧依赖图驱动的 scripts/run-affected-tests.cjs它只是一个薄 CLI 入口核心逻辑全部位于 scripts/affected-tests-lib.cjs。二、问题install 与 slow 套件为什么不能出现在 PR 运行中install套件的测试如release-tarball-smoke.install.test.cjs是 npm 打包 全局安装级的长耗时集成测试在 gsd-core 的 CI 编排中由独立的install-smoke.ymlworkflow负责运行slow套件则是标记为低频率、长耗时的测试。它们被设计为push-only只应在推送/发布级流水线中运行而不是在每一次 PR 上重复执行——否则会显著拖长 PR 反馈周期甚至触发按 chunk 的 Windows 超时tests/ci-test-scope.test.cjs 中明确记录了这一历史教训。在修复PR #370之前受影响测试选择存在三处漏洞导致 PR 仍可能选中甚至运行这些 push-only 套件pickAffectedTests在 direct-change直接变更的测试文件、reverse-index依赖图反查命中、stem-match文件名词干模糊匹配三条选择路径上都可能把install/slow文件选入集合当选择结果为空时存在一个DEFAULT_SMOKE_TESTS安装文件回退注入逻辑会把 install 套件的 smoke 测试强行塞进 PR 运行当变更触及关键路径critical path时旧实现调用runAllSuites——它会把包括install/slow在内的所有套件都运行一遍。三、修复核心一pickAffectedTests的单一咽喉点过滤修复后的过滤逻辑集中在 scripts/affected-tests-lib.cjs源码注释明确称之为单一咽喉点single chokepoint// Drop any file whose suite is push-only. This is the single chokepoint — // it catches direct-change, reverse-index, AND stem-match selections. for (const file of selected) { const suite suiteOf(path.basename(file)); if (PR_EXCLUDED_SUITES.has(suite)) selected.delete(file); }这段代码在pickAffectedTests完成三类选测direct-change、reverse-index 反查、stem 启发式匹配之后、返回之前统一执行对集合中每个文件调用suiteOf判断其套件凡命中PR_EXCLUDED_SUITES的立即从集合中删除。PR_EXCLUDED_SUITES的定义在 scripts/affected-tests-lib.cjs// Suites that are push-only. PRs must never select or run these. const PR_EXCLUDED_SUITES new Set([install, slow]);把过滤收敛到一个咽喉点而非散落在三条选择路径里各自判断带来的工程收益是单点可验证只要保证咽喉点的删除逻辑正确无论未来新增第几种选择路径都不会再次出现 push-only 套件泄漏。3.1 三类选择路径各自如何被覆盖从 scripts/affected-tests-lib.cjs 的pickAffectedTests实现可以看到三条路径direct-change遍历变更文件凡tests/下且仍存在未被删除的.test.cjs直接加入集合L300-L313reverse-index 反查对非测试文件的变更从传递性反查索引reverseIndex中取出所有可能依赖它的测试L307-L312stem-match对每个变更文件取 basename 去扩展名的词干与全部测试文件路径做不区分大小写的子串包含匹配L315-L322。咽喉点过滤位于三者之后因此一条路径都不漏。四、修复核心二移除DEFAULT_SMOKE_TESTS回退注入空选择运行 unit旧的空选择回退逻辑会在没有匹配到任何测试时无条件注入一份DEFAULT_SMOKE_TESTS其中包含 install 套件文件这等于绕过了过滤规则。修复将其整体移除新的行为是空选择时不再注入任何 install 文件而是以unit套件作为 smoke 回退。这一契约变化在 tests/affected-tests-lib.test.cjs 中有直接断言test(pickAffectedTests returns empty (no install smoke) when nothing maps, () { const allTests [ tests/release-tarball-smoke.install.test.cjs, tests/some-unit.test.cjs, ]; const selected pickAffectedTests( [docs/CONTRIBUTING.md], allTests, new Map(), ); assert.ok( !selected.includes(tests/release-tarball-smoke.install.test.cjs), install smoke test must not be injected as fallback, ); assert.deepEqual(selected, []); });对应的运行侧行为由resolveRunPlan落地见下一节当选择为空时返回{ mode: suite, suite: unit }运行器随后以unit套件作为 smoke 兜底。CI 侧的同类修复bug-408移除无条件 smoke 列表注入、改为 unit 回退在 tests/ci-test-scope.test.cjs 中有独立测试覆盖可见空选择 → unit 回退是仓库两侧一致的策略。五、修复核心三critical-path 分支从runAllSuites改为PR_FULL_SUITES第三个修复点是 critical-path 分支。旧实现调用runAllSuites会运行包括install/slow在内的全部套件修复后替换为PR_FULL_SUITES常量scripts/affected-tests-lib.cjs// Suites run on every PR cell when the critical-path fallback fires. const PR_FULL_SUITES [unit, integration, security];PR_FULL_SUITES恰好覆盖了所有 PR 合法套件unit integration security同时天然排除 install/slow。这一点在resolveRunPlan的注释中有更进一步的说明scripts/affected-tests-lib.cjsInvariant: when widenRequired is true the executed set is ALWAYS ⊇ selected, because PR_FULL_SUITES covers every PR-eligible suite (unit integration security), so every concrete match that pickAffectedTests put intoselectedbelongs to one of those suites and will be exercised by running all three.也就是说当出现 widen宽化回退时运行三套 PR 套件是严格包含咽喉点过滤后所选集合的超集——不存在过滤掉的选择会通过 widen 路径被重新放行的空子。5.1resolveRunPlan完整决策表从 scripts/affected-tests-lib.cjs 的实现可以得到一张完整的运行决策表输入状态决策结果noChanges相对 base 无变更{ mode: suite, suite: unit }criticalPath关键路径变更{ mode: suites, suites: PR_FULL_SUITES }widenRequired孤儿源文件无静态依赖测试{ mode: suites, suites: PR_FULL_SUITES }选择结果为空widenfalse{ mode: suite, suite: unit }有具体选择{ mode: files, files: selected }六、suiteOf的导出机制复用规范检测逻辑而非重复实现changeset 中提到的suiteOf从run-tests.cjs导出由require.main守卫这一细节在代码中有两层实现依据。第一层run-tests.cjs通过仅当作为主入口运行时才执行 CLI 主流程的守卫使其既可被 require 复用、又不会在被导入时误触发命令执行scripts/run-tests.cjsif (require.main module) { runMain(main); } module.exports { suiteOf, ensureBuiltArtifacts, // ... parseArgs、selectFiles、setupRunTempRoot 等 };第二层suiteOf的实际实现已经进一步下沉到独立模块scripts/lib/suite-detection.cjsrun-tests.cjs只是原样再导出以保持向后兼容。该文件头部的注释解释了这一拆分的缘由#4591 packaging fixrun-tests.cjs本身不随发布包分发它是仓库开发期工具如果已发布的脚本如scripts/gen-platform-conformance-tier.cjs直接 require 它会在安装后遇到MODULE_NOT_FOUND#2858因此把suiteOf及其背后的MARKED_SUITES提取到可发布的scripts/lib/下再经由run-tests.cjs导出。核心实现scripts/lib/suite-detection.cjsfunction suiteOf(filename) { const name basename(filename); if (!name.endsWith(.test.cjs)) return null; const base name.slice(0, -.test.cjs.length); const lastDot base.lastIndexOf(.); if (lastDot -1) return null; const marker base.slice(lastDot 1); return MARKED_SUITES.includes(marker) ? marker : null; }要点无标记文件如foo.test.cjs属于unit套件这里返回null带标记文件如foo.install.test.cjs返回其标记字符串。affected-tests-lib.cjs在文件顶部以require(./run-tests.cjs)引入suiteOfscripts/affected-tests-lib.cjs从而与run-tests.cjs的套件过滤行为共享同一份规范实现避免两处套件判定逻辑漂移。七、测试验证行为契约的落点修复后的行为契约由以下测试固定便于在仓库中直接复现验证直接变更 反查命中install 套件被排除tests/affected-tests-lib.test.cjs 断言普通tests/install.test.cjs无套件标记属 unit保留、tests/tarball.install.test.cjsinstall 标记被剔除直接变更 install 测试文件本身也被排除tests/affected-tests-lib.test.cjsstem-match 拉入的 install/slow 被排除tests/affected-tests-lib.test.cjs空选择不再注入 install smoketests/affected-tests-lib.test.cjs常量契约PR_EXCLUDED_SUITES含install、slowPR_FULL_SUITES含unit/integration/security且不含二者tests/affected-tests-lib.test.cjsCI 侧 smoke 列表移除bug-408 用例断言命令类变更不再无条件注入core.test.cjs、package-manifest.test.cjs无规则命中时回退[unit]tests/ci-test-scope.test.cjs。八、本地验证与使用方式运行受影响测试选择相关测试node --test tests/affected-tests-lib.test.cjs运行 CI 测试范围规则相关测试node --test tests/ci-test-scope.test.cjs本地触发受影响测试local-only 便捷入口CI 不使用它npm run test:affected该命令对应 scripts/run-affected-tests.cjs实际执行runAffectedTests先以GSD_AFFECTED_BASE→GITHUB_BASE_REF→origin/main的顺序解析对比基准scripts/affected-tests-lib.cjs再走关键路径 → 反查选测 → widen 兜底 → unit smoke的完整决策链。九、总结PR #370 的修复在 gsd-core 的受影响测试机制上确立了一个清晰且可验证的边界PR 运行集合中永远不允许出现install/slow套件。实现上通过三个相互独立又彼此衔接的手段保证——pickAffectedTests单一咽喉点过滤覆盖全部选择路径、DEFAULT_SMOKE_TESTS注入移除后以unit作为空选择回退、critical-path 分支改用PR_FULL_SUITES而suiteOf的提取与再导出机制require.main守卫 scripts/lib/suite-detection.cjs保证了套件判定逻辑的唯一来源与向后兼容。这套设计既缩短了 PR 反馈周期也通过单点收敛和测试契约避免了同类问题在未来回归。赞分享【免费下载链接】gsd-coreGit. Ship. Done - Core项目地址https://gitcode.com/gh_mirrors/ge/gsd-core点击查看免费下载相关推荐Wick Editor开发者指南贡献代码与扩展功能的终极教程Wick Editor开发者指南贡献代码与扩展功能的终极教程 想要为Wick Editor这个免费开源的多媒体创作工具贡献代码或扩展功能吗本指南将为你提供完游戏开发开发工具如何在 Docker 测试环境里运行 Huginn 测试套件rspec 与无头 Chrome如何在 Docker 测试环境里运行 Huginn 测试套件rspec 与无头 Chrome 如果你正在为 Huginn 开发或修改 Agent改完代码后端工作流自动化任务调度Lwan测试套件如何编写和运行集成测试Lwan测试套件如何编写和运行集成测试 Lwan是一个实验性的、可扩展的高性能HTTP服务器其测试套件是确保代码质量和稳定性的关键组成部分。本文将详细介绍L后端上一篇Spike模拟器与真实硬件对比功能差异与适用场景终极指南下一篇解决Hoppscotch CLI 0.10.0版本Docker安装依赖的终极方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表