Try   HackMD

Vue單元測試學習筆記

在深入技術前,可以先閱讀Vue官方的測試建議
以下,會介紹幾個在專案中撰寫測試搭配的套件及其初始範例,詳細寫法還請參考個別的官方文件。

Unit-jest (Jest & Vue Test Utils)

About

jest 官方文件

Jest 是一個由Facebook 開發的 test runner,它提供許多豐富的功能,例如:斷言、分析測試涵蓋率、 mock 功能與良好的錯誤提示訊息等。

Jest 可以測試的範圍涵蓋了 JavaScript 相關的技術,包含後端的 Node.js 與前端的 Vue 、 Angular 或 React ,是個完善的測試框架。

Vue Test Utils 英文 / 中文官方文件

Vue Test Utils 是Vue.js 官方所維護的單元測試套件,它提供了一系列的API 使我們很容易去操作存取元件

建立含有單元測試的專案

$ vue create vue-test -m npm

Vue CLI v5.0.8
? Please pick a preset: Manually select features
? Check the features needed for your project: Babel, Unit
? Choose a version of Vue.js that you want to start the project with 2.x
? Pick a unit testing solution: Jest
...

它會直接幫你建立測試的範例檔

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

運行後可以得到

$ npm run test:unit

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

於現有專案安裝

$ vue add unit-jest

簡單範例:Counter

  1. 建立一個counter頁面,點擊按鈕後數字會+1

@/components/Counter.vue

<template> <div> <h1>Count: {{ count }}</h1> <button id="increment-btn" @click="count++"> +1 </button> </div> </template> <script> export default { data() { return { count: 0, } }, } </script>

會長得像這樣:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

  1. 寫測試

預期初始值會是0,點擊一下之後會變成1

tests/unit/counter.spec.js

import { mount } from '@vue/test-utils' import Counter from '@/components/Counter.vue' describe('Counter.vue', () => { it('click once', async () => { // 驗證初始值 const wrapper = mount(Counter) expect(wrapper.vm.count).toBe(0) // 獲取元件 const button = wrapper.find('button') const h1 = wrapper.find('h1') // 測試互動 await button.trigger('click') expect(h1.text()).toContain('1') }) })
  1. 結果

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Vitest

  • Vitest 与大多数 Jest API 和生态系统库都有较好的兼容性,可以無痛轉換
  • 如果專案本身由 Vite 驅動,推薦以 Vitest 作為測試工具
  • 寫測試時也可以搭配 Vue Test Utils 或 testing-library 做組件測試使用

Install

基本上用 vue-create 建專案的話都會內建,沒有的話可以用下列指令安裝

$ npm install -D vitest
$ npm i @vitejs/plugin-vue

建立設定檔 vitest.config.ts

import { fileURLToPath, URL } from "node:url" import { defineConfig } from "vite" import type { UserConfig as VitestUserConfigInterface } from "vitest/config" import vue from "@vitejs/plugin-vue" const vitestConfig: VitestUserConfigInterface = { test: { globals: true, environment: "jsdom", // 也可以用happy-dom之類的 }, } export default defineConfig({ plugins: [vue()], resolve: { alias: { "@": fileURLToPath(new URL("./src", import.meta.url)), }, }, test: vitestConfig.test, })

配置 package.json

"scripts": {
    "test": "vitest",
    "coverage": "vitest --coverage" // 稍後覆蓋率會用到
  },

配置方式參考
vue 官方建議
一篇來自 stackoverflow 的建議

簡單範例(搭配Vue Test Utils)

要先安裝 Vue Test Utils

$ npm install @vue/test-utils --save-dev

建立基本測試,檔名須遵照 xxx.test.js 規則
code和上面jest的寫法一樣

@/tests/example.test.js

import { mount } from "@vue/test-utils"; import HelloWorld from "@/components/HelloWorld.vue"; import { describe, expect, test } from "vitest"; describe('HelloWorld.vue', () => { test('renders props.msg when passed', () => { const msg = 'new message' const wrapper = mount(HelloWorld, { propsData: { msg } // Mocking Props }) expect(wrapper.text()).toMatch(msg) }) })

運行測試,本指令會自動 watch

$ npm test  

覆蓋率

官方文件

設定 vitest.config.ts

const vitestConfig: VitestUserConfigInterface = {
  test: {
    globals: true,
    environment: "jsdom",
    /* 新增以下設定 */ 
    coverage:{
        all: true,
        provider: 'c8',         // 也可以用istanbul
        reporter: ['text', 'json', 'html'],
    },
    include: ['**/tests/*.js'], // 測試檔案路徑,也可以不設定預設抓所有
    /* ---------- */
  },
}
...

安裝覆蓋率套件

$ npm i -D @vitest/coverage-c8@{你的vitest版本號}

運行指令

$ npm run coverage
  • 從terminal檢視

  • 檢視網頁介面報告

運行覆蓋率指令後,會自動生成 /converage 資料夾

打開html網頁後,可以查看詳細的報告

testing-library

testing-library 官方文件

$ npm install --save-dev @testing-library/vue

語法指令

Vue Test Utils

Vue Test Utils APIs

Vitest

vitest APIs
Jest 的指令基本上和 Vitest 是兼容的

Jest

jest APIs

其他

Cypress

參考資料

尋覓網站開發的神兵利器系列 第 38 篇 Extra07 - Jest - 單元測試框架