Clearly 测试策略揭秘:76个单元测试如何覆盖一个原生 UI 应用

发布时间:2026/10/13 16:49:22
Clearly 测试策略揭秘:76个单元测试如何覆盖一个原生 UI 应用
【免费下载链接】clearlyMarkdown editor for Mac, iOS and iPadOS项目地址https://gitcode.com/gh_mirrors/cle/clearly点击查看免费下载Clearly 是一款原生 Markdown 编辑器支持 Mac、iOS 和 iPadOS。很多人以为 UI 应用很难做单元测试但 Clearly 用 76 个单元测试稳稳地覆盖了它的核心逻辑——秘诀在于把纯逻辑从界面里彻底剥离出来。这篇指南带你拆解它的测试策略看完你会明白什么样的代码值得测什么样的代码应该放手。先看结论UI 应用真的能单元测试吗能前提是架构上做一个关键决策把不依赖系统的部分单独打包。Clearly 采用这样的结构 层位置内容可测试性核心包 ClearlyCorePackages/ClearlyCore/渲染、查找替换、状态、字数统计✅ 纯函数/纯输入输出全部单测应用 UI 层Clearly/SwiftUI 视图、NSTextView 封装、WKWebView 预览❌ 不写单测人工验证共享资源Shared/Resources/KaTeX、Mermaid、演示文档作为测试数据源核心包的定义在 Package.swift它声明了平台无关的库目标和测试目标ClearlyCoreTests依赖 GFM 渲染引擎cmark-gfm。测试总入口一条命令跑完 76 个用例所有测试集中在 Packages/ClearlyCore/Tests/ClearlyCoreTests/共14 个测试文件、76 个测试函数。运行方式极其简单swift test --package-path Packages/ClearlyCore项目文档 CLAUDE.md 中明确要求任意 commit 上全部约 76 个测试都应该是绿的——这是一条硬性质量红线。14 个测试文件的分工一览测试文件用例数覆盖模块MarkdownStatsTests.swift24字数统计剥离 Markdown 标记、选区统计、阅读时间MarkdownWikilinkTests.swift23[[wikilink]]渲染、表格内链接、代码区保护MarkdownMathTests.swift17公式渲染以及美元符号不是公式这类反例PreviewCSSTests.swift12预览样式表的结构不变量与主题一致性ExternalFileWatcherTests.swift13外部文件变更的合并决策与真实文件监听TextMatcherTests.swift9查找引擎边界、大小写、多行ReplaceEngineTests.swift7替换引擎正则捕获组、全量替换NavigationGuardTests.swift5关闭/切换文档前的保存决策ATXHeadingPrefixTests.swift4标题前缀识别1~6 级、Tab 分隔等MarkdownTOCTests.swift2[TOC]展开为导航FindStateTests.swift2查找栏导航状态StatusBarStateTests.swift2状态栏计数刷新BugReportURLTests.swift2反馈链接只预填安全字段LimitsTests.swift1文件打开大小限制含符号链接场景策略一正反双向测试用反例锁住渲染管线渲染层是 Clearly 的命脉Markdown 文本经过cmark-gfm生成 HTML再经过一条十步后处理管线数学公式、高亮、上下标、Emoji、TOC……管线细节见 docs/markdown-rendering-architecture.md。针对这种复杂管线测试采取正例 反例双向锁定正例$x^2$必须渲染成math-inline公式标签欧拉公式e^{iπ} 1 0也要能渲染反例句子 They went to a grocery store and spent$5.12on soda 里的美元符号绝不能被误判成公式——这正是 MarkdownMathTests.swift 中针对真实 bugissue #200写的回归测试顺序陷阱公式里的^不能被后续的上下标处理器再转一次issue #389所以专门有testCaretsInInlineMathAreNotSuperscripted这类用例锁住管线顺序。同样的思路用于[[wikilink]]23 个用例覆盖普通链接、别名、标题锚点、表格内不断行、代码围栏内保持字面量、CRLF 换行等边缘场景全部在 MarkdownWikilinkTests.swift 中。策略二用不变量约束样式表主题再改也不跑偏预览样式表 PreviewCSS.swift 是纯字符串很难单元测试项目给出的答案是测结构不变量。PreviewCSSTests.swift 的 12 个用例检查的是:root色板块必须声明全部 40 个 CSS 变量 token文字、链接、代码、callout、TOC……规则主体里不允许再出现#RRGGBB或rgba()硬编码字面量——防止颜色绕过主题 token 体系样式表必须同时输出浅色、prefers-color-scheme: dark、media print三套色板且打印模式与浅色在关键变量上必须不同导出模式PDF/剪贴板必须内联打印色板并携带结构性覆盖。这样即便未来大幅重构 CSS只要不变量还在深色/浅色/打印三个主题就不会悄悄失配。策略三把文件同步决策写成纯函数异步只测一次编辑器要处理文件被外部程序修改了怎么办。这个逻辑拆成两层纯决策函数mergeExternalChange输入磁盘内容 / 编辑器内容 / 上次已知磁盘内容三个字符串输出apply、ignoreEcho自己保存的回声或ignoreDirty用户有未保存修改。ExternalFileWatcherTests.swift 用十几个短字符串组合穷举决策矩阵还专门写了回归测试防止基线随每次击键前进导致脏检测失效的老 bug真实异步路径只测两条外部写入能触发回调、stop()之后回调彻底静默。测试用临时目录 defer清理模拟外部写入时用系统原生的NSFileCoordinator。策略四明确什么不测比测什么更重要CLAUDE.md 的 Testing 章节写得很直白该测ClearlyCore 中一切纯输入/纯输出的东西——解析器、渲染器、同步逻辑、查找替换。不该测SwiftUI 视图、NSTextView/UITextView 封装、WKWebView 预览渲染、AppKit 菜单接线。苹果的 UI 框架没法干净地单元测试那些靠跑应用人工验证。这条负面清单是整个策略能落地的关键不追求 100% 覆盖率而是把测试预算集中投在会随需求演进而腐化的逻辑上——渲染管线、字数统计、查找替换、文件同步决策。工程化细节还有两处值得借鉴新测试优先 Swift Testing新用例用Test#expect宏旧 XCTest 套件保留不重写两套框架共存黄金数据集做端到端参照Fixtures/ 下有一份 golden-queries.json包含 31 条手写检索查询配套golden-corpus/目录的 34 篇真实风格笔记技术、食谱、运动、日记都有。查询刻意不按笔记标题改写避免词汇泄露虚高召回指标是典型的 golden-corpus 评测数据设计。新手可以抄走的最小实践清单从 Clearly 的测试策略里普通开发者可以带走这五条 先拆架构再谈测试把纯逻辑放进独立的 Swift 包或模块UI 壳子保持哑给核心行为定死数字红线CLAUDE.md 里76 个测试必须全绿就是可执行的质量契约每个真实 bug 都留一个反例测试美元符号误判、公式管线顺序问题都变成了带 issue 编号的用例名对字符串资产CSS/HTML 模板测不变量而不是逐字符比对写清不测什么把 SwiftUI 视图、系统控件封装明确排除在单测范围外避免测试腐化。写在最后76 个测试对 Clearly 来说不是负担而是一张精准的保险网它不保护每一个像素却保护了每一次输入 Markdown → 输出正确渲染与状态的约定。对新手而言最大的收获或许是——单元测试的价值不在于数量而在于选对了值得测的那部分代码。赞分享【免费下载链接】clearlyMarkdown editor for Mac, iOS and iPadOS项目地址https://gitcode.com/gh_mirrors/cle/clearly点击查看免费下载相关推荐CVAT 接入第三方模型 4 步走零基础跑通 serverless 算法自动标注CVAT 接入第三方模型 4 步走零基础跑通 serverless 算法自动标注 本教程带你完成 CVAT 接入第三方模型 的完整链路启动 serverle数据标注计算机视觉数据集AI 应用后端前端Manim让数学动起来的动画引擎轻松创建惊艳数学可视化Manim让数学动起来的动画引擎轻松创建惊艳数学可视化 你是否曾经为如何生动展示数学概念而烦恼传统的静态图表难以表达函数的变换过程复杂的几何证明难以直观图形学音视频Snowflake测试策略85个Jest单元测试覆盖90%代码的秘诀Snowflake测试策略85个Jest单元测试覆盖90%代码的秘诀 Snowflake作为一个现代化的分布式ID生成器项目在测试策略上展现了专业水准。通过移动开发创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考