vue単体テスト

はじめに: 単体テストはインターネット上にたくさんありますが、Vue の単体テストは非常に少ないですが、簡単に説明したビデオもいくつかあります。 , これは簡単な単体テストです。

理解できないかもしれないので、ここでは私自身のページの例は示しませんが、次のコード スニペットの一部はインターネットから取得したものになります。

1. ページを作成する

ルート ディレクトリで testing フォルダーを見つけ、iview ファイルの下に実際のテスト ファイルと同じパスのファイルを作成します。

たとえば、src/iview/Home に Home.vue があります。

次に、単体テストファイルは次のようにする必要があります。

テスト/iview/Home/Home.spec.js

ここに画像の説明を挿入します

外部の Home.vue をテストする必要がある場合は、自分のファイルの場所と同じファイルの場所が対応している必要があります。

注: テスト ファイルには、test.spec.js のファイル名に基づいた名前を付ける必要があります。

2. 各種ファイルをインポートする

@vue/test-utils を導入します (デフォルトでは、すでに @vue/test-utils がインストールされ、構成されています)

import {
    
     mount, flushPromises } from '@vue/test-utils'

コンポーネントのインポート (必須)

サブコンポーネント、カスタム コンポーネント、フレームワーク内のコンポーネント、または独自のファイルのいずれであっても、それらは 1 つずつ導入する必要があります。

import Home from '@/views/Home/Home.vue'            // 自身
import HomeTable from '@/components/HomeTable.vue'  // 子组件

要素を例としてコンポーネントを紹介します

import {
    
     ElMessageBox, ElTableColumn, ElTable } from 'element-plus'

インターフェースを導入します (必要な場合にのみ導入します。これは単なる拡張です)

import {
    
     tableList } from '@/api/index'

プラグインを導入します(必要な場合にのみ導入します。これは単なる拡張機能です)

lodash-es.js を例に挙げると、
lodash-es.js はさまざまな種類のデータを処理するプラグインです。たとえば、オブジェクトをディープ コピーする場合、従来の JS 処理は JSON.parse(JSON.stringify( ...)) をプロジェクトに追加しましたが、推奨されていないため、lodash-es.js を使用して処理します。詳細については、以前の記事を参照してください。

import {
    
     cloneDeep } from 'lodash-es'

ルートの導入 (必要な場合にのみ導入します。これは単なる拡張です)

import {
    
     useRouter } from 'vue-router'

Vuex を導入します (必要な場合のみ、これは単なる拡張機能です)

import {
    
     createStore } from 'vuex'

3. インポートした各種ファイルを呼び出す

関連するすべてのコンポーネントを呼び出します

const componentGlobal = {
    
    
  components: {
    
    
    'home-table': HomeTable,  // 组件
    ElMessageBox,             // element的组件(框架组件)
    ElTableColumn, 
    ElTable
  }
}

(偽の) データを返すインターフェースを作成する

const mockListData = {
    
    
  "phone": "1354490525",
  "isVip": 0,
  "createTime": "2021-12-06 00:00:00",
  "name": "测试人员1",
  "id": "h5214so514w1206",
  ...
}

const mockResponse = {
    
    
  data: {
    
    
    "msg": "success",
    "code": 200,
    "page": {
    
    
      "totalCount": 1,
      "pageSize": 10,
      "totalPage": 1,
      "currPage": 1,
      "list": [
        mockListData
      ]
    }
  }
}

モックインターフェース

上記データをリターンデータとして扱う

jest.mock('@/api/index', () => ({
    
    
  tableList: jest.fn(() => Promise.resolve(mockResponse)),
}))

ダイアログ ボックス/ルーティングのモック (一部のコンポーネントはノードを見つけられないため、モックする必要があります)

// mock 路由
jest.mock('vue-router', () => ({
    
    
  useRouter: jest.fn(() => ({
    
    
    push: () => ({
    
    })
  }))
}))
// mock 对话框 (他是通过 ElMessageBox. 弄出来,并没有把节点写在页面上,所以需要mock)
jest.mock('element-plus', () => ({
    
    
  ...jest.requireActual('element-plus'),
  ElMessageBox: {
    
    
    confirm: jest.fn(),
    cancel: jest.fn(),
  }
}))

Vuex を使用するには、ストアを定義する必要があります

const store = createStore({
    
    
  modules: {
    
    
    user: {
    
    
      namespaced: true,
      state: {
    
    
        userId: "07cbccc0039"
      },
    },
  }
})

4. テストを開始する

マウント

describe('测试 Home 页面是否正常工作', () => {
    
         // 中文部分按自己的来,在只用来展示
  const mockScrollTo = jest.fn()
  let wrapper: VueWrapper<ComponentPublicInstance<any>>
  beforeEach(() => {
    
    
    wrapper = mount(Home, {
    
    
      global: {
    
    
        ...componentGlobal,
        provide: {
    
    
          scrollTo : mockScrollTo,
          store                                  /// 用到 Vuex 的可以加上
        },
      }
    })
  })
})

コンポーネントをテストしている場合は、props の値も追加する必要があります

describe('测试 HomeTable 组件是否正常工作', () => {
    
    
  let wrapper: VueWrapper<ComponentPublicInstance<any>>
  beforeEach(() => {
    
    
    wrapper = mount(HomeTable, {
    
    
      props: {
    
    
	      dataList: cloneDeep(mockListData),  // cloneDeep是深拷贝
    },
      global: {
    
    
        components,
      },
    })
  })
 })

このパッケージでは、テストしたいものをすべて渡すことができます

it('测试内容', ()=>{
    
    })

テスト表示

利用

wrapper.findAll()
wrapper.find()
wrapper.findComponent()
wrapper.findAllComponents()

これらの API は、ページに必要なコンポーネントが表示されることが期待されているかどうかを検証するために使用されます。

テストクリック

また、最初にボタンをクリックするノードを見つけて、クリックスルートリガー('click')をシミュレートします。

it('测试点击', async () => {
    
    
	wrapper.find('.add').trigger('click')     // 找到节点,模拟点击
})

多数のノードがある場合は、テスト用にそのうちの 1 つを見つける必要があります。

it('测试点击', async () => {
    
    
	const ElTableColumnComponent = wrapper.find('.tableList')           // 找到节点
	ElTableColumnComponent.findAll('.updateBtn')[0].trigger('click')    // 模拟点击
})

テストインターフェース

クリック後にインターフェイスの実行など、特定の操作を実行したい場合

it('测试接口', async () => {
    
    
	ElTableColumnComponent.findAll('.deleteBtn')[0].trigger('click')
	
	// deleteUser 指接口名
	// mockImplementationOnce 官方api 指调用一次
	// delMockResponse 返回数据
	
	const delMockResponse = {
    
    
	  "msg": "success",
	  "code": 200
	};  // 注意这个; 
	(deleteUser as jest.Mock<any>).mockImplementationOnce(() => Promise.resolve(delMockResponse))   // 模拟接口
})

通常、テストはプロセスがスムーズに実行できるかどうかのみをテストします。

テストコンポーネントは情報を返します

メソッドとパラメータを返すサブコンポーネントを使用する場合があります。

例えば

<home-table
   :data-list="tableList"
    @changeDate="changeDateHandle"
 />
it('测试子组件返回', async () => {
    
    
	const data = {
    
    
		"id": "cs24545132hs5"
	}
	const HomeTableComponent = wrapper.findComponent(HomeTable)  // 找到这个组件节点
	HomeTableComponent.vm.$emit('changeDate', data)   // newMockListData 返回数据
})

テストジャンプ

  it('测试页面跳转是否正常', async () => {
    
    
    const push = jest.fn()
    useRouter.mockImplementationOnce(() => ({
    
     push }))
    // mock 完毕需要重新挂载
    const wrapper = mount(MyPatientList, {
    
    
      global: {
    
    
        ...componentGlobal,
        provide: {
    
    
          scrollTo: mockScrollTo
        }
      }
    })
  })

時計のテスト

Watch は監視しているため、監視されている値に新しい値を直接割り当てることができます。

wrapper.vm.要赋值的对象 = 新的值

5. 上級者向け

テストページを作成したら、次のコマンドを実行してください。

npm run ut:coverage

プロジェクト内のカバレッジ\lcov-report にindex.html ページがあります。クリックすると、プロジェクトのテスト カバレッジが表示されます。

一般に、緑色は単体テストに合格したことを意味します。もちろん、カバレッジが高いほど良いことになります。

ここに画像の説明を挿入します
テストしたいファイルをクリックします

ファイル内の赤いコードは検出されませんでした

ドキュメントの詳細を読む ドキュメントはあまり明確ではありませんが、基本的な方法で十分です。

公式ドキュメント

もっと書いて、もっと練習してください

6. 共通コマンド

私の記事を閲覧してください

おすすめ

転載: blog.csdn.net/weixin_44872023/article/details/121977081