2026/9/10 16:48:23

33-js-concepts 项目如何用 Vitest 为文档代码示例编写测试并运行

33-js-concepts 项目如何用 Vitest 为文档代码示例编写测试并运行 33-js-concepts 项目如何用 Vitest 为文档代码示例编写测试并运行【免费下载链接】33-js-concepts 33 JavaScript concepts every developer should know.项目地址: https://gitcode.com/GitHub_Trending/33/33-js-concepts33-js-concepts 项目把 33 个 JavaScript 概念文档里的代码示例当成可执行代码来对待每个概念文档中的console.log示例都要在tests/目录里有一份对应的断言测试来验证其行为。本文基于项目的 CONTRIBUTING.md、vitest.config.js 和 package.json说明如何按项目的规范为文档代码示例编写 Vitest 测试以及如何运行、观察这些测试。测试体系的配置依据在动手写测试之前先弄清项目里两个关键文件决定了测试的运行规则。vitest.config.js 的完整配置如下import { defineConfig } from vitest/config export default defineConfig({ test: { include: [tests/**/*.test.js], globals: false, environment: node } })这三项配置直接约束了测试文件的写法include: [tests/**/*.test.js]只有tests/目录下匹配*.test.js的文件会被执行新测试必须放在这个位置才会被收集globals: falsedescribe、it、expect不会自动注入全局作用域每个测试文件必须显式导入否则测试根本无法运行environment: node测试默认在 Node.js 环境运行document、window等浏览器对象不可用——这决定了 DOM 相关的文档示例需要特殊处理见下文。依赖方面package.json 在devDependencies中声明了三个包devDependencies: { vitest/coverage-v8: ^4.0.16, jsdom: ^27.4.0, vitest: ^4.0.16 }vitest是测试运行器jsdom用于个别需要 DOM 环境的测试vitest/coverage-v8提供覆盖率报告能力。首次拿到仓库后先运行npm install安装这些开发依赖再执行测试命令。测试的目录结构与命名规则CONTRIBUTING.md 规定测试按概念concept组织每个概念的测试放在以概念名命名的子目录中tests/ ├── call-stack/ │ └── call-stack.test.js ├── primitive-types/ │ └── primitive-types.test.js └── ...新增一个概念文档的代码示例时按同样的规则创建tests/{concept-name}/{concept-name}.test.js。当前仓库中实际的结构比示例更深一层例如tests/fundamentals/call-stack/、tests/async-javascript/callbacks/、tests/advanced-topics/error-handling/均遵循“按概念分组 {concept-name}.test.js命名”的约定。编写测试把 console.log 示例转成断言CONTRIBUTING.md 给出的核心规则是文档里用console.log展示输出测试里就必须用expect断言同一个输出。以 docs/concepts/primitive-types.mdx 开头的示例为例文档中是const str hello; console.log(typeof str); // string对应的测试写法就是把预期输出写成断言import { describe, it, expect } from vitest describe(Primitive Types, () { it(should return string type, () { expect(typeof hello).toBe(string) }) })第一行的显式导入是强制要求对应globals: false的配置。一个完整的测试文件可以参考 tests/fundamentals/call-stack/call-stack.test.js它把文档中“嵌套函数调用”的示例代码原样搬进it块最后用expect(printSquare(4)).toBe(16)验证示例声称的输出。错误路径用 toThrow 断言文档中“这个操作会抛出错误”的示例不能用普通断言覆盖CONTRIBUTING.md 要求使用expect(() { ... }).toThrow()。项目中实际用法见 tests/advanced-topics/data-structures/data-structures.test.jsconst weakMap new WeakMap() // Cannot use primitives as keys expect(() weakMap.set(string, value)).toThrow(TypeError)这里验证的正是文档里“WeakMap 的 key 必须是对象”这一行为说明。浏览器示例跳过或切换到 jsdom由于environment: node涉及document、window的文档示例默认无法测试CONTRIBUTING.md 的规则是跳过这类示例对应测试文件里保留纯 Node 可执行的.test.js不写 DOM 部分。如果确实需要为 DOM 示例写测试项目内的做法是创建单独的.dom.test.js文件并用 Vitest 的注释 pragma 把该文件切到 jsdom 环境。例如 tests/async-javascript/callbacks/callbacks.dom.test.js 的文件头/** * vitest-environment jsdom */ import { describe, it, expect, vi, beforeEach, afterEach } from vitest该文件在beforeEach里用document.createElement(button)构建 DOM 节点再用button.click()模拟事件验证文档中事件回调示例的输出。注意文件名必须仍然匹配*.test.js.dom.test.js满足否则不会被include规则收集。严格模式的行为差异CONTRIBUTING.md 特别提醒Vitest 以严格模式运行测试因此在非严格模式下“静默失败”的操作比如给只读属性赋值在测试中会抛出TypeError。写测试时如果某个示例在浏览器控制台里不报错、但测试里抛错了先按这条规则判断而不是怀疑文档示例写错。运行测试并验证结果package.json 的scripts提供了三个入口# 一次性运行全部测试 npm test # watch 模式文件变化后自动重跑 npm run test:watch # 运行测试并生成覆盖率报告 npm run test:coverage它们分别对应vitest run、vitest和vitest run --coverage。日常验证用npm test即可它会执行tests/下所有匹配*.test.js的文件任何一个断言与实际行为不符都会让对应测试失败失败信息中能看到具体是哪个describe/it块、哪一行expect不成立——据此回到对应概念文档核对示例代码。修改测试文件本身时npm run test:watch免去重复敲命令npm run test:coverage则用于查看哪些文档示例的行为被测试覆盖到。写作测试时的检查清单按 CONTRIBUTING.md 的规则新写一个测试文件前确认四件事文件位于tests/{concept-name}/下且命名为{concept-name}.test.js能被tests/**/*.test.js匹配第一行显式import { describe, it, expect } from vitest文档示例的每个预期输出都转成了expect断言错误路径用toThrow()涉及 DOM/window 的示例要么不写要么放进带vitest-environment jsdompragma 的.dom.test.js文件。全部满足后运行npm test全部通过即说明这批文档代码示例的行为与文档描述一致。【免费下载链接】33-js-concepts 33 JavaScript concepts every developer should know.项目地址: https://gitcode.com/GitHub_Trending/33/33-js-concepts创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考