plate-testing-strategy

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Testing Goal

测试目标

Push the suite toward three layers only:
  • Pure unit tests for deterministic logic.
  • Thin editor or plugin contract tests for real Plate or Slate wiring.
  • Golden input or output tests for serializer and parser behavior.
Hard constraints:
  • Bun-first and speed-first.
    bun run test
    is the default iterative workflow.
  • pnpm test:all
    is the full end-of-task and CI run. Do not use it as the default inner-loop command.
  • Keep the default iterative suite fast.
  • Browser/e2e coverage lives in
    tooling/e2e/
    (Playwright) and runs via
    pnpm e2e
    , outside the bun fast/slow lanes — keep it there so the inner loop stays fast. Reach for it only for genuinely browser-level contracts (overlay geometry, DOM measurement, viewport behavior) that unit/contract tests cannot prove.
  • Coverage is hotspot telemetry, not a vanity target. Do not chase repo-wide numbers blindly.
  • Use coverage after each phase only to choose the next hotspot.
  • No one-smoke-test-per-package sweep.
  • Do not add broad smoke coverage for thin wrapper packages.
将测试套件精简为仅三个层级:
  • 针对确定性逻辑的纯单元测试。
  • 针对真实Plate或Slate连接的轻量编辑器/插件契约测试。
  • 针对序列化器和解析器行为的黄金输入/输出测试。
硬性约束:
  • 优先使用Bun,以速度为第一要务。
    bun run test
    是默认的迭代工作流命令。
  • pnpm test:all
    用于任务结束时的完整测试及CI运行。不要将其作为默认的内循环命令。
  • 保持默认迭代测试套件的运行速度。
  • 浏览器端/e2e测试覆盖位于
    tooling/e2e/
    (基于Playwright),通过
    pnpm e2e
    运行,独立于Bun的快慢测试通道——将其放在此处以保证内循环速度。仅当单元/契约测试无法验证真正的浏览器级契约(如覆盖层几何形状、DOM测量、视口行为)时才使用它。
  • 测试覆盖率是热点遥测数据,而非虚荣指标。不要盲目追求仓库级的覆盖率数值。
  • 仅在每个阶段结束后使用覆盖率数据选择下一个热点区域。
  • 不要为每个包都设置一个冒烟测试。
  • 不要为轻量包装器包添加宽泛的冒烟测试覆盖。

Coverage Strategy

覆盖策略

  • Coverage is for regression detection during breaking changes and rearchitecture, not for winning a percentage contest.
  • Rank files from fresh
    lcov
    . Trust file order more than package totals.
  • Work in passes:
    1. high-value contract pass: do every honest file with score
      >= 6
    2. medium-value follow-up: rerun coverage, then do worthwhile
      >= 5
      files while skipping crumbs, wrappers, and sludge
    3. architecture-safety pass: stop following coverage blindly and harden the contracts you most refuse to break
  • File-first beats package sweeps once the obvious packages are already covered.
  • Good architecture-safety targets:
    • plugin resolution and composition
    • normalization contracts
    • parser and serializer behavior
    • structural transforms and merge helpers
    • history, diff, and change-tracking behavior
    • public editor invariants
  • /react
    is not permanently excluded. Exclude it only when the current pass explicitly says so.
  • React work should wait until non-React seams are exhausted only when that is the active phase goal, not because the skill hardcodes it forever.
  • Stop when the remaining misses are mostly:
    • thin wrappers
    • DOM-only or provider-only seams
    • giant low-ROI sludge files
    • tiny uncovered crumbs
    • code likely to be deleted or rewritten soon
  • 覆盖率用于在破坏性变更和重构期间检测回归,而非参与百分比竞赛。
  • 根据最新的
    lcov
    结果对文件进行排序。相比包级总计,更信任文件排序结果。
  • 分阶段推进:
    1. 高价值契约阶段:处理所有评分
      >= 6
      的重要文件
    2. 中等价值跟进阶段:重新生成覆盖率报告,处理评分
      >= 5
      的有价值文件,同时跳过无意义的小代码块、包装器和冗余代码
    3. 架构安全阶段:停止盲目跟随覆盖率数据,强化你最不愿破坏的契约
  • 一旦明显的包已被覆盖,优先按文件维度处理而非按包扫面。
  • 优质的架构安全目标:
    • 插件解析与组合
    • 规范化契约
    • 解析器与序列化器行为
    • 结构转换与合并工具
    • 历史记录、差异与变更追踪行为
    • 公共编辑器不变量
  • /react
    目录并非永久排除。仅当当前阶段明确要求时才排除它。
  • 仅当当前阶段目标如此时,React相关工作才需等待非React边界处理完毕,而非永久硬性规定。
  • 当剩余未覆盖部分主要为以下内容时即可停止:
    • 轻量包装器
    • 仅DOM或仅提供者的边界
    • 投入产出比极低的大型冗余文件
    • 微小的未覆盖代码块
    • 可能很快被删除或重写的代码

Core Rules

核心规则

  • Assert public behavior through editor APIs, plugin APIs, hooks, transforms, or rendered output. Do not assert private state, call order, or implementation detail when public behavior already proves the contract.
  • Prefer file-ranked batches over package sweeps. Package sweeps are for early broad passes, not the endgame.
  • Do not use coverage to justify testing files with no meaningful contract.
  • Bun globals come from
    tooling/config/global.d.ts
    . Do not import
    describe
    ,
    it
    ,
    expect
    ,
    mock
    ,
    spyOn
    , or other globals from
    bun:test
    .
  • Use
    *.spec.ts[x]
    for the fast lane and
    *.slow.ts[x]
    for the slow lane.
  • Keep helpers package-local. Never import a helper from another spec file.
  • No spec should import another spec.
  • Put compile-only type contracts in
    type-tests/
    , not mixed into runtime specs.
  • Titles should describe behavior semantically, not echo raw option names.
  • Prefer explicit assertions over snapshots by default.
  • Delete skipped tests, commented-out tests, and dead placeholder cases. Do not preserve wishful thinking.
  • No fake smoke tests.
  • No app-registry imports in package tests.
  • Do not add package
    devDependencies
    just to support cross-package or app-shaped test setups. If a test needs other package kits, app aliases, or multi-package wiring, move it to
    apps/www/src/__tests__/package-integration
    .
  • When adding tests, inspect fast-suite outliers with
    bun run test:profile
    .
    bun run test:slowest
    is the hard gate. If a fast-suite spec crosses the thresholds in
    tooling/config/test-suites.mjs
    , rename it to
    *.slow.ts[x]
    .
  • Do not trust a fast laptop. Treat the local warning zone as real debt before CI proves you wrong:
    60ms/test
    or
    120ms/file
    is already a move candidate, especially for React-heavy specs.
  • For borderline cases, run
    pnpm test:slowest -- --top 25 --rerun-each 3
    and move repeat offenders before they drift over the CI line.
  • Treat known third-party resource logs and serializer fallback warnings as test noise. Suppress them narrowly in the shared Bun setup at
    tooling/config/bunTestSetup.ts
    , not by changing runtime code or sprinkling per-spec console mocks.
  • 通过编辑器API、插件API、钩子、转换或渲染输出断言公共行为。当公共行为已能验证契约时,不要断言私有状态、调用顺序或实现细节。
  • 优先按文件排序的批量测试而非按包扫面。按包扫面仅适用于早期宽泛测试阶段,不适用于收尾阶段。
  • 不要用覆盖率数据为无意义契约的文件添加测试。
  • Bun全局变量来自
    tooling/config/global.d.ts
    。不要从
    bun:test
    导入
    describe
    it
    expect
    mock
    spyOn
    或其他全局变量。
  • 快速通道使用
    *.spec.ts[x]
    ,慢速通道使用
    *.slow.ts[x]
  • 工具函数保持包内本地化。绝不要从其他测试文件导入工具函数。
  • 测试文件之间禁止互相导入。
  • 仅编译型类型契约放在
    type-tests/
    目录中,不要混入运行时测试文件。
  • 测试标题应从语义上描述行为,而非直接照搬原始选项名称。
  • 默认优先使用显式断言而非快照。
  • 删除跳过的测试、注释掉的测试和无效的占位用例。不要保留不切实际的测试计划。
  • 禁止虚假冒烟测试。
  • 包测试中禁止导入应用注册表。
  • 不要仅为支持跨包或应用级测试设置而添加包的
    devDependencies
    。如果某个测试需要其他包工具、应用别名或多包连接,请将其移至
    apps/www/src/__tests__/package-integration
    目录。
  • 添加测试时,使用
    bun run test:profile
    检查快速套件中的异常项。
    bun run test:slowest
    是硬性门槛。如果快速套件中的测试超过
    tooling/config/test-suites.mjs
    中的阈值,请将其重命名为
    *.slow.ts[x]
  • 不要依赖高性能笔记本电脑。在CI验证之前,将本地警告区域视为真实技术债务:
    60ms/测试
    120ms/文件
    已属于需要迁移的候选,尤其是React密集型测试。
  • 对于临界情况,运行
    pnpm test:slowest -- --top 25 --rerun-each 3
    ,将多次违规的测试移至慢速通道,避免其超出CI阈值。
  • 将已知的第三方资源日志和序列化器回退警告视为测试噪音。在共享Bun设置文件
    tooling/config/bunTestSetup.ts
    中针对性地抑制它们,不要修改运行时代码或在每个测试中添加控制台模拟。

Seam Selection

测试边界选择

  • Use
    createEditor
    from
    @platejs/slate
    for pure Slate query, transform, interface, and history contracts.
  • Use
    createSlateEditor
    for non-React plugin or editor wiring:
    • plugin option stores
    • selector extension
    • pure plugin API composition
    • pure transform composition
    • parser and deserializer contracts
    • HTML
      insertData
    • DnD-style contracts
  • Use
    createPlateEditor
    only when the contract is genuinely Plate-specific.
  • Use rendered React tests only when the contract is genuinely React-specific: hooks, providers, stores, DOM behavior, or rerender semantics.
  • Remaining
    createPlateEditor
    usage is a reviewed allowlist, not a future cleanup queue.
  • 对于纯Slate查询、转换、接口和历史记录契约,使用
    @platejs/slate
    中的
    createEditor
  • 对于非React插件或编辑器连接,使用
    createSlateEditor
    • 插件选项存储
    • 选择器扩展
    • 纯插件API组合
    • 纯转换组合
    • 解析器与反序列化器契约
    • HTML
      insertData
    • 拖拽式契约
  • 仅当契约确实是Plate特有时才使用
    createPlateEditor
  • 仅当契约确实是React特有时才使用渲染式React测试:钩子、提供者、存储、DOM行为或重渲染语义。
  • 剩余的
    createPlateEditor
    使用情况属于已审核的允许列表,而非未来的清理队列。

File Organization

文件组织规范

  • File-scoped specs live beside the implementation.
  • Keep
    __tests__/
    only for:
    • package-local helpers
    • fixture banks
    • intentionally split multi-file behavior suites
    • intentionally kept integration suites
  • Move lone file-scoped specs out of
    __tests__/
    .
  • Collapse tiny split suites into one adjacent table-driven file when the only variation is fixture shape.
  • Action helpers may create the editor and perform the transform, but assertions stay in the
    it()
    body.
  • Rule-action helpers should return the editor and other setup results, not assert internally.
  • For composition-heavy suites, extract focused helpers before adding more inline setup. Small helpers like
    getSortedKeys(...)
    and
    createStoreEditor(...)
    beat repeated editor construction sludge.
  • 文件级测试与实现文件放在一起。
  • 仅在以下情况保留
    __tests__/
    目录:
    • 包内本地工具函数
    • 测试用例库
    • 有意拆分的多文件行为套件
    • 有意保留的集成套件
  • 将单个文件级测试从
    __tests__/
    目录移出。
  • 当唯一差异是用例形状时,将小型拆分套件合并为一个相邻的表格驱动文件。
  • 操作工具函数可以创建编辑器并执行转换,但断言必须放在
    it()
    代码块内。
  • 规则操作工具函数应返回编辑器和其他设置结果,不要在内部进行断言。
  • 对于组合密集型套件,在添加更多内联设置之前提取聚焦工具函数。像
    getSortedKeys(...)
    createStoreEditor(...)
    这样的小型工具函数比重复的编辑器构建代码更高效。

Fixtures And Assertions

测试用例与断言规范

  • Use JSX hyperscript only when tree shape or selection shape is the contract.
  • Use plain object fixtures for option, state, and pure helper tests.
  • Use a real editor object only when editor-root semantics matter.
    NodeApi
    and
    ElementApi
    do not treat plain
    { children: [...] }
    objects the same way as real editors.
  • Keep inputs and outputs small.
  • Use
    it.each
    for small behavior matrices.
  • In this Bun + Testing Library setup, prefer render-returned queries over
    screen
    .
  • Snapshots are allowed only when serialized text, AST, or similar output is the contract and inline assertions would be worse.
  • Whitespace-sensitive serializer outputs should prefer direct
    toBe(...)
    string assertions.
  • Avoid
    toHaveStyle
    here. Use direct style-property assertions instead.
  • After broad title renames on snapshot-backed suites, delete and regenerate the snapshot file.
    bun test -u
    updates and adds keys, but does not reliably prune dead ones.
  • 仅当树形结构或选择器形状是契约内容时才使用JSX超脚本。
  • 对于选项、状态和纯工具函数测试,使用普通对象作为测试用例。
  • 仅当编辑器根语义重要时才使用真实编辑器对象。
    NodeApi
    ElementApi
    对待普通
    { children: [...] }
    对象的方式与真实编辑器不同。
  • 保持输入和输出的简洁性。
  • 对于小型行为矩阵,使用
    it.each
  • 在Bun + Testing Library环境中,优先使用渲染返回的查询而非
    screen
  • 仅当序列化文本、AST或类似输出是契约内容且内联断言效果更差时,才允许使用快照。
  • 对空格敏感的序列化输出应优先使用直接的
    toBe(...)
    字符串断言。
  • 避免在此处使用
    toHaveStyle
    。改用直接的样式属性断言。
  • 在对基于快照的套件进行宽泛标题重命名后,删除并重新生成快照文件。
    bun test -u
    会更新并添加键,但无法可靠地删除无效键。

Cleanup Heuristics

清理准则

  • Score files before cleanup waves instead of skimming randomly.
  • Use fresh
    lcov
    after each pass. Do not keep working from a stale hotspot map.
  • Rewrite large hotspot specs before chasing broad title debt. Bigger signal first.
  • Scan title debt across:
    • plain string titles
    • it.each(...)
      format strings
    • String.raw
      titles
    • snapshot keys derived from those titles
  • Scan for commented-out
    it
    ,
    test
    , and
    describe
    blocks during dead-spec cleanup waves.
  • End cleanup waves with repo scans for:
    • skipped tests
    • commented-out tests
    • cross-spec imports
    • placeholder titles
    • non-allowlisted
      createPlateEditor
      seams
  • Use
    bun run test:profile
    for the fast suite when deciding whether a spec belongs in the slow lane.
    pnpm test:slowest
    and
    pnpm check
    enforce those thresholds.
  • For rule-override hotspots, extract one editor helper and table-drive repeated node-type cases instead of cloning the same transform assertions.
  • For plugin-composition hotspots, extract helpers before adding more inline setup.
  • Adapt upstream invariants when local runtime semantics differ. Keep the invariant, rewrite the fixture around the real public contract.
  • Treat tiny one-branch crumbs as crumbs. Do not let a coverage number talk you into fake work.
  • Penalize giant files with poor test ROI unless they hold a central contract you actually care about during the next rewrite.
  • 在清理之前先对文件评分,而非随机浏览。
  • 每个阶段结束后使用最新的
    lcov
    报告。不要基于过时的热点图开展工作。
  • 在处理宽泛标题债务之前重写大型热点测试。先处理更重要的问题。
  • 检查以下内容的标题债务:
    • 纯字符串标题
    • it.each(...)
      格式字符串
    • String.raw
      标题
    • 从这些标题派生的快照键
  • 在无效测试清理阶段扫描注释掉的
    it
    test
    describe
    块。
  • 清理阶段结束后对仓库进行扫描,检查:
    • 跳过的测试
    • 注释掉的测试
    • 跨测试文件的导入
    • 占位标题
    • 未在允许列表中的
      createPlateEditor
      使用情况
  • 当决定某个测试是否属于慢速通道时,对快速套件使用
    bun run test:profile
    pnpm test:slowest
    pnpm check
    会强制执行这些阈值。
  • 对于规则覆盖的热点,提取一个编辑器工具函数并以表格驱动重复的节点类型用例,而非复制相同的转换断言。
  • 对于插件组合的热点,在添加更多内联设置之前提取工具函数。
  • 当本地运行时语义不同时,调整上游不变量。保留不变量,围绕真实公共契约重写测试用例。
  • 将微小的单分支代码块视为无价值内容。不要让覆盖率数值诱使你做无用功。
  • 除非大型文件包含你在下次重写时真正关心的核心契约,否则对投入产出比低的大型文件进行扣分。

Package Rules

包级规则

autoformat

autoformat

  • Use package-local rule arrays.
  • Use
    KEYS
    or base plugins, not React plugin
    .key
    .
  • Add only the base plugins a rule actually needs.
  • Collapse tiny mark or block suites into matrices when the contract is the same.
  • Do not import
    AutoformatKit
    or app registries in package tests.
  • If an
    autoformat
    case needs cross-package behavior like
    code-block
    wiring or app-owned integration setup, move it to
    apps/www/src/__tests__/package-integration
    instead of expanding
    packages/autoformat/package.json
    .
  • 使用包内本地规则数组。
  • 使用
    KEYS
    或基础插件,而非React插件的
    .key
  • 仅添加规则实际需要的基础插件。
  • 当契约相同时,将小型标记或块套件合并为矩阵。
  • 包测试中禁止导入
    AutoformatKit
    或应用注册表。
  • 如果
    autoformat
    用例需要跨包行为(如
    code-block
    连接或应用级集成设置),请将其移至
    apps/www/src/__tests__/package-integration
    目录,而非扩展
    packages/autoformat/package.json

markdown

markdown

  • Configure
    MarkdownPlugin
    locally in the package helper.
  • Do not import
    MarkdownKit
    or any app registry from
    apps/www
    .
  • Prefer direct string assertions for tiny whitespace-sensitive serializer outputs.
  • 在包工具函数中本地配置
    MarkdownPlugin
  • 禁止从
    apps/www
    导入
    MarkdownKit
    或任何应用注册表。
  • 对于微小的空格敏感序列化输出,优先使用直接字符串断言。

ai / streaming markdown

ai / streaming markdown

  • Keep one mixed-document smoke case.
  • Add a few explicit chunk-boundary tests.
  • Do not hide streaming behavior behind snapshots or giant hand-written trees.
  • 保留一个混合文档冒烟测试用例。
  • 添加几个明确的块边界测试。
  • 不要将流式行为隐藏在快照或大型手写树之后。

core

core

  • Use
    createSlateEditor
    for:
    • pure plugin option stores
    • selector extension
    • plugin API composition
    • transform composition
    • parser and deserializer contracts
    • HTML
      insertData
    • DnD-style contracts
  • Grow the compile-only type lane here first:
    • plugin creation
    • editor creation
    • inference
    • option merging
    • API merging
  • Port upstream Slate React invariants by behavior, not by file.
  • When a core source test mounts
    Plate
    while the same run also loads public-package React entrypoints, treat duplicate-instance warnings as test noise. Suppress them in the test wrapper with
    suppressInstanceWarning
    instead of changing runtime warning logic.
  • For provider-only React specs in core, reuse the shared
    packages/core/src/react/__tests__/TestPlate.tsx
    helper instead of re-declaring local
    const Plate = ...
    wrappers.
  • 使用
    createSlateEditor
    处理以下内容:
    • 纯插件选项存储
    • 选择器扩展
    • 插件API组合
    • 转换组合
    • 解析器与反序列化器契约
    • HTML
      insertData
    • 拖拽式契约
  • 优先在此处扩展仅编译型类型测试通道:
    • 插件创建
    • 编辑器创建
    • 类型推断
    • 选项合并
    • API合并
  • 按行为移植上游Slate React不变量,而非按文件移植。
  • 当核心源测试挂载
    Plate
    且同一运行还加载了公共包的React入口点时,将重复实例警告视为测试噪音。在测试包装器中使用
    suppressInstanceWarning
    抑制它们,而非修改运行时警告逻辑。
  • 对于核心中仅提供者的React测试,重用共享的
    packages/core/src/react/__tests__/TestPlate.tsx
    工具函数,而非重新声明本地的
    const Plate = ...
    包装器。

selection

selection

  • moveSelection
    and
    shiftSelection
    stay on Plate. They are genuinely Plate-bound exceptions, not cleanup debt.
  • moveSelection
    shiftSelection
    保留在Plate中。它们确实是Plate绑定的例外情况,而非需要清理的债务。

docx
,
docx-io
, and app integration

docx
,
docx-io
, 和应用集成

  • Keep app-owned cross-package integration tests under
    apps/www/src/__tests__/package-integration
    .
  • Keep buckets local under that folder instead of scattering app-owned integration coverage through
    src/lib
    .
  • Package tests must not pull app aliases, app kits, or registries into package graphs.
  • Fixture-heavy
    docx
    and
    docx-io
    suites are valid reasons to keep
    __tests__/
    .
  • 将应用级跨包集成测试放在
    apps/www/src/__tests__/package-integration
    目录下。
  • 将相关测试集中放在该目录下的子文件夹中,而非分散在
    src/lib
    中。
  • 包测试不得将应用别名、应用工具或注册表拉入包依赖图。
  • 用例密集的
    docx
    docx-io
    套件是保留
    __tests__/
    目录的合理理由。

slate

slate

  • Focus on pure editor, query, and transform behavior first.
  • Keep runtime coverage on navigation, selection math, structural queries, transform edge cases, extension transforms, and
    createEditor
    legacy sync.
  • Keep a small compile-only type lane for public
    @platejs/slate
    contracts.
  • Use selective upstream mining. Pull invariants that cheaply improve local public-contract coverage; do not mirror upstream blindly.
  • Add direct helper specs for custom Slate code when indirect coverage is lying.
  • Use
    lcov
    as package truth. Bun’s text coverage summary is noisy for targeted package runs.
  • Stop once the remaining misses are mostly deferred DOM wrappers plus low-risk non-DOM dust.
  • Later utility and core work should mine these upstream
    slate-react
    invariants:
    • use-slate-selector
      : selector equality and stale-rerender prevention
    • use-slate
      : editor version and subscription behavior
    • use-selected
      : selection rerender and path stability
    • editable
      : value-change vs selection-change partitioning
    • decorations
      : decoration propagation and redecorate behavior
    • chunking
      : chunk or index invalidation only if remaining core gaps justify it
  • Skip
    react-editor
    DOM focus coverage unless a real Plate bug forces it.
  • Playwright example coverage stays out.
  • 优先关注纯编辑器、查询和转换行为。
  • 在导航、选择计算、结构查询、转换边界情况、扩展转换和
    createEditor
    遗留同步方面保持运行时覆盖。
  • 为公共
    @platejs/slate
    契约保留一个小型的仅编译型类型测试通道。
  • 选择性地借鉴上游内容。引入能低成本提升本地公共契约覆盖率的不变量;不要盲目镜像上游内容。
  • 当间接覆盖不准确时,为自定义Slate代码添加直接的工具函数测试。
  • lcov
    作为包级的真实依据。Bun的文本覆盖率摘要在针对特定包运行时存在噪音。
  • 当剩余未覆盖部分主要为延迟处理的DOM包装器以及低风险的非DOM冗余代码时即可停止。
  • 后续工具和核心工作应借鉴这些上游
    slate-react
    不变量:
    • use-slate-selector
      :选择器相等性和防止陈旧重渲染
    • use-slate
      :编辑器版本和订阅行为
    • use-selected
      :选择重渲染和路径稳定性
    • editable
      :值变更与选择变更的分区
    • decorations
      :装饰传播与重新装饰行为
    • chunking
      :仅当核心剩余缺口需要时才处理块或索引失效
  • 除非真实的Plate bug要求,否则跳过
    react-editor
    DOM焦点覆盖。
  • Playwright示例测试覆盖不纳入此处。

Reviewed Exceptions

已审核例外情况

createPlateEditor
allowlist

createPlateEditor
允许列表

Keep
createPlateEditor
when the contract is actually about:
  • React or provider wiring
  • rendered output or DOM behavior
  • store rerender semantics
  • Plate plugin conversion boundaries
  • the known Plate-only selection APIs:
    moveSelection
    and
    shiftSelection
Do not treat these files as backlog just because they still use Plate.
当契约实际涉及以下内容时,保留
createPlateEditor
的使用:
  • React或提供者连接
  • 渲染输出或DOM行为
  • 存储重渲染语义
  • Plate插件转换边界
  • 已知的Plate专属选择API:
    moveSelection
    shiftSelection
不要仅因为这些文件仍使用Plate就将其视为待办事项。

__tests__/
allowlist

__tests__/
允许列表

Keep
__tests__/
when it holds:
  • package-local helpers or fixture banks
  • intentionally split multi-file suites like
    withAutoformat
  • fixture-heavy integration suites like
    docx
    and
    docx-io
  • app-owned cross-package integration suites under
    apps/www/src/__tests__/package-integration
__tests__/
目录包含以下内容时,保留该目录:
  • 包内本地工具函数或测试用例库
  • 有意拆分的多文件套件(如
    withAutoformat
  • 用例密集的集成套件(如
    docx
    docx-io
  • apps/www/src/__tests__/package-integration
    下的应用级跨包集成套件

Quick Reference

快速参考

  • Start with the smallest seam that proves the contract:
    createEditor
    ->
    createSlateEditor
    ->
    createPlateEditor
    .
  • Work in passes:
    >= 6
    first, rerun coverage, then worthwhile
    >= 5
    , then switch to architecture-safety targets.
  • Use
    bun run test
    for the fast default loop. Use
    pnpm test:all
    for the full suite.
  • Use
    bun run test:profile
    to inspect the fast loop and
    bun run test:slowest
    to enforce it.
  • pnpm test:slowest
    has two bands: warning zone for local drift and hard CI failure thresholds. Fix the warning zone before it becomes a PR failure.
  • Use Bun globals. Do not import them from
    bun:test
    .
  • Keep specs beside the implementation. Use
    __tests__/
    only for helpers, fixtures, or intentional split or integration suites.
  • Use plain objects for simple state. Use JSX hyperscript only when tree or selection shape is the contract.
  • Prefer explicit assertions. Use render-returned queries over
    screen
    , and use direct style-property assertions over
    toHaveStyle
    .
  • Delete skips, commented tests, dead smoke tests, and stale snapshot files after broad title renames.
  • Package tests must stay package-local. No app registries, no app kits, no cross-spec imports.
  • For package-only coverage decisions, trust
    lcov
    , not Bun’s broad text summary.
  • Keep exactly two lanes:
    • fast lane:
      *.spec.ts[x]
      , run by
      pnpm test
    • slow lane:
      *.slow.ts[x]
      , run by
      pnpm test:slow
  • Use
    pnpm test:all
    for the full repo test run instead of relying on bare
    bun test
    .
  • Stop before 100%. When the remaining misses are wrappers, DOM/provider dust, sludge, or crumbs, you are done.
<!-- cross-ref:start -->
  • 从能验证契约的最小边界开始:
    createEditor
    ->
    createSlateEditor
    ->
    createPlateEditor
  • 分阶段推进:先处理
    >= 6
    的文件,重新生成覆盖率报告,再处理有价值的
    >= 5
    的文件,最后转向架构安全目标。
  • 使用
    bun run test
    作为默认的快速内循环命令。使用
    pnpm test:all
    运行完整套件。
  • 使用
    bun run test:profile
    检查快速内循环,使用
    bun run test:slowest
    强制执行速度阈值。
  • pnpm test:slowest
    有两个区间:本地漂移警告区间和CI失败硬性阈值。在其成为PR失败原因之前修复警告区间的问题。
  • 使用Bun全局变量。不要从
    bun:test
    导入它们。
  • 测试文件与实现文件放在一起。仅在工具函数、测试用例或有意拆分的集成套件等情况下使用
    __tests__/
    目录。
  • 简单状态使用普通对象。仅当树形或选择器形状是契约内容时才使用JSX超脚本。
  • 优先使用显式断言。优先使用渲染返回的查询而非
    screen
    ,优先使用直接样式属性断言而非
    toHaveStyle
  • 在宽泛标题重命名后删除跳过的测试、注释的测试、无效冒烟测试和陈旧快照文件。
  • 包测试必须保持包内本地化。禁止导入应用注册表、应用工具或跨测试文件导入。
  • 对于仅包级的覆盖率决策,信任
    lcov
    而非Bun的宽泛文本摘要。
  • 仅保留两个测试通道:
    • 快速通道:
      *.spec.ts[x]
      ,由
      pnpm test
      运行
    • 慢速通道:
      *.slow.ts[x]
      ,由
      pnpm test:slow
      运行
  • 使用
    pnpm test:all
    运行全仓库测试,而非依赖裸命令
    bun test
  • 不要追求100%覆盖率。当剩余未覆盖部分为包装器、DOM/提供者冗余代码、冗余文件或小代码块时,即可停止。
<!-- cross-ref:start -->

See also (related skills — Testing (project-level) family)

另请参阅(相关技能——项目级测试系列)

If your issue relates to:
  • Python pytest discipline — isolation, coverage, mocks — check
    testing-strategy
    if appropriate.
  • audit the whole test suite — rerun coverage, stale debt — check
    testing-review
    if appropriate.
<!-- cross-ref:end -->
如果你的问题涉及:
  • Python pytest规范——隔离、覆盖率、模拟——如有需要,请查看
    testing-strategy
  • 审核整个测试套件——重新生成覆盖率、处理陈旧债务——如有需要,请查看
    testing-review
<!-- cross-ref:end -->