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 测试)