close

Vue

本指南介绍如何使用 Rstest 测试 Vue 应用和组件。Rstest 支持在多种场景中测试 Vue:

  • Node(使用 happy-dom 或 jsdom):在 Node.js 中使用模拟 DOM 进行快速、轻量的测试
  • 浏览器模式:使用 Playwright 进行真实浏览器测试,获得准确的 DOM 行为

Node 测试

基于 Node 的测试使用 DOM 模拟器如 happy-domjsdom 在 Node.js 中提供 DOM 环境。这种方式更快,适用于大多数组件测试场景。

快速开始

1. 安装依赖

npm
yarn
pnpm
bun
deno
npm add @rstest/core @rsbuild/plugin-vue @vue/test-utils happy-dom -D

如果需要使用 Vue JSX,还需安装:

npm
yarn
pnpm
bun
deno
npm add @rsbuild/plugin-babel @rsbuild/plugin-vue-jsx -D

2. 配置 rstest

创建 rstest.config.ts

rstest.config.ts
import { pluginVue } from '@rsbuild/plugin-vue';
import { defineConfig } from '@rstest/core';

export default defineConfig({
  plugins: [pluginVue()],
  testEnvironment: 'happy-dom',
});

如需支持 Vue JSX:

rstest.config.ts
import { pluginBabel } from '@rsbuild/plugin-babel';
import { pluginVue } from '@rsbuild/plugin-vue';
import { pluginVueJsx } from '@rsbuild/plugin-vue-jsx';
import { defineConfig } from '@rstest/core';

export default defineConfig({
  plugins: [
    pluginBabel({
      include: /\.(?:jsx|tsx)$/,
    }),
    pluginVue(),
    pluginVueJsx(),
  ],
  testEnvironment: 'happy-dom',
});

3. 编写第一个测试

test/App.test.ts
import { expect, test } from '@rstest/core';
import { mount } from '@vue/test-utils';
import App from '../src/App.vue';

test('renders correctly', () => {
  const wrapper = mount(App);
  expect(wrapper.text()).toContain('Hello World');
});

测试组件

使用 @vue/test-utils 挂载和交互组件:

test/Counter.test.ts
import { expect, test } from '@rstest/core';
import { mount } from '@vue/test-utils';
import Counter from '../src/Counter.vue';

test('increments counter on click', async () => {
  const wrapper = mount(Counter);

  expect(wrapper.text()).toContain('Count: 0');

  await wrapper.find('button').trigger('click');
  expect(wrapper.text()).toContain('Count: 1');
});

测试事件

test/Button.test.ts
import { expect, test } from '@rstest/core';
import { mount } from '@vue/test-utils';
import Button from '../src/Button.vue';

test('emits click event', async () => {
  const wrapper = mount(Button);

  await wrapper.find('button').trigger('click');
  expect(wrapper.emitted('click')).toBeTruthy();
  expect(wrapper.emitted('click')).toHaveLength(1);
});

测试 Vue JSX 组件

Vue JSX 组件的测试方式与 SFC 组件相同:

test/JsxComponent.test.ts
import { expect, test } from '@rstest/core';
import { mount } from '@vue/test-utils';
import App from '../src/App.tsx';

test('renders JSX component correctly', async () => {
  const wrapper = mount(App);

  await wrapper.find('button').trigger('click');
  expect(wrapper.emitted('clickApp')).toBeTruthy();
});

模拟模块

使用 rs.mock() 模拟依赖:

test/UserProfile.test.ts
import { expect, rs, test } from '@rstest/core';
import { mount, flushPromises } from '@vue/test-utils';
import UserProfile from '../src/UserProfile.vue';

rs.mock('../src/api', () => ({
  fetchUser: () => Promise.resolve({ name: 'John Doe' }),
}));

test('renders user name', async () => {
  const wrapper = mount(UserProfile, {
    props: { userId: '1' },
  });

  await flushPromises();
  expect(wrapper.text()).toContain('John Doe');
});

浏览器模式测试

对于需要真实浏览器行为的场景(例如 CSS 渲染、Web API、视觉测试),使用 Rstest 的浏览器模式配合 Playwright。

详细的配置说明请参阅浏览器测试 - 快速开始

Info

浏览器模式目前仅对 React 提供开箱即用的支持,Vue 的浏览器模式支持将在未来添加。

建议:

  • 使用 Node 测试 进行单元测试、逻辑密集型组件和快速反馈
  • 使用 浏览器模式 进行集成测试、视觉行为测试以及需要真实浏览器 API 的场景

示例项目

  • vue - 使用 happy-dom 的 Vue 测试(包含 SFC 和 JSX 测试)