EP49 - 測試

更新 發佈閱讀 18 分鐘
Testing 每次測試這一塊都是內心想花點時間實作
最後都沒時間認真實作www
測試還是蠻重要的吧 哈

為什麼要測試? Why Test?

自動化測試能幫助您和您的團隊快速且自信地構建複雜的 Vue 應用,透過防止回歸並鼓勵您將應用拆分為可測試的函數、模組、類別和組件。與所有應用一樣,新的 Vue 應用可能會以多種方式出錯,因此在發布前能發現並修復這些問題是很重要的。

在本指南中,我們將介紹基本術語,並提供我們推薦的 Vue 3 應用測試工具。此外,指南包含針對 Vue 特定的可組合項目測試的部分,詳情請參考下方的「測試可組合項目」部分。

何時進行測試? - When to Test

越早開始測試越好!我們建議您儘早編寫測試。拖得越久,應用的相依性就越多,開始測試的難度也會越高。

測試類型 - Testing Types

設計 Vue 應用的測試策略時,您應考慮以下測試類型:

  • 單元測試:檢查給定函數、類別或可組合的輸入是否產生預期的輸出或副作用。
  • 元件測試:檢查元件的掛載、渲染、互動及預期行為。這些測試會導入比單元測試更多的程式碼,較為複雜且執行時間較長。
  • 端對端測試:檢查跨多頁面的功能,並針對生產構建的 Vue 應用進行真實網路請求。這些測試通常需要啟用資料庫或其他後端。

每種測試類型在應用的測試策略中都發揮著作用,並能防範不同類型的問題。

概述 - Overview

我們將簡要討論每種類型的測試是什麼、如何在 Vue 應用中實現它們,並提供一些一般建議。

單元測試 - Unit Test

單元測試用來驗證小而獨立的代碼單元運行是否符合預期。通常測試一個函數、類別、可組合的功能或模組,關注邏輯正確性,只涵蓋應用的一小部分功能,可能模擬應用的環境(如初始狀態、複雜類別、第三方模組和網絡請求)。

一般來說,單元測試可以捕捉到函數業務邏輯和邏輯正確性的問題。

例如此增量函數:

// helpers.js
export function increment (current, max = 10) {
if (current < max) {
return current + 1;
}
return current;
}

這個函數是獨立的,很容易進行測試,確保返回預期結果。

// helpers.spec.js
import { increment } from './helpers';

describe('increment', () => {
test('increments the current number by 1', () => {
expect(increment(0, 10)).toBe(1);
});

test('does not increment the current number over the max', () => {
expect(increment(10, 10)).toBe(10);
});

test('has a default max of 10', () => {
expect(increment(10)).toBe(10);
});
});

單元測試通常針對不涉及 UI 渲染、網絡請求或環境的業務邏輯。

Vue 應用中有兩個 Vue 特定的單元測試場景:

  1. 可組合功能(Composables)
  2. 組件

可組合功能

Vue 應用中特有的可組合功能可能需要特殊測試處理,詳見「測試可組合功能」。

單元測試組件

組件測試有兩種方式:

  • 白箱測試:關注組件的實現細節和依賴,通常模擬組件的子組件和插件狀態,進行隔離測試。
  • 黑箱測試:不關注組件的實現細節,盡量少模擬子組件,以測試組件和系統的整合。

以下組件測試建議如下

建議使用 Vitest

由於 Vue 官方使用 Vite 建立配置,建議使用 Vitest 進行單元測試。Vitest 由 Vue / Vite 團隊開發,與 Vite 集成簡便且速度快。

其他選擇

Jest 是常見的單元測試框架,但僅當已有 Jest 測試集需遷移至 Vite 時使用,否則建議使用 Vitest 以獲得更佳的效能和整合。

組件測試 - Component Testing​

在 Vue 應用中,組件是 UI 的主要構建塊,因此它們成為驗證應用行為時自然的隔離單元。從粒度上來看,組件測試位於單元測試之上,可視為一種整合測試。大部分 Vue 應用應覆蓋組件測試,建議為每個 Vue 組件編寫專屬的測試文件。

組件測試應捕捉與組件屬性、事件、插槽、樣式、類別、生命週期勾子等相關的問題。組件測試不應模擬子組件,而應透過用戶互動方式測試組件與子組件間的交互。例如,測試中應透過點擊元素來操作組件,而不是直接程式化操作。

組件測試應關注組件的公開介面,而非內部實現細節。對於大多數組件,公開介面僅限於:發出的事件、屬性與插槽。測試時應著重於組件的行為,而非其實現。

應該做的事 - Do

  • 對視覺邏輯:依據輸入的屬性和插槽確認渲染輸出是否正確。
  • 對行為邏輯:驗證對用戶輸入事件的正確渲染更新或發出的事件。

以下範例展示了 Stepper 組件,其包含一個標示為 "increment" 的 DOM 元素,且可以點擊。我們傳遞一個 max 屬性,防止 Stepper 增加到超過 2,所以點擊 3 次後,UI 仍應顯示 2。

const valueSelector = '[data-testid=stepper-value]'
const buttonSelector = '[data-testid=increment]'

const wrapper = mount(Stepper, {
props: {
max: 1
}
})

expect(wrapper.find(valueSelector).text()).toContain('0')

await wrapper.find(buttonSelector).trigger('click')

expect(wrapper.find(valueSelector).text()).toContain('1')

避免 Don't

  • 不要檢查組件實例的私有狀態或測試組件的私有方法,測試實現細節會使測試脆弱,且更容易因實現變更而需要更新。
  • 不要完全依賴快照測試,僅檢查 HTML 字串不能保證正確性。應撰寫具明確目的的測試。
  • 若需詳細測試方法,建議將其提取為單獨的工具函數並針對其進行單元測試。

推薦工具 - Recommendation

Vitest 與基於瀏覽器的測試執行器之間的主要差異在於速度與執行環境。簡而言之,像 Cypress 這樣的瀏覽器執行器可以發現一些 Node.js 執行器(如 Vitest)無法檢測的問題(例如樣式問題、真實的原生 DOM 事件、Cookies、本地儲存和網絡故障)。然而,瀏覽器執行器的速度比 Vitest 慢很多,因為它需要開啟瀏覽器、編譯樣式等。Cypress 是一款支援組件測試的瀏覽器執行器。請參考 Vitest 的比較頁面以獲取 Vitest 與 Cypress 最新的比較資訊。

掛載庫 - Mounting Libraries

組件測試通常涉及單獨掛載組件、模擬用戶事件並驗證 DOM 輸出,有專門工具庫可簡化這些任務。

  • @vue/test-utils:官方低階組件測試庫,提供 Vue 特定 API。@testing-library/vue 底層基於此庫。
  • @testing-library/vue:專注於不依賴實現細節的組件測試,其原則是測試越接近真實使用,越能提供信心。對於含 Suspense 的異步組件應謹慎使用。

我們建議在應用程式中使用 @vue/test-utils 來測試組件。@testing-library/vue 在測試具有 Suspense 的非同步組件時存在一些問題,因此應謹慎使用。

其他選項

  • Nightwatch:端到端測試工具,支援 Vue 組件測試(範例專案)。
  • WebdriverIO:跨瀏覽器組件測試工具,基於標準化自動化執行原生用戶互動,也可與 Testing Library 搭配使用。

E2E 測試 - E2E Testing​

雖然單元測試能提供一定的信心,但單元和組件測試無法全面涵蓋應用在生產環境中運行時的情況。因此,端到端(E2E)測試提供了更全面的覆蓋範圍,專注於應用實際運行時的行為。

E2E 測試的重點在於多頁面應用的行為,它會針對已部署的 Vue 應用進行網路請求。通常需要連接資料庫或其他後端服務,甚至可能在測試環境中執行。

E2E 測試通常可以檢測到路由、狀態管理、頂層組件(例如 App 或 Layout)、公共資源或請求處理上的問題。它不會匯入任何 Vue 應用程式的程式碼,而是透過瀏覽器模擬實際操作應用的情況。

E2E 測試涵蓋應用的多層面。可以在本地或線上測試環境中測試,這樣不僅涵蓋前端和靜態伺服器,還涵蓋後端服務和基礎設施。

Kent C. Dodds 說道:「測試越貼近真實使用情況,能提供的信心就越高。」

E2E 測試透過模擬使用者行為提升信心,確保應用正常運行。

選擇 E2E 測試解決方案

雖然 E2E 測試曾因不穩定而惡名昭彰,但現代工具已經改善了這一問題。選擇 E2E 測試框架時,請考慮以下幾點。

跨瀏覽器測試

E2E 測試的主要優勢是能跨多個瀏覽器測試應用,但 100% 覆蓋的效益可能隨資源投入而遞減。選擇適合的跨瀏覽器測試程度有助於資源最佳化。

更快速的反饋循環

E2E 測試執行時間長,通常僅在 CI/CD 中完整執行。現代 E2E 框架支援平行執行來提升速度,並支援單獨測試和測試熱重新加載,提升開發效率。

一流的除錯體驗

傳統上需查看終端日誌來排錯,現代框架則允許使用瀏覽器開發工具,提升除錯便利性。

無頭模式的可視化

在 CI/CD 管線中,E2E 測試常使用無頭瀏覽器執行。現代 E2E 框架提供截圖或錄影功能,有助於識別錯誤原因。

推薦工具

Playwright:支援 Chromium、WebKit 和 Firefox,能在 Windows、Linux 和 macOS 執行。擁有出色的 UI、除錯功能、內建斷言、平行執行和防止不穩定測試的設計。支援組件測試(實驗性)。

Cypress:具備豐富的圖形介面、出色的除錯功能、內建斷言、快照等。支援 Chromium、Firefox 和 Electron。WebKit 支援為實驗性,部分平行化功能需 Cypress Cloud 訂閱。

其他選擇

Nightwatch:基於 Selenium WebDriver,支援最多瀏覽器。

WebdriverIO:基於 WebDriver 協議,適用於網頁和行動裝置的測試框架。

範例 - Recipes

將 Vitest 添加到專案中

在基於 Vite 的 Vue 專案中,運行以下命令:

> npm install -D vitest happy-dom @testing-library/vue

接下來,更新 Vite 配置以添加測試選項區塊:

// vite.config.js
import { defineConfig } from 'vite'

export default defineConfig({
// ...
test: {
// 啟用類似 Jest 的全域測試 API
globals: true,
// 使用 happy-dom 模擬 DOM
// (需要將 happy-dom 安裝為 peer 依賴)
environment: 'happy-dom'
}
})
提示:如果您使用 TypeScript,請在 tsconfig.jsontypes 欄位中添加 vitest/globals
// tsconfig.json
{
"compilerOptions": {
"types": ["vitest/globals"]
}
}

然後,在您的專案中創建一個以 .test.js 結尾的檔案。您可以將所有測試檔案放在專案根目錄的 test 目錄中,或放在與源檔案相鄰的 test 目錄中。Vitest 將自動使用命名慣例搜尋它們。

// MyComponent.test.js
import { render } from '@testing-library/vue'
import MyComponent from './MyComponent.vue'

test('it should work', () => {
const { getByText } = render(MyComponent, {
props: {
/* ... */
}
})

// 驗證輸出
getByText('...')
})

最後,更新 package.json 以添加測試腳本並運行它:

{
// ...
"scripts": {
"test": "vitest"
}
}
> npm test

測試可組合函式

本節假設您已閱讀過可組合函式的相關內容。

在測試可組合函式時,可以將其分為兩類:不依賴於宿主組件實例的可組合函式,以及依賴於宿主組件實例的可組合函式。

當可組合函式使用以下 API 時,則依賴於宿主組件實例:

  • 生命週期鉤子
  • 提供 / 注入

如果可組合函式僅使用響應式 API,那麼可以直接調用它並驗證其返回的狀態/方法:

// counter.js
import { ref } from 'vue'

export function useCounter() {
const count = ref(0)
const increment = () => count.value++

return {
count,
increment
}
}
// counter.test.js
import { useCounter } from './counter.js'

test('useCounter', () => {
const { count, increment } = useCounter()
expect(count.value).toBe(0)

increment()
expect(count.value).toBe(1)
})

依賴於生命週期鉤子或提供 / 注入的可組合函式需要包裹在宿主組件中進行測試。我們可以創建一個幫助函式,如下所示:

// test-utils.js
import { createApp } from 'vue'

export function withSetup(composable) {
let result
const app = createApp({
setup() {
result = composable()
// 抑制缺少模板的警告
return () => {}
}
})
app.mount(document.createElement('div'))
// 返回結果和應用實例
// 以便測試提供/卸載
return [result, app]
}
import { withSetup } from './test-utils'
import { useFoo } from './foo'

test('useFoo', () => {
const [result, app] = withSetup(() => useFoo(123))
// 模擬提供以測試注入
app.provide(...)
// 執行斷言
expect(result.foo.value).toBe(1)
// 如果需要,觸發 onUnmounted 鉤子
app.unmount()
})

對於更複雜的可組合函式,通過使用組件測試技術編寫測試包裝組件也可能更容易進行測試。

測試的章節比我想像中的還多資訊@@
真的要實作過會比較有印象....Orz...
繼續堆疊知識中...www
留言
avatar-img
卡關的人生
4會員
73內容數
分享生活趣事~
卡關的人生的其他內容
2024/11/10
Vue 提供了多種動畫技術來提升應用程式的互動性,包括基於 CSS 類別的動畫、基於狀態的動畫,以及使用監視器來動畫化數值。基於類別的動畫可通過動態添加 CSS 類別來觸發,像是觸發按鈕搖動效果。基於狀態的動畫則是透過樣式綁定,根據互動動態調整元素的外觀,例如根據滑鼠位置改變背景顏色。
Thumbnail
2024/11/10
Vue 提供了多種動畫技術來提升應用程式的互動性,包括基於 CSS 類別的動畫、基於狀態的動畫,以及使用監視器來動畫化數值。基於類別的動畫可通過動態添加 CSS 類別來觸發,像是觸發按鈕搖動效果。基於狀態的動畫則是透過樣式綁定,根據互動動態調整元素的外觀,例如根據滑鼠位置改變背景顏色。
Thumbnail
2024/11/09
Web Components 是一組網頁原生 API,允許開發者創建可重複使用的自訂元素。Vue 與 Web Components 是互補的技術,Vue 支援整合和創建自訂元素。
Thumbnail
2024/11/09
Web Components 是一組網頁原生 API,允許開發者創建可重複使用的自訂元素。Vue 與 Web Components 是互補的技術,Vue 支援整合和創建自訂元素。
Thumbnail
2024/11/08
Vue 建議使用模板構建應用程式,但在需要 JavaScript 的全程式化功能時,渲染函數可派上用場。渲染函數通過 h() 函數創建 vnode,h 是 hyperscript 的簡寫,能生成 HTML 的 JavaScript。
Thumbnail
2024/11/08
Vue 建議使用模板構建應用程式,但在需要 JavaScript 的全程式化功能時,渲染函數可派上用場。渲染函數通過 h() 函數創建 vnode,h 是 hyperscript 的簡寫,能生成 HTML 的 JavaScript。
Thumbnail
看更多
你可能也想看
Thumbnail
在使用 Vue 組件 API 和 TypeScript 的開發中,通常會遇到類型錯誤和需要 debug 的情況。組件 API 下的 TypeScript 提供了更強的型別檢查和類型推斷功能,這有助於減少錯誤。
Thumbnail
在使用 Vue 組件 API 和 TypeScript 的開發中,通常會遇到類型錯誤和需要 debug 的情況。組件 API 下的 TypeScript 提供了更強的型別檢查和類型推斷功能,這有助於減少錯誤。
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
過去在程式導師實驗課程中,整理過這兩篇筆記探討「測試」是怎麼回事: [week 3] 初探 Jest:如何測試程式? [week 22] React:用 SPA 架構實作一個部落格(三)- 淺談測試 在轉職後的第一家公司,組內曾嘗試在既有專案中撰寫測試,卻因時程緊湊而不了了之。
Thumbnail
過去在程式導師實驗課程中,整理過這兩篇筆記探討「測試」是怎麼回事: [week 3] 初探 Jest:如何測試程式? [week 22] React:用 SPA 架構實作一個部落格(三)- 淺談測試 在轉職後的第一家公司,組內曾嘗試在既有專案中撰寫測試,卻因時程緊湊而不了了之。
Thumbnail
大家好!我們都知道,程式碼寫出來不代表就完工了,還要確保它真的“做到”我們想要的。這就是測試的力量!尤其是在 Web 開發中,測試確保我們的應用正確、穩定且高效地運行。今天,我們就來探討如何在 Gin 應用中進行測試和單元測試。
Thumbnail
大家好!我們都知道,程式碼寫出來不代表就完工了,還要確保它真的“做到”我們想要的。這就是測試的力量!尤其是在 Web 開發中,測試確保我們的應用正確、穩定且高效地運行。今天,我們就來探討如何在 Gin 應用中進行測試和單元測試。
Thumbnail
單元測試不僅能發現錯誤,更是提升開發技能的關鍵工具。Laravel 提供強大的測試框架,讓我們可以輕鬆撰寫測試。建立測試資料庫、撰寫測試方法、使用 Factory 生成測試資料,能確保程式碼穩定,並幫助開發者在修改與重構中更有信心。持續撰寫測試能提高程式碼品質,並讓開發過程更有條理與安全感。
Thumbnail
單元測試不僅能發現錯誤,更是提升開發技能的關鍵工具。Laravel 提供強大的測試框架,讓我們可以輕鬆撰寫測試。建立測試資料庫、撰寫測試方法、使用 Factory 生成測試資料,能確保程式碼穩定,並幫助開發者在修改與重構中更有信心。持續撰寫測試能提高程式碼品質,並讓開發過程更有條理與安全感。
Thumbnail
《轉轉生》(Re:INCARNATION)為奈及利亞編舞家庫德斯.奧尼奎庫與 Q 舞團創作的當代舞蹈作品,結合拉各斯街頭節奏、Afrobeat/Afrobeats、以及約魯巴宇宙觀的非線性時間,建構出關於輪迴的「誕生—死亡—重生」儀式結構。本文將從約魯巴哲學概念出發,解析其去殖民的身體政治。
Thumbnail
《轉轉生》(Re:INCARNATION)為奈及利亞編舞家庫德斯.奧尼奎庫與 Q 舞團創作的當代舞蹈作品,結合拉各斯街頭節奏、Afrobeat/Afrobeats、以及約魯巴宇宙觀的非線性時間,建構出關於輪迴的「誕生—死亡—重生」儀式結構。本文將從約魯巴哲學概念出發,解析其去殖民的身體政治。
Thumbnail
接下來要深入探討組件註冊的內容!Vue 組件需要註冊,讓 Vue 知道在模板中遇到組件時在哪裡找到實現。註冊方式有全局和局部兩種。全局註冊適用於通用、頻繁使用的組件,例如按鈕、模態框等;而局部註冊適用於特定頁面或功能,能明確依賴關係,提升維護性。回顧之前的範例,我們都是使用局部註冊呢!
Thumbnail
接下來要深入探討組件註冊的內容!Vue 組件需要註冊,讓 Vue 知道在模板中遇到組件時在哪裡找到實現。註冊方式有全局和局部兩種。全局註冊適用於通用、頻繁使用的組件,例如按鈕、模態框等;而局部註冊適用於特定頁面或功能,能明確依賴關係,提升維護性。回顧之前的範例,我們都是使用局部註冊呢!
Thumbnail
背景:從冷門配角到市場主線,算力與電力被重新定價   小P從2008進入股市,每一個時期的投資亮點都不同,記得2009蘋果手機剛上市,當時蘋果只要在媒體上提到哪一間供應鏈,隔天股價就有驚人的表現,當時光學鏡頭非常熱門,因為手機第一次搭上鏡頭可以拍照,也造就傳統相機廠的殞落,如今手機已經全面普及,題
Thumbnail
背景:從冷門配角到市場主線,算力與電力被重新定價   小P從2008進入股市,每一個時期的投資亮點都不同,記得2009蘋果手機剛上市,當時蘋果只要在媒體上提到哪一間供應鏈,隔天股價就有驚人的表現,當時光學鏡頭非常熱門,因為手機第一次搭上鏡頭可以拍照,也造就傳統相機廠的殞落,如今手機已經全面普及,題
Thumbnail
最近在研讀單元測試的藝術這本書,也剛好因為自己對單元測試的撰寫還沒有很游刃有餘XD,但由於我是挑重點看,簡單做個內容讀後感的整理
Thumbnail
最近在研讀單元測試的藝術這本書,也剛好因為自己對單元測試的撰寫還沒有很游刃有餘XD,但由於我是挑重點看,簡單做個內容讀後感的整理
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
測試對於構建複雜的 Vue 應用至關重要,因為它能防止回歸並鼓勵將應用拆分為可測試的模組。我們介紹了測試的基本術語和推薦的工具,包括單元測試、組件測試和端對端測試。建議越早開始測試,避免隨著時間推移而增加的相依性。單元測試專注於函數和邏輯的正確性,而組件測試則驗證 UI 元素的行為與交互。
Thumbnail
測試對於構建複雜的 Vue 應用至關重要,因為它能防止回歸並鼓勵將應用拆分為可測試的模組。我們介紹了測試的基本術語和推薦的工具,包括單元測試、組件測試和端對端測試。建議越早開始測試,避免隨著時間推移而增加的相依性。單元測試專注於函數和邏輯的正確性,而組件測試則驗證 UI 元素的行為與交互。
Thumbnail
歡迎支持與學習,讓阿Han幫您脫離無限加班的惡性循環… 您是否苦於網路資訊爆炸嗎? 教學何其多,但卻無法好好選擇的困境呢? 歡迎加入實戰營, 這裡不給您冗餘的雜訊, 單刀直入直接送您重點, 避開選擇障礙的困境, 讓您獲得業界標準的開發起手式, 成為Top 1的頂尖人才。
Thumbnail
歡迎支持與學習,讓阿Han幫您脫離無限加班的惡性循環… 您是否苦於網路資訊爆炸嗎? 教學何其多,但卻無法好好選擇的困境呢? 歡迎加入實戰營, 這裡不給您冗餘的雜訊, 單刀直入直接送您重點, 避開選擇障礙的困境, 讓您獲得業界標準的開發起手式, 成為Top 1的頂尖人才。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News