本文首發於 Vue 應用單元測試的策略與實踐 01 - 前言 | 呂立青的部落格
歡迎關注知乎專欄 —— 前端的逆襲(凡可 JavaScript,終將 JavaScript。)
前言
本文主要嘗試解決三個問題:
- 在 TDD 做完Tasking列完例項化資料之後,完全沒有UT基礎不知道該怎麼寫單元測試?
- 在Vue應用的單元測試中,對UI元件和vuex store等測試的區別有何不同?顆粒度該細到什麼程度?
- 測試收益如何最大化,如何配置高價效比的測試策略,即什麼地方到底該花力氣測試,什麼地方又可以暫且放一放?
不談論的包括:
- ATT 驗收測試 或 E2E 端到端測試,這個是我想進一步探索的話題,特別是在TDD的語境下。#322
- 為什麼要 TDD?但是我會講為什麼要 UT 單元測試。測試和TDD是兩碼事,而光是自動化測試的好處就已經足夠多,但是如何做到更好的自動化和持續整合,那就需要TDD來指引方向。
- Snapshot Testing 快照測試,其實我是很認可快照這種形式,但需要改進其工作流,至少結合Image Snapshot和Storybook等工具,甚至更應該放到CI上去。#311
下面我就來結合具體場景,進一步例項化這些問題,舉幾個?:
- 在 TDD 做完Tasking列完例項化資料之後,完全沒有UT基礎不知道該怎麼寫單元測試?
// Given
一個完全沒有UT基礎的新人?
// When
當他?閱讀和練習本文的Jest的部分
// Then
他能夠把Given/When/Then的套路學會
他能夠學會Jest的基本用法,包括測試suite和斷言等語法
他能夠學會Jest中測試非同步的幾種方式
複製程式碼
- 在Vue應用的單元測試中,對UI元件和vuex store等測試的區別有何不同?顆粒度該細到什麼程度?
// Given
一個有基本的UT知識但沒寫過Vue測試的新人?
// When
當他?閱讀和練習本文的Vue單元測試的部分
// Then
當然,他能夠學會Vue元件在測試當中的幾種渲染方式
他能夠學會UI元件的分類,特別是互動行為的測試方式
他能夠對Vuex概念的理解更加深入,且知道 `Redux-like` 架構的好處
他能夠合理測試vuex store的mutation和getter中的業務邏輯
他能夠測試元件如何正確dispatch action以及action中如何做非同步操作
複製程式碼
- Vue專案中測試收益如何最大化,如何配置高價效比的測試策略,即什麼地方到底該花力氣測試,什麼地方又可以暫且放一放?
// Given
一個具備UT基礎但找不到著力點的求索之徒?
// When
當他?閱讀本文的Vue應用測試策略部分
// Then
他能夠找到測試的重點,重新燃起對UT的熱情?
他能夠在專案背景下合理配置單元測試的測試策略
複製程式碼
於是乎,這就是本系列文章的大綱,先放出來給大家一個對於Vue應用單元測試的全域性觀:
## 單元測試基礎
### 為什麼選擇 Jest
### Jest 的基本用法
### 該如何測試非同步程式碼?
### 單元測試與自動化的意義
## Vue 單元測試
### Vue 元件的渲染方式
### Wrapper `find()` 方法與選擇器
### UI 元件互動行為的測試
## Vuex 單元測試
### CQRS 與 `Redux-like` 架構
### 如何對 Vuex 進行單元測試
### Vue元件和Vuex store的互動
## Vue應用測試策略
### 單元測試的特點及其位置
### 單元測試的關注點
### 應用測試的測試策略
複製程式碼
? 哦豁,正文終於開始……
為什麼要有單元測試?
引用好友鮮明的觀點就是:寫不好是能力問題,不寫則是態度問題。單元測試客觀上可以讓開發者的工作更高效,Vue 應用的單元測試是一定要的。
單元測試的上下文
談任何東西都一定要有個上下文。你的論述不能是「因為單元測試有這些好處,所以我們要做單元測試」,而應該是「不做單元測試我們會遇到什麼問題」,這樣才能回答「為什麼要寫單元測試」的問題。那麼我們談論單元測試的上下文是什麼呢?不做單元測試我們會遇到什麼問題呢?
上圖為一個產品從 idea 分析、設計、開發、測試到交付並獲取市場反饋的過程。
而單元測試的上下文就是存在於「敏捷」當中。敏捷為的是更快地交付有價值的可工作的軟體。為此,它有一個指標來度量這個「更快」,那就是 lead time,它度量的是一個 idea 從提出被驗證,到最終上生產環境面對使用者的時間。顯然,這個時間越短,軟體獲得反饋的時間就越短,對價值的驗證就越快發生。
單元測試的意義
這個結論對我們寫不寫單元測試有什麼影響呢?答案是,不寫單元測試,你就快不起來。為啥呢?因為每次釋出,你都要投入人力來進行手工測試;因為沒有測試,你傾向於不敢隨意重構,這又導致程式碼逐漸腐化,複雜度使得你的開發速度降低。
那麼在這個上下文中來談要不要單元測試,我們就可以很有根據了,而不是“開發爽了就用,不爽就不用”這樣含糊的答案:
- 如果你說我的業務部門不需要頻繁上線,並且我有足夠的人力來覆蓋手工測試,那你可以不用單元測試
- 如果你說我不在意程式碼腐化,並且我也不做重構,那你可以不用單元測試
- 如果你說我不在意程式碼質量,好幾個沒有測試保護的
if-else
裸奔也不在話下,腦不好還做什麼程式設計師,那你可以不用單元測試 - 如果你說我確有快速部署的需求,但我們不 care 質量問題,出迴歸問題就修,那你可以不用單元測試
除此之外,你就需要寫單元測試。如果你想隨時整理重構程式碼,那麼你需要寫單元測試;如果你想有自動化的測試套件來幫你快速驗證提交的完整性,那麼你需要寫單元測試。
單元測試與自動化的關係
綜上,我們用來談論單元測試的「透鏡」是什麼呢?一言以蔽之,兩點:反饋速度和自動化。
自動化回答的是要不要自動化的單元測試這個問題。測試是重構的唯一保障,也就是說,沒有測試,基本上就沒法重構程式碼(重構指的是 不改變軟體可觀測行為的前提下改善程式碼內部設計或實現 ),基本上就只能看著程式碼腐化。那麼,基本上只要你的系統需要持續發展,你就需要單元測試。
反饋速度回答的是要不要 TDD、測試先行還是後補這個問題。答案是,需要 TDD,最好先行,因為可以提高反饋速度,縮短反饋週期,與此同時減少不必要的浪費。
至此,回答了「為什麼我們需要寫單元測試」的問題。下面讓我們來談談如何寫好 JavaScript 程式碼和 Vue 應用框架的單元測試。
如何選擇一個測試框架?
眾所周知,JavaScript 世界裡最不缺的就是輪子,測試框架也是如此。其實這裡的子標題就是為什麼選擇 Jest?有時候安於現狀,只不過是因為我們沒有見過理想的模樣。只有當我們見過更好的世界和更好的測試框架,才會驚呼“原來世界是這樣美好呀!我怎麼都沒有想到呢?”
引自技術雷達:Jest是一個“零配置”的前端測試工具,具有諸如模擬和程式碼覆蓋之類的開箱即用特性,主要用於React和其他JavaScript框架。
我們團隊對採用JEST做前端測試的結果非常滿意。它提供了一種“零配置”的開發體驗,並具備諸多開箱即用的功能,比如 Mock 和程式碼覆蓋率等。你不僅可以將此測試框架應用於React.js應用程式,也可以應用於其他 JavaScript 框架。Jest 經常被炒作的功能之一是使用者介面的快照測試。快照測試可以作為測試金字塔上層一個很好的補充,但請記住,單元測試仍然是堅實的基礎。
一個好的測試框架,Jest 的幾大好處可以涵蓋為:
- Fast 天下武功,唯快不破。確實很快,雖然實測下來跟 Mocha 新版本還是慢了些,以後找個機會再測一次。
- Opinionated 不需要你做出選擇和配置,就能提供所有的東西,比如Mock(幹掉Sinon)、Test Runner(幹掉Karma)、Matcher(幹掉Chai)、Test Coverage(內建istanbul)
- Watch Mode 守護模式。非常注重開發者體驗,能夠在編碼的時候幫助我們快速獲得測試結果的反饋。
- Snapshot Testing 快照測試。這是值得爭議的一點,前文也提到過會專門開個issue來討論,在此不再贅述。
最後,總結一下 Jest
Jest 作為一個測試框架,其最大的特點就在於它是一個非常有效的解決方案,不需要與其他測試庫互動來執行它的工作。與此同時 Jest 非常注重開發者體驗,這一點也是特別值得欣賞,現在市面上關注開發者(“人”)體驗的開發框架和工具實在不多,而Jest Watch模式的核心就在於快速獲得反饋,雖然我沒在命令列使用而是WebStorm但亦可以與之結合。
ps: 除此之外,還有很多開發者體驗亦值得細細品味與發現,特別是Jest本身來自Facebook的工程化支援也是特別棒的,這個講述如何開發Jest的官方視訊值得一看:Building High-Quality JavaScript Tools。
未完待續……
## 單元測試基礎
- [x] ### 為什麼選擇 Jest
- [ ] ### Jest 的基本用法
- [ ] ### 該如何測試非同步程式碼?
- [ ] ### 單元測試與自動化的意義
## Vue 單元測試
- [ ] ### Vue 元件的渲染方式
- [ ] ### Wrapper
find()
方法與選擇器 - [ ] ### UI 元件互動行為的測試
## Vuex 單元測試
- [ ] ### CQRS 與
Redux-like
架構 - [ ] ### 如何對 Vuex 進行單元測試
- [ ] ### Vue元件和Vuex store的互動
## Vue應用測試策略
- [ ] ### 單元測試的特點及其位置
- [ ] ### 單元測試的關注點
- [ ] ### 應用測試的測試策略