测试
不用安装测试框架,也不用写配置:所有测试都是跑在公开入口上的普通 Node 脚本。
npm run lint # ESLint,flat config
npm test # 纯函数单测
npm run test:build # 构建 fixture 站点并断言产物
npm run test:browser # 在 Chromium 中实跑构建产物
npm run test:all # 以上四层按序全跑npm run test:browser 有两步前置:
npx playwright install chromium # 一次即可
npm run test:build # 先构建 fixture,每次改完源码都要重来浏览器层不会替你构建。 产物比 src/ 旧时它会直接报错退出,而不是拿上一次的产物 跑出一片绿 —— 否则「改了主题再跑浏览器层」永远测的是旧代码。
各层分别拦什么
| 层 | 文件 | 拦的问题 |
|---|---|---|
| Lint | eslint.config.js | 无用代码、Vue 模板写法错误 |
| 单测 | scripts/test.mjs | 纯逻辑错误:链接解析、slug、locale 匹配、标题树、阅读时间与字数 |
| 集成 | scripts/test-build.mjs | 接线错误:页面生成到了错误的 locale 下、链接指向没人创建的路由、标签链接逃出自己的 locale、分页页数两端不一致 |
| 浏览器 | scripts/test-browser.mjs | 运行时错误与位置错误:hydration 不一致、导航栏不吸顶、锚点落点在导航栏下方、目录高亮慢一格、重复/不可达的控件、抽屉不响应 Escape、配色图标与已绘制主题不符、组件名解析失败(只在 console 里,构建日志看不见) |
分层是刻意的。构建打印 success 也可能生成了一个没人链接的页面;链接正确的页面也可能 在客户端抛错;而没注册的组件既不会让构建失败,也不会产生坏链接 —— 它只在浏览器 console 里留下一行 warning,页面上那块是空的。1.5.0 修的 WCardList/WSteps 就是这一类。
更难的一类是元素都在、位置全错:粘性导航栏失效、锚点落点偏了一个导航栏的高度、 目录高亮慢一格。它们的 HTML 完全正确,静态检查全绿,只有把产物放进真浏览器、逐项量 getBoundingClientRect() 才看得见。浏览器层因此不只看「有没有元素」,还看 在哪里、可不可达、有几个。
当前规模:单元 26、集成 26、浏览器 28。
fixture 站点
test/i18n/ 是一个小站点,含一个嵌套 locale,并且挪走了自己的博客。这个形状刻意做得 别扭,因为它正是会压坏 locale 处理的形状:
test/i18n/docs/
├── posts/ # 4 篇英文文章,标签:shared / english / math / C++
├── guide/ # 含一个 js fence、一个无语言 fence
└── zh/
├── posts/ # 2 篇文章,标签:shared / C++ / 中文标签
└── guide/站点配置刻意做得别扭:每页 2 篇文章(于是分页与标签分页都会被压到)、关掉两个代码高亮器 (于是代码块是「没有包装元素」的那种形状)。
集成测试断言的其中几条:
- 根 locale 列表不含中文文章,尽管
/zh/posts/one.html同样以/开头 shared在两个 locale 中都存在,内容各不同,而不是一方偷走另一方的归档C++与非 ASCII 标签各自得到一个可访问的归档- 主页与标签页都被分页,且每个被链接的页数都真的存在
- 每个生成页面里的每个内链都指向真实存在的路由
- 站点里每一个
/tags/…链接都指向已生成的页面 - 某个 locale 内的标签链接永不指向另一个 locale 的归档
ClientOnly里的东西(页内目录、进度条)不在服务端 HTML 里- 组件正文被渲染成 markdown,而不是原样输出作者写的源码
WSteps的序号在服务端产物里正确递增- 文章以
<time>元素展示日期,并显示阅读时间
浏览器测试另加:
- 代码块有语言标签,点复制真的把片段(不是按钮文案)写进剪贴板
- 没有语言的 fence 有按钮、没有标签
- 进度条从 0 跟到 ≥0.9
- 抽屉打开后焦点移入、连按 40 次
Tab都不逃出去、关闭后焦点还给按钮 Escape关下拉但不关抽屉/zh/下的侧边栏与导航链接都留在/zh/内- 滚动后导航栏停在
top: 0(不吸顶会读到负值) - 页内目录的每一项:标题落在粘性导航栏下方 且 不会低到读不出是哪一节
- 高亮与读者所在章节一致 —— 直接按标题自己的锚点落点滚动,因此差几个像素就会红
- 320px 到 1920px 之间,没有任何元素被挤出视口(跳过自己有滚动条的代码块与表格), 且导航栏里的每个可见控件都在视口内
- 全站恰好一个返回顶部控件
- 首页、博客、404 都有
main#github-main-content,skip link 真的能跳进去 WSteps的序号在服务端产物里就是1/2/3/4,不是 hydration 之后才改正- 站点里不存在嵌套的
<a>
guide/long.md。overflow-x: hidden 会把 scrollWidth 一起截断,于是被挤出右边缘的控件不会 让断言失败。要遍历所有渲染盒,跳过「自己有滚动条」的容器(代码块、宽表格是应该能 横向滚的)。测试你自己的改动
scripts/test.mjs 是一串扁平的 test('名称', fn) 调用,加一条用例就是一行。优先测试 纯函数而不是组件:「能用」与「看起来能用」的分界线通常就是一个小函数,而它们正是 fixture 站点端到端压到的东西。
发布前的完整检查清单见发版 —— 四层测试只是其中一步, npm pack 的消费者实测同样不能省。
