恰好在公司一個項目中需要配置單元測試,借著機會學(xué)習(xí)了一下。經(jīng)過對比最終選用了Facebook的jest測試框架,本文包含以下幾點內(nèi)容
- 什么是單元測試?
- 什么時候使用單元測試?
- 如何使用單元測試?
什么是單元測試(Unit Testing)?
什么是單元?軟件設(shè)計的最小單位。在過程化編程時,它可以是單個程序、函數(shù)、過程等;在面向?qū)ο蟮木幊讨?,它可以是方法,包括基類、抽象類、子類中的方法等?所謂單元測試,就是針對軟件設(shè)計的最小單位來進行正確性檢驗的測試工作。 除了單元測試之外,還有集成測試、系統(tǒng)測試、驗收測試等測試類型,它們作用在項目開發(fā)的不同階段,測試目的也不盡相同。
什么時候使用單元測試?
軟件設(shè)計有兩個終極目標(biāo):
- 實現(xiàn)需求;
- 代碼質(zhì)量及可維護性。
所以要判斷什么時候使用單元測試,就是看是否實現(xiàn)了這兩個目標(biāo)。舉例說明,考慮如下兩個場景:
- 輸出
Hello World,幾行代碼; - 某公司的管理系統(tǒng),2w+代碼,上千個函數(shù)及方法。
對于場景1,需求簡單,無論是代碼質(zhì)量,還是可維護性,都相當(dāng)高,這樣的場景顯然沒有必要添加單元測試。對于場景2,你能保證組成這個系統(tǒng)的上千個函數(shù)和方法沒有BUG嗎?即使你天賦異稟,能夠讓如此復(fù)雜的代碼不失控,那么遇到需求迭代、工作交接等場景時,能保證變更不引入新的問題么?(稍有工程經(jīng)驗的人應(yīng)該都體會過一邊修bug一邊寫bug的絕望)
所以我們的結(jié)論是,如果你的場景需求簡單、個人開發(fā)、代碼量小,或者你是準(zhǔn)備干一票跑路,那么單測也許顯得不那么重要。但是如果系統(tǒng)的復(fù)雜度終究會超過個人的精力,那么你需要單元測試這樣的工具幫助你規(guī)避潛在的風(fēng)險。==最能體現(xiàn)單元測試意義的場景,就是你修改代碼的時候。==
常用的JavaScript單測框架及對比?
暫時只使用過jest框架,待補充
實踐一個單元測試
場景
遇到的一個業(yè)務(wù)場景是數(shù)個APP上的鏈接拼接規(guī)則不同,通過一些函數(shù)規(guī)范輸出成拼接好的字符串。實現(xiàn)拼接功能本身并不麻煩,麻煩的是各個APP鏈接規(guī)則不同,在迭代(比如添加日志參數(shù)、新增支持的APP)等功能時非常容易出錯,因此接入單測,提高效率。
項目是一個用vue-cli進行的初始化,是為了給上述功能提供簡單的web頁面,因此UI部分不是重點,暫時不接入單測,只對純js的邏輯部分接入單測。
使用
jest非常易于使用,文檔也很詳細(xì),這里主要說一下我在項目里的應(yīng)用步驟,具體的API調(diào)用可以直接參考官方文檔 Getting Started
- 安裝
jest。官方文檔中大多數(shù)使用yarn(另一種包管理工具)命令,不過使用npm也是可行的。
npm install --save-dev jest
- 修改package.json添加如下命令(--coverage表示打印覆蓋率等信息)
{
"script": {
"test": "jest --coverage"
}
}
- 項目根目錄下建立tests文件夾(和src目錄平級),里面建立和要測試的文件同路徑的測試文件,命名為
xxx.test.js - 引入要添加單測的函數(shù)
- 編寫單測
- 在expect中調(diào)用引入的函數(shù),通過匹配器(有用于數(shù)字、對象、字符串等多種不同匹配器)判斷輸出是否符合預(yù)期
- 可mock一些考慮邊界情況、異常輸入等的測試用例
test('two plus two is four', () => {
expect(2 + 2).toBe(4);
});
- 修改package.json文件,在
pre-commit的鉤子也執(zhí)行,這樣其它人修改這個項目提交也會默認(rèn)走一次單測 - 也可以通過
npm run test手動執(zhí)行單測
FAQ
1. 我有代碼規(guī)范檢查,test函數(shù)為全局方法,會報未定義的錯誤?
答:通過 /* global test */ 注釋將test函數(shù)標(biāo)記為全局變量即可
2. 上面說了純js的測試方案,那么單文件組件(含有UI、生命周期等)該如何測試?
答:本質(zhì)上思路是一樣的,就是看在指定輸入下輸出是否符合預(yù)期。UI測試用例的編寫可能要麻煩一些,網(wǎng)上能找到很多資料,這里不再贅述。
參考文獻(xiàn)
單元測試到底是什么?應(yīng)該怎么做? - coolhappy的回答 - 知乎
本文同步發(fā)布在我的個人博客:JavaScript單元測試