news 2026/9/10 15:07:06

freeCodeCamp 课程挑战测试如何用 Vitest 运行?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
freeCodeCamp 课程挑战测试如何用 Vitest 运行?

freeCodeCamp 课程挑战测试如何用 Vitest 运行?

【免费下载链接】freeCodeCampfreeCodeCamp.org's open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp

freeCodeCamp 单仓中,课程挑战内容(curriculum/下的挑战 Markdown 与课程结构)由curriculum包内的一套 Vitest 测试来验证。当你修改了课程挑战文件、schema 或课程结构后,需要跑通这套测试确认没有破坏挑战的测试套件。测试入口是 curriculum/package.json 里的一组 pnpm 脚本。环境要求以 curriculum/package.json 的engines声明为准:Node.js>=24、pnpm>=10;curriculum 包使用 Vitest 4.1.5。

先理解测试被拆成了哪两个项目

curriculum/vitest.config.mjs 使用 Vitest 的 projects 模式,聚合了两个测试项目:

import { defineConfig } from 'vitest/config'; export default defineConfig({ test: { projects: ['vitest.tooling.config.mjs', 'src/test/vitest.config.mjs'] } });
  • 工具测试项目:vitest.tooling.config.mjs 只声明了exclude: ['src/test/blocks-generated/**/*.test.js', 'dist', 'node_modules'],用于运行 curriculum 工具代码(schema 校验、过滤器等)自身的测试。
  • 课程内容测试项目:src/test/vitest.config.mjs 只包含blocks-generated/**/*.test.jsenvironment: 'node'hookTimeout: 60000testTimeout: 30000isolate: false,并声明了globalSetup: 'vitest-global-setup.mjs'setupFiles: 'vitest-setup.mjs'。真正"运行课程挑战测试"的就是这个项目。

准备条件

课程内容测试的全局 setup(src/test/vitest-global-setup.mjs)在每次运行时做三件事:

  1. tools/client-plugins/browser-scripts/dist/js拷贝到src/test/stubs/js(先删除该目标目录再重建);
  2. 127.0.0.1:8080启动本地静态服务,用于向浏览器提供 test-runner 与 stubs 文件;
  3. 通过 Puppeteer 启动一个 headless Chrome(参数含--no-sandbox--disable-setuid-sandbox--disable-dev-shm-usage),并把连接地址导出为PUPPETEER_WS_ENDPOINT,供各测试池复用(src/test/vitest-setup.mjs 按VITEST_POOL_ID为每个池创建独立的 browser context)。

因此运行前需要满足:

  • 在仓库根目录安装依赖:

    pnpm install
  • tools/client-plugins/browser-scripts必须先构建出dist/js,否则全局 setup 没有可拷贝的产物。该包的构建脚本(tools/client-plugins/browser-scripts/package.json)是 webpack production 打包:

    cd tools/client-plugins/browser-scripts && pnpm build
  • Puppeteer 需要本地 Chrome 可执行文件,curriculum 包提供了安装脚本(即puppeteer browsers install chrome --force):

    cd curriculum && pnpm install-puppeteer
  • setup 使用固定端口127.0.0.1:8080,该端口被占用会导致本地服务无法监听,运行前先确认空闲。

需要注意的副作用:全局 setup 会删除并重建src/test/stubs/js;测试文件生成步骤会删除并重建src/test/blocks-generated目录。两者都是本地测试产物目录,不属于课程源文件。

生成 block 测试文件(test-gen)

课程内容测试不是直接指向挑战 Markdown,而是先为每个 block 生成一个测试文件:

cd curriculum pnpm test-gen

该脚本是tsx ./src/test/utils/generate-block-tests.ts(generate-block-tests.ts):解析课程结构后,为每个 block 在src/test/blocks-generated/下写出一个${block}.test.js,文件内容形如(文档示例):

import { defineTestsForBlock } from '../test-challenges.js'; await defineTestsForBlock({ "block": "basic-javascript" });

实际参数是JSON.stringify后的 filter 对象(含block字段)。成功后会打印Generated N block test file(s).,其中 N 为课程中的 block 数量。

真正的测试断言由 test-challenges.js 中的defineTestsForBlock提供:它使用 Vitest 的describe/it/expect,结合challenge-schema.jscurriculum-schema.jsmeta-schema.js等 Joi schema 校验挑战与课程结构,并通过 Puppeteer 浏览器执行挑战内嵌的测试代码(TypeScript 编译在测试中被 mock 为进程内编译,见该文件顶部的vi.mock)。

运行测试

curriculum/package.json 提供了四个脚本,按需选择:

命令实际执行适用场景
pnpm testNODE_OPTIONS='--max-old-space-size=7168' pnpm test-gen && vitest run完整运行两个项目(一次性验证)
pnpm test-contentpnpm test-gen && pnpm test --project test只验证课程内容测试项目
pnpm test-toolingpnpm test --project @freecodecamp/curriculum只验证工具代码测试项目
pnpm test:watchpnpm test-gen && vitest修改代码时的 watch 模式

在仓库根目录也可以用pnpm test-curriculum-content,它等价于turbo -F=@freecodecamp/curriculum test-content

最短主路径如下(按顺序执行):

pnpm install cd tools/client-plugins/browser-scripts && pnpm build cd ../.. cd curriculum && pnpm install-puppeteer pnpm test-content

其中pnpm install-puppeteer在本地已装好 Chrome 时可跳过;NODE_OPTIONS='--max-old-space-size=7168'已由test脚本内置,用于给整轮测试扩大 Node 堆内存,无需手动设置。

结果验证

  • test-gen阶段:输出Generated N block test file(s).,可对照src/test/blocks-generated/下的文件数量确认生成完整。
  • 测试阶段:vitest run结束时,输出中没有失败用例且进程退出码为 0 即为通过;若有挑战的测试用例失败,Vitest 会列出失败的测试文件与断言信息,退出码非 0。

排查与限制

  • 全局 setup 失败、浏览器侧加载不到 test-runner:先确认tools/client-plugins/browser-scripts/dist/js是否存在,不存在则回到准备条件中执行 browser-scripts 的构建。
  • Chrome 启动失败:执行pnpm install-puppeteer重新安装 Chrome 可执行文件。
  • 超时类失败:内容项目已把hookTimeout放宽到 60000、testTimeout到 30000 并关闭 isolate;整轮运行依赖--max-old-space-size=7168的堆内存配置,不要去掉它。
  • 课程内容项目只运行src/test/blocks-generated/下生成的文件;修改了curriculum/challenges/下的挑战文件后,重新运行pnpm test-content(它包含 test-gen)即可重新生成并执行测试。
  • 课程内容的浏览器执行路径依赖固定端口 127.0.0.1:8080 上的本地静态服务,测试运行期间该端口由 setup 占用,运行结束时 setup 的 teardown 会关闭浏览器与服务。

本地内容测试通过后,从仓库根目录执行pnpm test-curriculum-content可以复现与 turbo 构建链路一致的运行方式。

【免费下载链接】freeCodeCampfreeCodeCamp.org's open-source codebase and curriculum. Learn math, programming, and computer science for free.项目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 15:06:56

降AI率解读:为什么选降AI率工具必须看退款保障2026选购核心指南

降AI率解读:为什么选降AI率工具必须看退款保障2026选购核心指南 降AI率工具退款保障解读背后的机制,很多人说不清楚。这篇梳理清楚降AI率核心逻辑,以及针对性的解决方案。 主推嘎嘎降AI(www.aigcleaner.com)&#xf…

作者头像 李华
网站建设 2026/9/10 15:06:16

CANN/GE:模型图总数查询API

aclmdlBundleGetQueryModelNum 【免费下载链接】ge GE(Graph Engine)是面向昇腾的图编译器和执行器,提供了计算图优化、多流并行、内存复用和模型下沉等技术手段,加速模型执行效率,减少模型内存占用。 GE 提供对 PyTor…

作者头像 李华
网站建设 2026/9/10 15:05:31

游戏运营AI自动化:提升数据处理与玩家行为分析效率

1. 项目概述:当游戏运营遇上AI自动化这个项目本质上是一套为游戏运营团队设计的智能分析系统,它解决了两个核心痛点:一是通过自动化工具替代人工整理日报周报的重复劳动,二是利用AI问答技术快速洞察玩家行为规律。我在某MMORPG项目…

作者头像 李华
网站建设 2026/9/10 15:01:17

CANN/ge图引擎SetCustomValue API

SetCustomValue 【免费下载链接】ge GE(Graph Engine)是面向昇腾的图编译器和执行器,提供了计算图优化、多流并行、内存复用和模型下沉等技术手段,加速模型执行效率,减少模型内存占用。 GE 提供对 PyTorch、TensorFlow…

作者头像 李华