是否可以从 javascript 上下文测试 wasm-pack 生成的 WebAssembly?

sam*_*rts 9 javascript automated-tests rust wasm-pack

我有一个像这样的 Rust + wasm 项目:

wasm-pack-example/
  pkg/
    .gitignore
    package.json
    wasm_pack_example.d.ts
    wasm_pack_example.js
    wasm_pack_example_bg.d.ts
    wasm_pack_example_bg.js
    wasm_pack_example_bg.wasm
  src/
    lib.rs
  Cargo.toml
Run Code Online (Sandbox Code Playgroud)

pkg当我运行时,会构建wasm-pack build.

发出的 js 文件不是公共 rust 函数的简单传递 - wasm-pack 向它们添加了一些逻辑。它看起来很像公共 Rust 函数的内存管理包装器。

在我的项目中,我现在真正想做的是针对发出的 wasm 的 js 接口编写自动化测试。这就是我的应用程序所做的,这就是我需要测试的。我很高兴使用任何测试框架(我已经用玩笑做了很多这样的实验)。

我已经尝试了许多指南和工具来做到这一点,包括https://github.com/DrSensor/rs-jest,它很有前途,但缺乏测试 wasm-pack 生成的特定 js 接口的能力。另外,它似乎缺少我的特定库所需的东西,也许是我使用 wasm_bindgen 的特定方式。当根据 rs-jest 实例化 WebAssembly 时,我会看到TypeError: WebAssembly.instantiate(): Imports argument must be present and must be an object,如果我将一个空对象传递给实例化,我会看到TypeError: WebAssembly.instantiate(): Import #0 module="__wbindgen_placeholder__" error: module is not an object or function

我还尝试了一段时间来模拟浏览器使用 JsDom 获取和实例化 wasm 的特定方式。我生成了一个 index.html 文件,该文件通过脚本标记加载 wasm-pack js 文件,然后我使用该 index.html 文件创建了一个 JsDom 实例。它正确地尝试从 js 中的导入中获取 wasm(这要求我将自己的fetch实现添加到 JsDom 实例的窗口,从文件系统返回 wasm 文件),但随后在 js 文件中被阻塞,因为module.require不是功能。我无法再取得任何进展。

无论如何,这只是为了表明我还没有找到任何解决方案。有没有人能够针对 wasm-pack 生成的 js 接口编写自动化测试?

Lyn*_*ynn 1

我也有同样的情况。我使用 wasm-pack 和 Jest,但不使用 rs-jest。我只想针对 wasm-pack 生成的 JavaScript 包编写 Jest 测试。

我无法让我的测试与 Jest 一起使用,testEnvironment: "jsdom"并且wasm-pack build:Jest 会抱怨它无法在 上找到模块“foo_wasm”import * as wasm from "foo_wasm";

然而,testEnvironment: "node"在 jest.config.ts 中设置并运行wasm-pack build --target nodejs对我有用!

然而,我确实需要--target bundler我的网络应用程序。所以我运行 wasm-pack 两次:

wasm-pack build --target bundler --out-dir pkg  # (the defaults)
wasm-pack build --target nodejs --out-dir pkg_node
Run Code Online (Sandbox Code Playgroud)

然后在我的 package.json 中我指向捆绑器/Web 绑定:

{
  "dependencies": {
    "foo_wasm": "file:../wasm/foo/pkg",
  }
}
Run Code Online (Sandbox Code Playgroud)

在 jest.config.ts 中,我使用节点绑定覆盖它:

export default {
  moduleNameMapper: {
    foo_wasm: "<rootDir>/../wasm/foo/pkg_node",
  },
};
Run Code Online (Sandbox Code Playgroud)

然后在我的测试中我可以import * as wasm from "foo_wasm";

请参阅此 wasm-pack 问题,它将添加--target all这样我们就不必运行 wasm-pack 两次。