Vitest 4.0 重磅发布:Browser Mode 正式稳定,前端测试进入新纪元

大家好,我是行业观察员,编程前线记者,程序员包打听,热衷于分享行业一手资讯。

如果本文能给你提供启发或帮助,欢迎动动小手指,一键三连 (点赞评论转发),给我一些支持和鼓励,谢谢。


10 月 22 日,前端测试框架 Vitest 4.0 正式发布!这是一个值得关注的重大版本更新,尤其是对于追求开发体验和测试效率的前端开发者来说。

作为目前前端领域最热门的测试框架之一,Vitest 凭借其极快的速度、简洁的 API 和对 Vite 生态的原生支持,已经成为越来越多开发者的首选。而 Vitest 4.0 的发布,更是带来了一系列令人兴奋的新特性。

让我们一起深入了解一下这次更新都带来了哪些重磅功能。

Browser Mode 正式稳定

这次最重磅的更新莫过于 Browser Mode(浏览器模式)正式移除 experimental 标签,进入稳定阶段

对于前端开发者来说,Browser Mode 的意义重大------它允许你在真实的浏览器环境中运行测试,而不仅仅是在 Node.js 环境的模拟器中。这意味着你可以测试那些依赖浏览器特定 API 的代码,比如 DOM 操作、localStorage、IndexedDB 等。

API 变更:更清晰的提供商配置

为了达到稳定状态,Vitest 4.0 对 Browser Mode 的 API 进行了重要调整:

之前的配置方式

typescript 复制代码
/// <reference path="@vitest/browser/providers/playwright" />

export default defineConfig({
    test: {
        browser: {
            provider: 'playwright',
            instances: [
                {
                    browser: 'chromium',
                    launch: {
                        slowMo: 100
                    }
                }
            ]
        }
    }
});

现在的配置方式

typescript 复制代码
import { defineConfig } from 'vitest/config';
import { playwright } from '@vitest/browser-playwright';

export default defineConfig({
    test: {
        browser: {
            provider: playwright({
                launchOptions: {
                    slowMo: 100
                }
            }),
            instances: [
                {
                    browser: 'chromium'
                }
            ]
        }
    }
});

新的方式需要单独安装提供商包:

  • @vitest/browser-playwright
  • @vitest/browser-webdriverio
  • @vitest/browser-preview

这样做的好处是配置更加清晰 ,不再需要添加 /// <reference> 注释,而且可以直接在提供商函数中配置选项。

导入路径简化

上下文导入也变得更简洁了:

typescript 复制代码
// 旧的导入方式
import { page } from '@vitest/browser/context';

// 新的导入方式
import { page } from 'vitest/browser';

test('example', async () => {
    await page.getByRole('button').click();
});

随着这些变更,@vitest/browser 包可以从依赖中移除了------它现在已经自动包含在每个提供商包中。

Visual Regression Testing(视觉回归测试)

Vitest 4.0 在 Browser Mode 中加入了视觉回归测试支持,这是一个让人期待已久的功能。

视觉回归测试可以捕获 UI 组件和页面的截图,然后与参考图像进行比较,以检测意外的视觉变化。这对于确保 UI 的一致性非常有用。

使用 toMatchScreenshot 断言

使用起来非常简单:

typescript 复制代码
import { expect, test } from 'vitest';
import { page } from 'vitest/browser';

test('hero section looks correct', async () => {
    // ...测试的其余部分

    // 捕获并比较截图
    await expect(page.getByTestId('hero')).toMatchScreenshot('hero-section');
});

Vitest 会自动捕获你指定元素的截图,并与之前保存的参考图像进行比较。如果有差异,测试就会失败。

新增 toBeInViewport 匹配器

同时还引入了 toBeInViewport 匹配器,用于检查元素是否在视口中:

typescript 复制代码
// 检查特定元素是否在视口中
await expect.element(page.getByText('Welcome')).toBeInViewport();

// 检查元素的 50% 是否在视口中
await expect.element(page.getByText('To')).toBeInViewport({ ratio: 0.5 });

这个功能基于 IntersectionObserver API,非常适合测试懒加载、无限滚动等场景。

Playwright Traces 支持

Vitest 4.0 开始支持生成 Playwright Traces(追踪记录),这对于调试失败的测试非常有帮助。

要启用追踪,你需要在 test.browser 配置中设置 trace 选项:

typescript 复制代码
export default defineConfig({
    test: {
        browser: {
            trace: 'on' // 可选值:'off', 'on-first-retry', 'on-all-retries', 'retain-on-failure'
        }
    }
});

或者通过命令行:

bash 复制代码
vitest --browser.trace=on

生成的追踪文件可以在 HTML reporter 中找到,你可以使用 Playwright Trace Viewer 打开它,查看测试执行的详细过程,包括每一步的截图、网络请求、控制台输出等。

Locator 改进

FrameLocator 支持

Vitest 4.0 新增了 page.frameLocator API(仅限 playwright 提供商),用于在 iframe 中查找元素:

typescript 复制代码
const frame = page.frameLocator(page.getByTestId('iframe'));

await frame.getByText('Hello World').click(); // ✅ 可以使用
await frame.click(); // ❌ 不可用

length 属性

每个 locator 现在都暴露了 length 属性,可以直接与 toHaveLength 匹配器配合使用:

typescript 复制代码
await expect.element(page.getByText('Item')).toHaveLength(3);

这使得测试列表、重复元素等场景变得更加简洁。

调试体验改进

Vitest 4.0 在调试方面也有显著提升:

  1. VSCode 扩展支持"Debug Test"按钮:在运行浏览器测试时,可以直接通过 VSCode 扩展的"Debug Test"按钮启动调试。

  2. --inspect 标志支持 :你可以使用 --inspect 标志启动 Vitest(支持 playwrightwebdriverio),然后手动连接到 DevTools。在这种情况下,Vitest 会自动禁用新的 trackUnhandledErrors 选项。

Type-Aware Hooks(类型感知钩子)

当使用 test.extend 扩展测试上下文时,现在可以在返回的 test 对象上直接引用生命周期钩子:

typescript 复制代码
import { test as baseTest } from 'vitest';

const test = baseTest.extend<{
    todos: number[];
}>({
    todos: async ({}, use) => {
        await use([]);
    }
});

// 与全局钩子不同,这些钩子能感知扩展的上下文
test.beforeEach(({ todos }) => {
    todos.push(1);
});

test.afterEach(({ todos }) => {
    console.log(todos);
});

这使得在使用扩展上下文时,钩子函数能够访问到自定义的测试上下文,类型安全性更好。

expect.assert

Vitest 一直导出 Chai 的 assert,但有时使用起来不太方便,因为很多模块都有相同的导出。

现在 Vitest 在 expect 上暴露了相同的方法,方便快速访问。这在需要缩小类型范围时特别有用,因为 expect.to* 方法不支持类型缩小:

typescript 复制代码
interface Cat {
    __type: 'Cat';
    mew(): void;
}
interface Dog {
    __type: 'Dog';
    bark(): void;
}
type Animal = Cat | Dog;

const animal: Animal = { __type: 'Dog', bark: () => {} };

expect.assert(animal.__type === 'Dog');
// 不会显示类型错误!
expect(animal.bark()).toBeUndefined();

expect.schemaMatching

Vitest 4.0 引入了一个新的非对称匹配器 expect.schemaMatching,它接受一个 Standard Schema v1 对象,并根据它验证值。

这个功能支持多种流行的 schema 验证库:

typescript 复制代码
import { expect, test } from 'vitest';
import { z } from 'zod';
import * as v from 'valibot';
import { type } from 'arktype';

test('email validation', () => {
    const user = { email: 'john@example.com' };

    // 使用 Zod
    expect(user).toEqual({
        email: expect.schemaMatching(z.string().email())
    });

    // 使用 Valibot
    expect(user).toEqual({
        email: expect.schemaMatching(v.pipe(v.string(), v.email()))
    });

    // 使用 ArkType
    expect(user).toEqual({
        email: expect.schemaMatching(type('string.email'))
    });
});

非对称匹配器可以在所有检查相等性的 expect 匹配器中使用,包括 toEqualtoStrictEqualtoMatchObjecttoContainEqualtoThrowErrortoHaveBeenCalledWithtoHaveReturnedWithtoHaveBeenResolvedWith

Reporter 更新

basic reporter 被移除

basic reporter 已被移除,你可以使用带有 summary: false 选项的 default reporter 代替:

typescript 复制代码
export default defineConfig({
    test: {
        reporters: [['default', { summary: false }]]
    }
});

default reporter 的改进

default reporter 现在在只有一个测试文件运行时,会始终以树状格式打印测试。如果你想始终以树状格式查看测试,可以使用新的 tree reporter。

verbose reporter 的行为变更

verbose reporter 现在会在测试完成时逐个打印测试结果。之前这种行为只在 CI 中启用,本地环境下 verbose 的行为与 default reporter 基本相同。

如果你想保持旧的行为,可以在配置中条件性地使用 verbose reporter:

typescript 复制代码
import { defineConfig } from 'vitest/config';

export default defineConfig({
    test: {
        reporter: process.env.CI ? 'verbose' : 'default'
    }
});

新增 API 方法

Vitest 4.0 带来了一些新的高级公共 API 方法:

  • experimental_parseSpecifications:允许你在不运行测试文件的情况下解析它
  • watcher:暴露了在禁用默认 Vitest 监视器时可以使用的方法
  • enableCoveragedisableCoverage:允许你动态启用和禁用覆盖率
  • getSeed:如果测试以随机顺序运行,返回 seed 值
  • getGlobalTestNamePattern:返回当前的测试名称模式
  • waitForTestRunEnd:返回一个 promise,在所有测试完成运行后解析

这些 API 为构建自定义测试工具和集成提供了更多可能性。

社区与生态

Vitest 4.0 是 640 多位贡献者、维护者以及翻译者共同努力的结果。值得一提的是:

写在最后

Vitest 4.0 的发布标志着这个年轻的测试框架又迈上了一个新台阶。

Browser Mode 的稳定 让在真实浏览器环境中测试成为标准实践,视觉回归测试 的加入填补了前端测试领域的重要空白,Playwright Traces 支持让调试变得更加直观,而各种 API 的改进则让开发体验更上一层楼。

如果你还在使用 Jest 或其他传统测试框架,不妨试试 Vitest。它不仅速度快、配置简单,现在还拥有了更强大的浏览器测试能力。

更多详细信息,可以查看:

前端测试的未来,看起来更加光明了。

相关推荐
BumBle5 小时前
UniApp 多页面编译优化:编译时间从10分钟到1分钟
前端
星链引擎5 小时前
大语言模型的技术突破与稳定 API 生态的构建
前端
还是大剑师兰特5 小时前
TypeScript 面试题及详细答案 100题 (71-80)-- 模块与命名空间
前端·javascript·typescript
BumBle5 小时前
使用 SortableJS 实现vue3 + Element Plus 表格拖拽排序
前端·vue.js·element
玉宇夕落5 小时前
HTML5 音乐敲击乐静态界面
前端
海在掘金611275 小时前
告别"拼写错误":TS如何让你的代码"字字精准"
前端
用户47949283569155 小时前
什么是XSS攻击,怎么预防,一篇文章带你搞清楚
前端·javascript·安全
摸着石头过河的石头5 小时前
深入理解JavaScript事件流:从DOM0到DOM3的演进之路
前端·javascript·性能优化
卡尔特斯6 小时前
油猴脚本支持的所有 UserScript
前端