ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Plate 测试套件清理实战:三层测试架构、最小 Seam 策略与 25 轮重构全记录

Plate 测试套件清理实战:三层测试架构、最小 Seam 策略与 25 轮重构全记录 Plate 测试套件清理实战三层测试架构、最小 Seam 策略与 25 轮重构全记录【免费下载链接】plateRich-text editor with AI and shadcn/ui项目地址: https://gitcode.com/GitHub_Trending/pl/plate本指南以仓库内 docs/plans/2026-03-06-test-suite-cleanup-plan.md 为骨架完整还原 Plate 富文本编辑器platejs/*工作区一次为期数周的测试套件质量治理过程从单元 / 薄契约 / 黄金 I/O三层测试架构的确立到createEditor → createSlateEditor → createPlateEditor最小 Seam 选择策略再到 25 个清理 Pass 的逐轮执行、矩阵扫描、决策沉淀与验证记录。读完本文你将掌握一套可直接复用的测试债务清理方法学如何用数据驱动挑选清理目标、如何在保持行为契约不缩水的前提下压缩套件体积、如何处理快照死键与注释测试以及如何把规则沉淀进testing.mdc供后续贡献者长期遵守。背景与目标把测试套件收敛为三层该计划类型标记为refactor2026-03-06 制定的目标非常明确把整个测试套件推向仅保留三层的结构纯单元测试Pure unit tests针对确定性逻辑不依赖编辑器运行时。薄编辑器/插件契约测试Thin editor or plugin contract tests验证真实的 Plate 或 Slate 装配wiring行为。黄金输入/输出测试Golden input/output tests针对序列化器serializer与解析器parser行为的输入输出对照。同时划出明确的范围边界本阶段不做盲目的仓库级覆盖率推动不设覆盖率百分比竞赛不做 e2e 或浏览器测试全程保持本地、终端化、快节奏的迭代闭环。这一目标后来被完整固化进仓库的 .agents/rules/testing.mdc成为platejs/*各包测试写作的纲领性规范。核心方法学覆盖率策略与最小 Seam 选择覆盖率是热点遥测不是虚荣指标整个清理过程反复强调一个观念覆盖率用于破坏性变更/重构期间的回归检测而不是用于赢得百分比竞赛。对应的操作纪律是从新鲜的lcov报告对文件排序打分信任文件级排序多于包级汇总lcov是包级可信真相Bun 的宽泛文本汇总噪声大每轮 Pass 之后重新跑覆盖率绝不沿用过期的热点地图按轮次推进先做诚实且得分 6的文件重跑覆盖率后处理值得做的 5文件最后切换到架构安全 Pass——不再盲从覆盖率转而加固你最不愿被破坏的契约插件解析与组合、规范化契约、解析/序列化行为、结构性 transform、history/diff、公开编辑器不变量剩余未覆盖的薄包装wrapper、DOM/Provider 专属 seam、巨型低 ROI 文件、微小碎屑crumb、以及即将被重写或删除的代码都属于可以停下来的信号不追求 100%。最小 SeamcreateEditor→createSlateEditor→createPlateEditor这是整个清理计划最核心的操作准则按能证明契约的最小 seam逐级选择createEditor来自platejs/slate纯 Slate 的 query、transform、interface、history 契约。createSlateEditor非 React 的插件或编辑器装配包括插件 option store、selector 扩展、纯插件 API 组合、纯 transform 组合、parser/deserializer 契约、HTMLinsertData、DnD 类契约。createPlateEditor仅当契约确实是 Plate 专属时才使用React hook、provider、渲染输出、DOM 行为、store 重渲染语义、Plate 插件转换边界以及两个已知的 Plate 专属选择 APImoveSelection与shiftSelection。从源码可以确认createSlateEditor是createSlateEditor选项 withSlate的组合定义位于 packages/core/src/lib/editor/withSlate.ts其 JSDoc 明确说明这是非 React 版本的 Plate 编辑器内部通过withSlate(editor, options)把全部插件与配置应用到createEditor()产生的实例上适用于非 React 环境或服务端场景。仓库中还存在专门的测试辅助resolveCreatePluginTest见 packages/core/src/internal/plugin/resolveCreatePluginTest.ts它就是用createSlateEditor({ plugins: [p] })构造最小编辑器后解析插件 key为插件解析类测试提供最小可复用的装配入口。清理完成后的最终状态是剩余的createPlateEditor用法构成一份经过审查的允许清单allowlist而不是待清理队列——这是判断清理是否到位的分水岭。25 轮清理的执行记录从热点重写到包级专项计划用 25 个 Pass 记录了完整的执行历史按主题可归纳为以下阶段。第一阶段热点批处理与死代码移除Pass 1–2Pass 1 围绕core、table、link、list-classic、markdown、udecode/utils中更小的行为 seam 重建了第一批热点测试移除了getHandler.spec.ts这类低信号测试删除了deserializeMd的旧 markdown 快照并在testing.mdc中加入了初始测试分类与 helper 放置规则。Pass 2 用packages/selection/src/react/internal/api/setSelectedIds.spec.tsx的直接 API 覆盖替换了被跳过skip的死选择测试统一了NormalizeTypesPlugin与TrailingBlockPlugin的 spec共享normalizeRoothelper清理了list-classic、slate、core中的小型 query spec让标题描述行为而非占位文本删除了一个标题与断言自相矛盾的resolvePlugin深拷贝测试。第二阶段共享 Helper 与文件组织规范Pass 3–4Pass 3 把共享的表格测试 helper 从withNormalizeTable.spec.tsx迁移到packages/table/src/lib/__tests__/getTestTablePlugins.ts各 table spec 改为从真实 helper 模块导入而非从另一个 spec 文件导入删除了packages/table/src/react/onKeyDownTable.spec.tsx零活动测试、只有注释或 skip 意图与packages/docx-io/src/lib/__tests__/lists.spec.tsx完全跳过的未支持场景从streamDeserializeMd.spec.tsx、splitLineBreaks.spec.tsx中移除被跳过的未支持用例并把活动用例压缩成小矩阵精简Plate.spec.tsx删除死 skip 用例、重复 id 测试重命名低信号标题扩展了testing.mdc的清理矩阵指引并立下禁止憧憬式跳过测试的硬规则。Pass 4 把packages/core/src/static/__tests__/中文件级静态序列化器 spec 移到相邻的serializeHtml.*.spec.*文件只留下create-static-editor.ts作为唯一 helper把HotkeysProvider.test.tsx移到packages/udecode/react-hotkeys/src/internal/HotkeysProvider.spec.tsx并改为.spec命名用packages/find-replace/src/lib/decorateFindReplace.spec.ts替换旧__tests__/decorateSearchHighlightspec多数用例转为直接单元测试仅保留一个插件装配冒烟测试在testing.mdc中加入显式.spec命名规则与__tests__/放置规则。第三阶段AI 流式套件重构Pass 5packages/ai/src/react/ai-chat/streaming/streamInsertChunk.spec.tsx被判定为最高 ROI 的 AI 热点864 行、5 个 skip、2 个快照且与 markdown 解析器行为高度重叠。清理动作包括把巨型混合用途集成文件改写为更小的契约套件一个 chunk helper、针对 chunk 边界的断言、it.eachmarkdown 对齐用例删除全部 5 个 skip 用例而非保留美好愿望删除快照文件把两个快照用例替换为显式断言移除skills and weather专属 fixture 与巨型手写期望树替换为一个更小的混合 markdown 冒烟用例在testing.mdc中立下反对随意使用快照的硬规则并固化流式 markdown 模式一个混合文档冒烟用例 少量显式 chunk 边界测试不用快照或巨型手写树隐藏行为。第四阶段纯工具套件折叠Pass 6mergeDeepToNodes原本是分散在packages/core/src/lib/utils/__tests__/mergeDeepToNodes/下的 8 个小 hyperscript spec清理后合并为单个相邻单元文件 packages/core/src/lib/utils/mergeDeepToNodes.spec.ts。要点用纯对象 fixture 替换 hyperscript fixture仅对 editor-root 用例保留真实编辑器对象——因为NodeApi与ElementApi对真实编辑器对象和普通{ children: [...] }对象的语义不同把单节点的 source-factory 覆盖升级为多节点断言证明 factory 对每个匹配节点只运行一次同时把withAutoformat/trigger.spec.tsx重构为createSlateEditorit.each 行为标题原实现用createPlateEditor反复搭建但契约其实是纯 Slate 行为。第五阶段autoformat 套件去 app 耦合Pass 7–8autoformat 套件的问题在于包测试导入了应用注册表Pass 7 新增packages/autoformat/src/lib/__tests__/withAutoformat/createAutoformatEditor.ts共享 helpertext、markup、ignoreTrim、mark/multiple-marks、trigger、block/singleCharTrigger全部改用KEYS或本地规则彻底摆脱platejs/basic-nodes/react、platejs/link/react、wwwapp-kit 导入清除了包类型检查阻塞移除坏掉的 React-only key 导入。Pass 8 完成block/list、block/code-block、block/heading、block/blockquote、block/preFormat、invalid的重写——每个用例只添加该规则真正需要的 base 插件如 list 规则只需BaseListPluginBaseIndentPlugincode-block 规则只需BaseCodeBlockPlugin移除最后一个AutoformatKit、createPlateEditor、React-only.key与占位标题把四个单用例 mark 文件折叠为mark/basic-marks.spec.tsx矩阵删除 app 耦合的 toggle 用例。关键原则被固化包测试必须使用包本地规则列表或包导出不得导入 app 注册表mark 类型字符串用KEYS而非 React 插件.keyblock 规则只加所需 base 插件单用例 mark/block spec 折叠为矩阵。第六阶段标题债务扫描Pass 9一次仓库级、逐文件的标题扫描覆盖普通字符串标题、it.each(...)(...)格式串、String.raw\...标题、以及由这些标题派生的快照键。清理了Plate.spec.tsx、init.spec.ts、removeMarks.spec.tsx、serializeMd.spec.tsx、deserializeMdList.spec.tsx 的剩余标题债务把两个空白敏感的 markdown 序列化器快照断言替换为直接toBe(...)字符串断言原快照含尾部有意义空格会触发git diff --check失败标题重命名后删除并重新生成 markdown 快照文件——因为bun test -u会更新/新增键但不可靠地清理死键教训固化标题应语义化描述行为when normalization is disabled优于when shouldNormalizeEditor false不镜像原始选项名。第七阶段插件组合测试精简Pass 10–11resolvePlugins.spec.tsx用getResolvedKeys(...)、getSortedKeys(...)与it.each(...)处理确定性插件排序用例resolvePlugins-store.spec.tsx把纯 option-store 与 selector 扩展用例迁移到createSlateEditor删除重叠的 rerender 测试保留更聚焦的 React hook rerender 覆盖extendApi.spec.ts通过本地 helper 切到createSlateEditor仅保留纯插件 API 组合行为之后热点矩阵显示剩余大套件如AffinityPlugin.spec.tsx、Plate.spec.tsx大多是真实的 React 或 transform 边界覆盖而非伪装集成予以保留。第八阶段注释测试清理Pass 12仓库级扫描packages/**/*.spec.*中被注释掉的it(...)、test(...)、describe(...)块删除来自shortcuts、useEditableProps、EditorMethodsEffect、pluginDeserializeHtml、SlateExtensionPlugin、withList、setSelectedCellsBorder、cleanDocx、withImageUpload、computeDiff的死注释块并在testing.mdc中固化删除注释测试的硬规则。认知注释掉的测试会腐烂、污染矩阵扫描比诚实的缺失测试更糟。第九阶段规则覆盖套件矩阵化Pass 13–14withBreakRules.spec.tsxpackages/core/src/lib/plugins/override/withBreakRules.spec.tsx围绕createElementPlugin(...)、runInsertBreak(...)、it.each(...)重写重复的 empty-reset 与默认行为用例把原始 config 驱动的describe(...)块重命名为语义行为组——从 725 行降到 472 行行为契约零丢失其兄弟套件withDeleteRules.spec.tsx同样用createElementPlugin(...)、getEditorAfterAction(...)、it.each(...)重写从 648 行降到 496 行断言保持在it()体内helper 只负责 setup 与动作以保持 Biome 干净避免noMisplacedAssertion。第十阶段大规模 Seam 收窄Pass 15–20把 20 个确定性核心/表格 transform spec 从createPlateEditor迁移到createSlateEditoroverrideEditor、SlateEditorMethods、BaseHeadingPlugin、createSlatePlugin、LengthPlugin、insertTable、deleteColumn、setBorderSize、getSelectedCellsBorders、setCellBackground、withDeleteTable、isTableBorderHidden等HTML parser/deserializer、selectBlocks、setSelectedIds、copySelectedBlocks、code-block、DebugPlugin、getEditorPlugin、date、dnd、layout、link、media、slate、list等包随后跟进。两次关键例外moveSelection与shiftSelection尝试迁移后被证明是真正的 Plate 绑定契约依赖 Plate 专属能力强制迁移会破坏契约因此保留在 Plate 并写进testing.mdc作为文档化例外Pass 20 的最终仓库级扫描确认剩余的createPlateEditor文件即React/provider/render/store 允许清单 两个 Plate-only 选择 API剩余的__tests__/spec 即 fixture 密集的docx/docx-io套件与有意拆分的withAutoformat套件。第十一阶段跨包集成测试迁移到 app 层Pass 21–24当包测试需要其他包 kit、app 别名或多包装配时原则是不为此给包添加内部 devDependencies而是把测试迁移到apps/wwwapp 已承载完整包面Pass 21 把platejs/slate中真正跨包装配的 spec 迁移到apps/www合并为单个集成 specinline-link 遍历、inlineisEmpty、mark 切换、void delete 边界并从core移除platejs专用类型导入与不再使用的 devDependencyPass 22 把core静态serializeHtml集成 spec 迁到apps/www它们依赖BaseEditorKit与注册表 fixture删除packages/core/src/static/__tests__/create-static-editor.ts最后一个 helperPass 23 把docx-ioroundtrip fixture 套件迁到apps/www/src/__tests__/package-integration/docx-io.roundtrip.spec.tsx删除packages/docx-io/tsconfig.json中的/*与www/*别名包 typecheck 不再拖入 app-only 导入 seam并为apps/www补齐直接依赖mammothNode 侧 DOCX fixture 导入与types/unist随后在真实 workspace 图上重跑 typecheck包不再依赖假 pinning 绕路Pass 24 把apps/www全部 app 自有包集成簇从src/lib/package-integration迁到src/__tests__/package-integration保留既有 bucket 结构。第十二阶段slate 包专项收尾Pass 25platejs/slate被定为显式的第一阶段优先级选择性挖掘上游.tmp/slate-v2与slate-history测试——只抽取能低成本改善本地公开契约覆盖的不变量绝不盲目镜像最终状态395 个通过测试packages/slate/src函数覆盖率100.00%、行覆盖率96.97%来自lcov覆盖的真实契约桶包括slate-history与 history helperPath、Range、Node、location-ref契约editor query/navigation seamabove、next、previous、marks、string、nodes、isAt、getPointBeforetransform/helper seamdeleteText、deleteMerge、mergeNodes、toggleMark、setNodes、moveSelection、duplicateNodes、addMarks停止条件剩余未覆盖主要是延迟处理的 DOM 包装器加少量低风险非 DOM 文件isEmpty、prop、getFragment、queryNode。Pass 25 还沉淀了方法论与经验Bun 优先、速度优先bun test是默认工作流本程序无浏览器/e2e 覆盖包级真相用lcovBun 的宽泛文本覆盖率汇总对定向包运行噪声大直接 helper spec 对deleteMerge、location-ref、toggleMark、mergeNodes等自定义 slate 代码物有所值——间接覆盖在撒谎上游不变量是参考材料而非神圣经文本地运行时语义不同时保留不变量、围绕真实公开契约重写 fixture不要 cargo-cult 上游 fixture编译期类型契约放type-tests/不放运行时 spec。矩阵扫描如何用数据驱动清理计划在多轮 Pass 前后保留了大量矩阵快照展示了先打分、再清理的决策方式。核心度量列包括行数Lines、跳过数Skips、createPlateEditor/createSlateEditor命中数、jsxt命中数、占位标题命中数、it.each数。代表性判断文件记录于计划文档判定依据packages/core/src/react/components/Plate.spec.tsx高 ROI React/provider 清理目标690 行、2 skip、23 个 Plate seampackages/table/src/react/onKeyDownTable.spec.tsx死文件删除535 行、仅 skip/注释用例packages/ai/.../streamInsertChunk.spec.tsx主清理目标864 行、5 skip、2 快照、与 markdown 解析器重叠packages/core/src/lib/utils/mergeDeepToNodes/8 个 spec折叠为单文件纯逻辑却分散在__tests__ 过度使用 hyperscriptpackages/autoformat/.../text.spec.tsx等去 app 耦合使用AutoformatKit、React.key、占位标题withBreakRules.spec.tsx压缩真实边界套件但重复 setup 过多725→472 行__tests__目录扫描Pass 4 快照确立了放置决策packages/core/src/static/__tests__的 6 个 spec 迁出保留 helperpackages/udecode/react-hotkeys/src/__tests__的 1 个 spec 迁出packages/find-replace/src/lib/__tests__的 2 个 spec 替换为相邻单元 specdocx21 spec 47 fixture与docx-io6 spec 1 fixture保留为 fixture 密集的集成套件autoformat与core/src/lib/utils的拆分多文件行为套件暂时保留。沉淀到 testing.mdc 的标准清理成果最终固化在 .agents/rules/testing.mdc 中核心标准如下。通用标准仅当树形/选择形状是契约时才使用 JSX hyperscriptoption 与 state 测试用纯对象 fixture所有测试使用*.spec.ts[x]命名文件级 spec 紧邻实现共享 helper 放__tests__/绝不放在另一个 spec 文件里__tests__/只用于helper、fixture 库、有意拆分的多文件/集成套件除非序列化文本或 AST 输出就是契约否则避免快照批量重命名快照测试后要删除并重新生成快照文件bun test -u不清理死键微小拆分套件在唯一差异是 fixture 形态时折叠为一个表驱动文件流式 markdown一个混合文档冒烟用例 少量显式 chunk 边界测试不用快照或巨型手写树插件 option store、selector 扩展等非 React 组合测试用createSlateEditorparser/deserializer/HTMLinsertData/DnD 契约测试默认也用createSlateEditormarkdown 包测试必须在包 helper 中本地配置MarkdownPlugin禁止从apps/www导入MarkdownKit或任何 app 注册表删除死skip测试而非保留愿望清理波按文件打分而非随机浏览标题清理波同时扫描普通标题、it.each格式串、String.raw标题与快照键死 spec 清理波同时扫描注释掉的it/test/describe插件组合热点先抽取getSortedKeys(...)、createStoreEditor(...)等 helper规则覆盖热点抽取一个编辑器 helper 并用it.each表驱动重复节点类型用例动作 helper 可以创建编辑器并执行 transform但断言必须留在it()体内不在仓库根目录创建task_plan.md、findings.md、progress.md把内容并入docs/plans/...计划文件测试运行纪律Bun 优先、速度优先bun run test是默认内环pnpm test:all是收尾/CI 运行pnpm test:slowest是硬门禁package.json 中定义了test、test:all、test:slow、test:slowest、test:profile等脚本均由 tooling/scripts 下的脚本驱动不做每个包一个冒烟测试的扫荡不为薄包装包添加宽泛冒烟覆盖。包级规则autoformat包本地规则数组KEYS/base 插件而非 React.key只加规则需要的 base 插件微小 mark/block 套件折叠为矩阵不导入AutoformatKit需要跨包行为时迁到apps/www/src/__tests__/package-integrationmarkdown本地配置MarkdownPlugin空白敏感输出优先直接字符串断言ai/流式 markdown一个混合文档冒烟 显式 chunk 边界测试corecreateSlateEditor用于纯 option store/selector/API 组合/transform/parser/insertData/DnD优先在此扩张编译期类型测试车道core 源码测试同时加载公开 React 入口时把重复实例警告当噪声用suppressInstanceWarning处理不改运行时Provider-only React spec 复用 packages/core/src/react/tests/TestPlate.tsxselectionmoveSelection与shiftSelection留在 Plate是文档化例外而非债务docx/docx-io/app 集成app 自有跨包集成测试放apps/www/src/__tests__/package-integration包测试不得把 app 别名/kit/注册表拖进包图fixture 密集的docx、docx-io是保留__tests__/的正当理由slate先做纯 editor/query/transform 行为选择性上游挖掘直接 helper spec 用于自定义 slate 代码lcov作为包级真相剩余 miss 主要是 DOM 包装器与低风险非 DOM 尘埃时即停止。两个 Reviewed Exceptions审查过的例外createPlateEditor允许清单React/provider 装配、渲染输出/DOM 行为、store 重渲染语义、Plate 插件转换边界、两个 Plate-only 选择 API——这些文件不是 backlog不应再被当作清理目标__tests__/允许清单包本地 helper/fixture 库、withAutoformat这类有意拆分套件、docx/docx-io这类 fixture 密集集成套件、app 层package-integration套件。关键技术决策为什么这样做计划文档以决策表形式记录了 20 条技术决策及其理由核心摘录决策理由只保留三层单元 / 薄契约 / 黄金 I/O削减伪装集成覆盖所有测试用*.spec.ts[x]文件命名一致、Bun 行为一致纯树工具优先纯对象 fixture结构简单时 hyperscript 是噪声除非序列化输出是契约否则避免快照快照在隐藏行为而非证明行为editor-root 语义用真实编辑器对象NodeApi/ElementApi对普通对象与真实编辑器的处理不同包测试用本地规则或包导出而非 app 注册表防止跨包耦合、保持 seam 干净先重写大型热点 spec 再追广泛标题债务每轮信号增益更大重命名快照测试后删除并重生成快照文件bun test -u会留下死键标题语义化而非镜像原始选项名可读性更佳注释掉的测试应删除而非停放在文件里它们会腐烂并污染矩阵扫描剩余createPlateEditor文件视为审查过的允许清单它们已是合法的边界套件计划还明确了本轮需求边界不增加覆盖工作而提升套件质量移除无用或重叠测试优先小 seam 而非宽 Slate 集成测试保持测试风格一致并文档化供后续贡献者使用本阶段不做慢速 e2e 或浏览器测试。验证与错误日志每轮清理的收尾纪律验证命令体系每轮 Pass 之后都执行固定组合拳计划文档中的验证日志记录了完整的命令形态定向测试bun test spec 文件列表如 AI 流式套件27 pass, 0 failcoreautoformat 套件11 pass, 0 failautoformat 全套36 pass, 0 failtitle 加固79 pass, 0 fail快照重生成bun test -u markdown spec18 pass无残留死键变更覆盖扫描git diff --name-only -- packages | rg \.spec\. | xargs bun test最终1590 pass / 0 fail / 209 文件构建与类型检查pnpm turbo build --filter./packages/pkg、pnpm turbo typecheck --filter./packages/pkg受影响包逐一通过格式与 lintpnpm exec biome check --write 变更文件最终 211 文件检查、4 个自动修复、仓库级bun lint:fix2585 文件、0 修复债务扫描针对标题债务、快照键、注释测试、跨 spec 导入、非允许清单createPlateEditor、markdown helper 泄漏的rg扫描全部无匹配空白检查git diff --check干净。错误日志中的典型坑计划保留了一张踩坑记录表值得所有测试重构参与者注意错误处理streamInsertChunk.spec.tsxhelper 触发noMisplacedAssertion断言移回每个it()体内mergeDeepToNodes.spec.tseditor-root 用例比较整个编辑器对象用真实编辑器并断言children与根边界autoformattypecheck 因 spec 中残留platejs/basic-nodes/react、platejs/link/react导入失败移除热点 spec 的 React-only.key导入bun test -u在标题重命名后留下死快照键删除受影响快照文件并从头重生成markdown 序列化器快照含有意义尾部空格git diff --check报警两处改用显式字符串断言moveSelection/shiftSelection切到createSlateEditor后失败保留在 Plate文档化例外而非照搬规则markdown helper 从apps/www导入MarkdownKit替换为本地MarkdownPlugin.configure(...) remark 插件迁移 DOCX roundtrip spec 到www后Cannot find package mammoth随后又暴露src/types/unist.ts缺直接类型给apps/www添加mammoth与types/unist直接依赖当前状态清理结束时的可验证成果计划收尾时Pass 20–25 之后记录了如下状态仓库级变更 spec 扫描1590 pass / 0 fail覆盖 209 个文件core、slate、markdown的pnpm turbo build与 typecheck 通过git diff --check干净标题债务扫描should、fixures、qoute在 spec 标题与快照键中均无匹配剩余最大 spec 大多是边界套件而非明显死重集成测试extendApi.spec.ts不再用 Plate seam 测纯插件组合注释掉的it/test/describe扫描零匹配withBreakRules.spec.tsx725→472 行、withDeleteRules.spec.tsx648→496 行行为契约不变createPlateEditor扫描收敛为有意允许清单packages/markdown/src/lib/__tests__/createTestEditor.tsx不再导入apps/wwwpackages/docx-io/tsconfig.json不再别名apps/wwwapps/www/src/__tests__/package-integration/docx-io.roundtrip.spec.tsx承接 DOCX 导出/导入 roundtrip 覆盖package-integration成为 app 自有跨包集成测试的家。结语一套可复用的测试债务清理方法这份计划最大的价值不在于清理了多少行而在于它沉淀出一套可移植的清理流程先立架构目标明确三层测试结构划定不做 e2e/浏览器、不做盲目覆盖竞赛的边界用数据选目标以lcov文件排序打分按 6 → 重跑 → 5 → 架构安全的轮次推进先重写大热点再追标题债务选最小 seamcreateEditor → createSlateEditor → createPlateEditor把createPlateEditor收敛为审查过的允许清单每轮收尾必验证定向bun test 受影响包turbo build/typecheckbiome check 债务rg扫描 git diff --check把规则写进规范文件所有判断标准命名、放置、fixture、快照、例外全部固化到.agents/rules/testing.mdc让后续贡献者按规则写测试而不是按感觉写测试。对于正在维护大型编辑器/插件仓库的团队这份记录可以作为一份现成的测试治理清单先抄三层架构再抄扫描命令最后抄 allowlist 与例外管理——而完整的历史轨迹与全部决策细节都保存在 docs/plans/2026-03-06-test-suite-cleanup-plan.md 中可随时回溯核查。【免费下载链接】plateRich-text editor with AI and shadcn/ui项目地址: https://gitcode.com/GitHub_Trending/pl/plate创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表