单元测试
Vitest
WXT 为 Vitest 提供了一流的单元测试支持:
ts
// vitest.config.ts
import { defineConfig } from 'vitest/config';
import { WxtVitest } from 'wxt/testing/vitest-plugin';
export default defineConfig({
plugins: [WxtVitest()],
});该插件做了以下几件事:
- 使用
@webext-core/fake-browser的内存实现来 polyfill 扩展 APIbrowser - 添加
wxt.config.ts中的所有 Vite 配置或插件 - 配置自动导入(如果启用)
- 应用 WXT 内部 Vite 插件,用于处理打包远程代码等功能
- 设置 WXT 提供的全局变量(
import.meta.env.BROWSER、import.meta.env.MANIFEST_VERSION、import.meta.env.IS_CHROME等) - 配置别名(
@/*、@@/*等),以便正确解析导入路径
以下是已配置单元测试的真实项目,可以参考它们的代码和测试了解具体写法。
测试示例
此示例演示了在测试中无需模拟 browser.storage(由 wxt/utils/storage 使用)—— @webext-core/fake-browser 在内存中实现了 storage,其行为与真实扩展中的表现一致!
ts
import { describe, it, expect } from 'vitest';
import { fakeBrowser } from 'wxt/testing/fake-browser';
const accountStorage = storage.defineItem<Account>('local:account');
async function isLoggedIn(): Promise<Account> {
const value = await accountStorage.getValue();
return value != null;
}
describe('isLoggedIn', () => {
beforeEach(() => {
// 参见 https://webext-core.aklinker1.io/fake-browser/reseting-state
fakeBrowser.reset();
});
it('当存储中存在账户时应返回 true', async () => {
const account: Account = {
username: '...',
preferences: {
// ...
},
};
await accountStorage.setValue(account);
expect(await isLoggedIn()).toBe(true);
});
it('当存储中不存在账户时应返回 false', async () => {
await accountStorage.deleteValue();
expect(await isLoggedIn()).toBe(false);
});
});模拟 WXT API
首先,你需要了解 #imports 模块的工作原理。当 WXT(和 Vitest)在预处理阶段遇到此导入时,该导入会被替换为多个指向"真实"导入路径的导入语句。
例如,这是你在源代码中编写的内容:
ts
// 你编写的代码
import { injectScript, createShadowRootUi } from '#imports';但 Vitest 看到的是:
ts
import { injectScript } from 'wxt/utils/inject-script';
import { createShadowRootUi } from 'wxt/utils/content-script-ui/shadow-root';因此在这种情况下,如果你想模拟 injectScript,需要传入 "wxt/utils/inject-script",而不是 "#imports"。
ts
vi.mock("wxt/utils/inject-script", () => ({
injectScript: ...
}))请参考项目中的 .wxt/types/imports-module.d.ts 文件来查找 #imports 的真实导入路径。如果该文件不存在,请运行 wxt prepare。
其他测试框架
如果使用其他框架,你可能需要禁用自动导入、设置导入别名、手动模拟扩展 API,并配置测试环境以支持你使用的所有 WXT 功能。
这是可以实现的,但需要更多的配置工作。请参考 Vitest 的配置作为搭建测试环境的示例:
https://github.com/wxt-dev/wxt/blob/main/packages/wxt/src/testing/wxt-vitest-plugin.ts