WXT浏览器插件开发中文教程(26)----单元测试与E2E测试

前言

大家好,我是倔强青铜三 。是一名热情的软件工程师,我热衷于分享和传播IT技术,致力于通过我的知识和技能推动技术交流与创新,欢迎关注我,微信公众号:倔强青铜三。欢迎点赞、收藏、关注,一键三连!!!

单元测试 ​

Vitest ​

WXT 为 Vitest 提供了顶级支持,用于单元测试:

ts 复制代码
// vitest.config.ts
import { defineConfig } from 'vitest/config';
import { WxtVitest } from 'wxt/testing';
export default defineConfig({
  plugins: [WxtVitest()],
});

此插件执行以下操作:

  • 使用内存实现的扩展 API browser,通过 webext-core.aklinker1.io/fake-browse... 提供的 @webext-core/fake-browser 进行 polyfill
  • 添加 wxt.config.ts 中的所有 Vite 配置或插件
  • 配置自动导入(如果启用)
  • 应用内部 WXT Vite 插件,例如 wxt.dev/guide/essen... 中的远程代码打包
  • 设置 WXT 提供的全局变量(import.meta.env.BROWSER、import.meta.env.MANIFEST_VERSION、import.meta.env.IS_CHROME 等)
  • 配置别名(@/*、@@/* 等),以便解析导入

以下是一些设置了单元测试的真实项目。查看代码和测试,了解它们的编写方式。

示例测试 ​

此示例展示了在测试中无需模拟 browser.storage(由 wxt/utils/storage 使用)------webext-core.aklinker1.io/fake-browse... 提供的 @webext-core/fake-browser 在内存中实现了存储功能,因此其行为与真实扩展中一致!

ts 复制代码
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);
  });
});

模拟 WXT API [​](#模拟 WXT API "#%E6%A8%A1%E6%8B%9F-wxt-api")

首先,您需要了解 #imports 模块的工作方式。当 WXT(以及 Vitest)在预处理步骤中看到此导入时,导入将被替换为指向其"真实"导入路径的多个导入。

例如,这是您在源代码中编写的内容:

ts 复制代码
// 您编写的代码
import { injectScript, createShadowRootUi } from '#imports';

但 Vitest 看到的是:

ts 复制代码
import { injectScript } from 'wxt/browser';
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.dev/guide/essen... 中的 wxt prepare。

其他测试框架 ​

如果要使用其他框架,您可能需要禁用自动导入,设置导入别名,手动模拟扩展 API,并设置测试环境以支持您使用的 WXT 的所有功能。

这是可能的,但需要更多的设置。可以参考 Vitest 的设置,了解如何设置测试环境:

github.com/wxt-dev/wxt...

E2E 测试 [​](#E2E 测试 "#e2e-testing")

Playwright ​

Playwright 是编写 Chrome 扩展端到端测试的唯一好选择。

要为您的项目添加 E2E 测试,请遵循 Playwright 的 Chrome 扩展文档。当您需要传递扩展的路径时,请传递输出目录,/path/to/project/.output/chrome-mv3。

完整的示例请参考 WXT 的 Playwright 示例。

最后感谢阅读!欢迎关注我,微信公众号 :倔强青铜三。欢迎点赞、收藏、关注,一键三连!!!

相关推荐
FungLeo5 小时前
成为全栈·React 管理后台篇·总复盘:从“接口能调通”到“后台值得使用”
前端·react.js·前端框架·项目复盘·成为全栈
Csvn6 小时前
并发模式:让渲染学会排队、插队和让路
前端
可乐鸡翅yeah_7 小时前
新手梳理:M3U8 线上问题,哪些是前端锅,哪些是后端锅
前端·ios·音视频·实时音视频·m3u8·音视频在线播放
Flynt7 小时前
Linear 用 1000 个 PR 换掉 styled-components,我写了 200 个按钮,把这笔账复现了一遍
前端·css·preact
JavaGuide8 小时前
NVIDIA 又开源了!这次给 AI Agent 加上权限管控
前端·后端
excel8 小时前
prisma 如何处理数据库竞态
前端·数据库·后端
莪_幻尘9 小时前
Skill 体检:30 个 Skill 全凭感觉?体检器先自曝了 8 个“假 0 分
前端·人工智能·llm
风骏时光牛马9 小时前
AI模型综合能力评测:性能、指令遵循与多场景实测对比
前端
Frag0ut9 小时前
Chrome与Chromium内核浏览器在Windows 11上的新特性全景解析
前端·chrome·windows·web安全·chromium·gemini ai·playready drm
hiahiahia12310 小时前
实现完整 Tool Dispatcher
开发语言·前端