返回博客首页
← 所有文章

使用 Vitest 进行 NativeScript-Vue 单元测试

2023年12月8日 — 作者:Juan de Dios Martínez

NativeScript (NS) 是一个使用 JS/TS 构建原生应用程序的框架。如果我们将 NS 与 Vue 结合使用,我们可以构建高性能的原生应用程序,并且由于 NS、NS-Vue 和 Vue 的出色架构,我们可以像使用前端应用程序一样使用 Vue 依赖项。在本例中,我们重点关注使用 Vitest 进行单元测试,Vitest 是一个测试框架,它每天都在获得越来越多的关注,由 Vue 团队创建,但可以测试我们与它的老大哥 Vite 一起使用的几乎所有框架。

设置

首先,需要安装测试所需的依赖项。

npm i -D @types/[email protected] @vitejs/plugin-vue @vue/test-utils vitest jsdom

现在我们有了依赖项,就开始编写代码。在开始配置 vitest 之前,我们将创建两个文件用于配置测试。

首先,对于此示例,我们将在项目的根目录中创建 test 文件夹,并在其中添加我们的测试和通用配置的文件。在此文件夹中,我们创建文件 NSMockViews.ts,其中将包含 NativeScript 提供的视图数组。如果您有任何插件视图,可以将其添加到此列表中。我们将在 vitest 配置中使用此文件。

// test/NSMockViews.ts
export const NSMockViews = [
  'AbsoluteLayout',
  'ActionBar',
  'ActionItem',
  'ActivityIndicator',
  'Button',
  'ContentView',
  'DatePicker',
  'DockLayout',
  'FlexboxLayout',
  'FormattedString',
  'Frame',
  'GridLayout',
  'HtmlView',
  'Image',
  'Label',
  'ListPicker',
  'ListView',
  'NavigationButton',
  'Page',
  'Placeholder',
  'Progress',
  'ProxyViewContainer',
  'RootLayout',
  'ScrollView',
  'SearchBar',
  'SegmentedBar',
  'SegmentedBarItem',
  'Slider',
  'Span',
  'StackLayout',
  'Switch',
  'TabView',
  'TabViewItem',
  'TextField',
  'TextView',
  'TimePicker',
  'WebView',
  'WrapLayout',
  'Prop',
  'Template',
];

现在,我们将在 test 文件夹中创建 setup.ts 文件。在此文件中,我们使用 @vue/test-utils 模拟 nativescript-vue,并模拟 @nativescript/core

// test/setup.ts
import Vue from '@vue/test-utils';
import { vi } from 'vitest';

/* MOCK Vue & Nativescript */
vi.mock('nativescript-vue', () => Vue);
vi.mock('@nativescript/core', async () => {
  return {
    default: () => ({}),
    TouchManager: {},
  };
});

为了防止 TypeScript 在我们的测试中报错,我们将 test 文件夹添加到 tsconfig.json 文件的 include 部分。

// tsconfig.json
"include": [
    "src",
    "types",
+   "test"
],

完成所有测试的基本配置后,我们创建 vitest.config.ts 文件,vitest 将使用此文件来启动我们的测试。

// vitest.config.ts
import Vue from '@vitejs/plugin-vue';
import path from 'path';
import { defineConfig } from 'vitest/config';
import { NSMockViews } from './test/NSMockViews';

export default defineConfig({
  plugins: [
    Vue({
      template: {
        compilerOptions: {
          isCustomElement: (tag) =>
            NSMockViews.map((nsView) => nsView.toLowerCase()).includes(
              tag.toLowerCase()
            ),
        },
      },
    }),
  ],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src'),
      '~': path.resolve(__dirname, './src'),
    },
    extensions: ['.mjs', '.js', '.ts', '.json', '.vue'],
  },
  test: {
    globals: true,
    name: 'jsdom',
    environment: 'jsdom',
    setupFiles: ['test/setup.ts'],
  },
});

我们简要解释一下这里配置的内容

  • 我们使用 NSMockViews 告诉 vue NativeScript 组件是自定义元素。
  • 我们添加了默认的 NativeScript-Vue 别名,以便它可以解析我们应用程序的组件。
  • 我们指示测试的基本配置。

构建测试和运行

现在我们已经完成了所有配置。让我们继续创建一个基本组件,该组件将显示一个图标,以便稍后在此组件上进行测试。

// src/components/Icon.vue

<script lang="ts" setup>
const props = defineProps({ icon: String });
</script>

<template>
  <Label :text="props.icon" class="m-icon-round text-center"></Label>
</template>

让我们开始行动,进行我们的第一个测试。我们创建文件 test/components/icon.test.ts 并添加一些基本测试,例如检查组件是否接收 prop 以及 NS Label 视图是否包含我们传递给组件的文本。

// test/components/icon.test.ts
import Icon from '@/components/Icon.vue';
import { mount, VueWrapper } from '@vue/test-utils';
import { beforeEach, describe, expect, test } from 'vitest';

let wrapper: VueWrapper<any, any>;

beforeEach(async () => {
  wrapper = mount(Icon, {
    props: {
      icon: 'my-icon',
    },
  });
});

describe('Icon Component', async () => {
  test('mount component', async () => {
    expect(wrapper.html()).toBeTruthy();
  });

  test('should have icon as text', async () => {
    expect(wrapper.attributes('text')).toContain('my-icon');
  });

  test('should update icon ', async () => {
    expect(wrapper.attributes('text')).toContain('my-icon');
    await wrapper.setProps({ icon: 'updated-icon' });
    expect(wrapper.attributes('text')).toContain('updated-icon');
  });
});

我们已经完成了第一个测试。让我们将启动 vitest 的脚本添加到我们的 package.json 文件中。

"scripts": {
  "test": "vitest"
},

我们准备启动测试了,现在只需启动测试,您应该会看到 3 个测试通过。

npm run test

就是这样!我们只需要进行一些模拟并定义 NativeScript 视图为自定义元素。

这里我提供了一个带有基本项目的存储库,该项目已准备好使用 vitest 启动测试:https://github.com/vallemar/nativescript-vue-vitest

测试愉快!