Skip to content

单位测试

目录

Vitest 插件

WXT 提供了对 Vitest 的一级支持,以实现单元测试:

typescript
// vitest.config.ts
import { defineConfig } from 'vitest/config';
import { WxtVitest } from 'wxt/testing';

export default defineConfig({
  plugins: [WxtVitest()],
});

该插件执行以下操作:

  • 替代了扩展 API browser,使用内存中的实现进行了仿射(基于 @webext-core/fake-browser
  • 将所有 Vite 配置或插件添加到 wxt.config.ts
  • 配置自动生成导入(如果启用)
  • 安装 WXT 内置的 Vite 插件,例如 远程代码打包
  • 设置了由 WXT 提供的全局变量(import.meta.env.BROWSERimport.meta.env.MANIFEST_VERSION 等等)
  • 配置了类似 @/*, @@/* 的前缀,以便于导入

以下是使用了单元测试配置的真实项目。请查看代码和测试文件以了解它们是如何书写的。

示例测试

此示例展示了无需为 wxt/storage 模拟 browser.storage(在测试中使用的)——@webext-core/fake-browser 在内存中实现了存储,因此其行为与实际扩展中的情况类似。

typescript
import { describe, it, expect } from 'vitest';
import { fakeBrowser } from 'wxt/testing';

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);
  });
});

其他测试框架

要使用其他测试框架,您可能需要禁用自动生成导入、配置前缀、手动模拟扩展 API,并设置测试环境以支持您使用的 WXT 的所有功能。

这是可行的,但需要更多的配置。请参考 Vitest 的设置示例,了解如何设置测试环境:

https://github.com/wxt-dev/wxt/blob/main/packages/wxt/src/testing/wxt-vitest-plugin.ts