news 2026/8/31 10:06:37

如何为 @pydantic/monty 编写 TypeScript 测试:vitest 与 WASM 测试矩阵实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
如何为 @pydantic/monty 编写 TypeScript 测试:vitest 与 WASM 测试矩阵实战指南

如何为 @pydantic/monty 编写 TypeScript 测试:vitest 与 WASM 测试矩阵实战指南

【免费下载链接】montyA minimal, secure Python interpreter written in Rust for use by AI项目地址: https://gitcode.com/GitHub_Trending/monty3/monty

monty是一个用 Rust 编写、专为 AI 场景打造的极简安全 Python 解释器,其 npm 包@pydantic/monty让你在 Node.js 中通过崩溃隔离的子进程 Worker、在浏览器中通过 Web Worker + WASM 安全地运行不可信 Python 代码。本文带你完整拆解crates/monty-js的 TypeScript 测试体系:如何用一套 vitest 配置矩阵,同时覆盖「Node 原生绑定、WASM 运行时、真实浏览器」三条执行路径。🧪


一、先看懂测试矩阵:三套 vitest 配置

@pydantic/monty的产物有三个入口,测试自然也要按入口分工。整个测试矩阵由三份 vitest 配置文件驱动:

配置文件覆盖范围运行命令前置条件
vitest.config.ts__test__/*.spec.ts(排除wasm_*.spec.tsnpm test已构建 NAPI 原生绑定
vitest.wasm.config.ts__test__/wasm_*.spec.tsnpm run test:wasm先执行npm run build:wasm
vitest.browser.config.ts__test__/*.spec.ts(排除node_*.spec.tsnpm run test:browser先构建 wasm,并安装 Playwright Chromium

👉 三套配置的关键区别只有一组include/exclude:默认套件刻意排除wasm_*用例(因为它需要预构建的monty_wasm_runtime.wasm),WASM 套件只跑wasm_*用例,浏览器套件则反向排除node_*用例(这些用例会读源码文件、执行 shell 命令,无文件系统的浏览器里跑不了)。

💡 三套配置都设置了fileParallelism: false和 120 秒超时——因为每个测试都在真实的隔离 Worker 子进程中执行 Python,宁可串行慢一点,也不要并行抢资源。


二、写第一个 spec:池化夹具 + 精简断言

所有 spec 文件都在 crates/monty-js/test/ 目录,共 23 个文件(如 basic.spec.ts、async.spec.ts、pool.spec.ts 等)。它们共享两个「地基」文件:

1️⃣ 池化夹具 helpers.ts

核心思想:每个 spec 文件只创建一个共享 Worker 池,并在beforeAll/afterAll中创建与关闭。setupPool()返回一个run辅助函数——在全新会话中执行一段 Python 代码并返回结果:

const { run, pool } = setupPool() test('simple expression', async () => { t.is(await run('1 + 2'), 3) })

需要直接管理会话(测试会话隔离、状态持久化等)时,用pool()拿到池子自行checkout()/close(),模式参考 basic.spec.ts 中的会话行为用例。

2️⃣ 精简断言 assertions.ts

没有直接使用expect,而是包了一层极简的t(is / deepEqual / throws / throwsAsync …),并额外提供:

  • throws/throwsAsync:同时断言错误类型instanceOf: MontySyntaxError)与消息,是测试解释器异常路径的主力工具;
  • assertMemoryError:校验MemoryError报错中的字节数,且容忍 1KB 误差——因为分配器基线在不同操作系统上会漂移几十个字节,精确匹配会让测试变成「平台专属」,这是跨平台测试很实用的一招。🎯

三、WASM 测试怎么写:先构建,再导入正确入口

WASM 套件(wasm_memory_limitwasm_type_checkwasm_word_size等 spec)有两个必须记住的约定:

  1. 必须先行构建 wasm 产物package.jsonbuild:wasm脚本会用wasm32-wasip1目标编译 monty-wasm-runtime,仓库顶层的 Makefile 提供了make test-wasm一键完成「构建 + 测试」:
make test-wasm
  1. /wasm入口导入 API,而不是包主入口。以 wasm_memory_limit.spec.ts 为例,它特意写import { Monty, MontyCrashedError } from '@pydantic/monty/wasm'——因为从主入口导入会拉进 NAPI 原生加载器,而 WASM 套件的环境里根本没有构建原生模块。

这套用例还示范了「崩溃语义」的测试写法:软性超限抛出可捕获的MontyRuntimeError(实例存活);硬性超限则 wasm 模块直接 trap,表现为MontyCrashedError——wasm 模块没有退出码,无法分类为 MemoryError,这正是与 Node 原生 Worker 路径的行为差异点,值得单独成用例。


四、浏览器测试:vitest browser + Playwright

vitest.browser.config.ts 展示了在无 Node 环境的浏览器中跑同一批用例的三件事:

  • 真实浏览器:启用@vitest/browser,provider 为playwright,headless Chromium 单实例;
  • 打桩node:内置模块:自定义 Vite 插件把所有node:开头的导入解析到 node-builtins-stub.ts(一个会抛错的桩),别名把@pydantic/monty/node指向 node-stubs.ts;
  • 排除 Node 专属用例exclude: ['__test__/node_*.spec.ts']

对应命令(Makefile 中会自动先装 Chromium):

make test-browser

⚠️ 一个容易踩的坑:浏览器模式下 Worker 数量受限,setupPool()内部会自动为 browser 环境加maxCheckoutsPerWorker: 1,见 helpers.ts。


五、跨环境通用技巧

  • 环境探测 + 条件跳过:env.ts 用typeof window判断运行环境,导出skipIfBrowser/skipIfNode。同一 spec 文件在 Node 套件和浏览器套件中都会执行,用它们让用例「各走各的路」,而不是拆成两份文件;
  • 会话一律close()归还:参考 basic.spec.ts 中try / finally的结构,避免会话泄漏影响后续用例;
  • 公开 API 契约测试:public_api.spec.ts 与 node_protocol_version.spec.ts 直接读取源码文件、断言导出面,保证包入口(././node/./wasm,见 package.json 的exports字段)不被意外破坏。

六、推荐运行顺序清单 ✅

步骤命令目的
1make install-js安装 JS 依赖
2npm test(在crates/monty-jsNode 原生路径全量回归
3make test-wasmWASM Worker 路径(Node 驱动,无需浏览器)
4make test-browser真实 Chromium 中的 WASM 路径

三条命令跑绿,才算一次完整的跨平台回归。


延伸阅读

  • 包使用与 API 文档:crates/monty-js/README.md
  • 测试支撑代码:crates/monty-js/test-support/
  • 浏览器 Worker 运行时源码:crates/monty-js/ts/worker/
  • WASM 运行时 crate:crates/monty-wasm-runtime/

总结一句话:一份用例、三套配置、两个共享地基(池化夹具 + 精简断言),就是@pydantic/monty用 vitest 同时守护 Node / WASM / 浏览器三条路径的完整秘诀。🚀

【免费下载链接】montyA minimal, secure Python interpreter written in Rust for use by AI项目地址: https://gitcode.com/GitHub_Trending/monty3/monty

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

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

华硕弘道AI笔记本实战:搭建贷后催收AI工作流指南

“周志”这个词,最初看到时我以为是某位同事的名字,后来才知道这是一个贷后管理项目的代号,也可以理解为“周度业绩日志”的简称。项目并不复杂,但有一个很有代表性的矛盾:流程本身非常成熟,话术模板、客户…

作者头像 李华
网站建设 2026/8/31 10:03:58

硬件面试通关指南:基础、项目复盘与排错技巧全解析

硬件面试不是把课本上的知识点背一遍就能通过的。真实面试里,面试官会围绕你的简历项目、常用接口、电源设计、信号完整性和一次真实的调试经历不断追问,直到确认你是在真正做硬件,而不是只会背结论。很多候选人在笔试环节能拿高分&#xff0…

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

10 分钟跑通 LocalAI:本地部署私有 AI 推理服务的完整指南

10 分钟跑通 LocalAI:本地部署私有 AI 推理服务的完整指南 【免费下载链接】LocalAI LocalAI is the open-source AI engine. Run any model - LLMs, vision, voice, image, video - on any hardware. No GPU required. 项目地址: https://gitcode.com/GitHub_Tre…

作者头像 李华
网站建设 2026/8/31 9:57:39

搜狗测开笔试编程题全解析:字符串、数组与测试思维

2019年的搜狗秋招测试工程师笔试,到现在还有人翻出来看,说明这个岗位的题目是真的有参考价值。先说清楚一件事:这里的"搜狗"是公司,不是输入法。搜狗的测试工程师岗在当年是很多人的目标,笔试分为多场&#…

作者头像 李华