以前有分享過UI組件庫搭建思路和組件如何實現,今天分享的內容是我認爲開發組件庫中'最'.repeat(1e8)
有(zei)意(ma)思(fan)的部分-單元測試,目前個人UI組件庫覆蓋率爲92%,功能組件部分單側所有覆蓋,工具類部分尚未徹底覆蓋。報告以下所示:html
本篇大體分爲三部份內容,第一部分淺顯的介紹單元測試,讓你們初步瞭解它的做用及優勢。第二部分介紹單元測試的技術選型和在項目中的實戰運用,會舉一個簡單的例子介紹怎麼使用它。第三部分介紹如何使用集成服務工具提升咱們的工做效率。前端
但願你閱讀完本篇文章以後,能讓你對單元測試這個概念有一個初步的瞭解。接下來咱們進入正片部分。vue
首先提出兩個問題。git
英文叫 Unit Testing,又稱爲模塊測試,是針對程序模塊來進行正確性檢驗的測試工做。程序單元是應用的最小可測試部件。在過程化編程中,一個單元就是單個程序、函數、過程等;對於面向對象編程,最小單元就是方法,包括基類(超類)、抽象類、或者派生類(子類)中的方法。github
須要注意如下幾種狀況:數據庫
單元測試我總結出如下三個優勢。npm
1. 可能會測出功能的隱藏bug編程
我在寫單元測試的時候,遇到過不止一次我認爲輸出結果應該爲 a
,可是結果卻爲 b
的狀況。這時你就要從新審視你的代碼了。瀏覽器
2. 保證代碼重構的安全性安全
組件庫中每個組件均可能會重構或者更新迭代,若是單元測試覆蓋率高的話,修改代碼以後就越可能會發現潛在的問題。好比某些功能代碼不當心刪掉了。這樣會致使用戶更新最新版本時,缺乏了以前使用過的功能,產生一些疑惑。
3. 易於測試的代碼,源於好的設計
一句話,當我開始爲組件庫添加單元測試的時候,我才意識到我寫的代碼是有多麼的爛。
除了這些還有一種設計方法論叫 測試驅動開發(TDD),它是敏捷開發中的一項核心實踐和技術,在開發功能代碼以前,先編寫單元測試用例代碼,測試代碼肯定須要編寫什麼樣的代碼。另外有一種設計方法論叫 行爲驅動開發(BDD)。 感興趣的同窗能夠自行查閱。
接下來進入第二部分,咱們如何來使用單元測試。
單元測試用到的工具大體分爲三部分:分別爲管理工具、測試框架、斷言庫。
我選用的是Karma、Mocha 和 Chai,接下來分別講一下他們仨的做用。
Karma
是一個基於 Node.js 的 JavaScript 測試執行過程管理工具,又稱 Test Runner
。經常使用的管理工具還有 Jest
等。
Mocha
是一個功能豐富的前端測試框架。所謂"測試框架",就是運行測試的工具。經過它,能夠爲 JavaScript 應用添加測試用例,從而保證代碼的質量。Mocha
既能夠基於 Node.js 環境運行也能夠在瀏覽器環境運行。經常使用的測試框架還有 Asmine
、 Jasmine
等。
Chai
是一個斷言庫,相似於 Node 的內置斷言。經過提供許多能夠針對代碼運行的斷言,它使測試變得更加容易。不一樣斷言庫的語法都大同小異,以下圖對比 expect
、should
和 assert
三種斷言庫的區別:
expect(a).to.equal(b) // expect
a.should.equal(b) // should
assert.equal(a, b) // assert
複製代碼
上面的例子中,a
表明輸出的結果,b
表明你想要的結果,三個測試示例都是判斷 a
是否等於 b
。
接下來介紹在項目中真實的示例。
舉例 Switch
組件以下圖:
圖中有兩部分信息,分別爲四個測量維度和標記。
行覆蓋率(line coverage):是否每一行都執行了
函數覆蓋率(function coverage):是否每一個函數都調用了
分支覆蓋率(brancch coverage):是否每一個if代碼塊都執行了
語句覆蓋率(statement coverage):是否每一個語句都執行了
'E':'else path not taken', 出如今if/else語句,表示通過了if測試,但沒通過else測試。
'I':'if path not taken', 出如今if/else語句,沒有通過if測試。
'x(N)':該行執行通過幾回。
未執行的行或代碼段將用紅色突出顯示
咱們看一下 Switch
單元測試代碼。
import Vue from 'vue'
import { destroyVM, createVue, createTest } from '../util'
import Switch from 'packages/switch'
describe('Switch', () => {
let vm
afterEach(() => {
destroyVM(vm)
})
it('use', () => {
Vue.use(Switch)
expect(Vue.component(Switch.name))
.to.be.a('function')
})
it('disabled', () => {
vm = createTest(Switch, {
disabled: true
}, true)
let switchElm = vm.$el.querySelector('.owl-switch-input')
expect(switchElm.disabled).to.be.true
})
it('init callback event', done => {
const btnHandler = sinon.spy()
vm = createVue({
template: ` <owl-switch v-model="val" :init-callback="true" :color="color" @callback="handle"> </owl-switch> `,
data: {
val: false,
color: '#584628',
},
methods: {
handle () {
return btnHandler()
}
}
})
expect(btnHandler).to.be.called
setTimeout(() => {
vm.val = true
done()
})
})
})
複製代碼
測試框架的語法結構爲 describe
、it
、expect
,一個測試文件能夠有多個描述,it
是定義了一條測試用例,第二個參數爲一個回調函數,函數裏可使用斷言庫所提供的返回結果來判斷該測試用例是經過仍是失敗。
解讀一下以上的代碼,我建立三條測試用例,第一條測試用例 Switch
組件是否能正常注入;第二條測試用例判斷給組件設置爲 disabled
時,該組件是否被禁用;第三條測試用例主要測試組件的回調事件是否被執行,若是你有須要延遲調用的邏輯時,須要用到 done
方法。
這樣一個簡單組件的單側就寫完了。由於功能不多,因此須要寫的測試代碼也不多。其實有一些複雜的組件會有7到8個測試用例或者更多。
接下來介紹最後一個部分-集成服務工具
咱們在工做中除了開發功能時,寫代碼須要花費不少時間,構建(build)和測試(test)項目時,也花費了大量的時間。使用構建和測試的自動化工具,會幫助咱們節省一部分時間,從而間接地提升咱們的工做效率。
介紹兩款我正在使用的集成服務工具,Travis CI 和 Codecov。
Travis CI 提供的是持續集成服務(Continuous Integration,簡稱 CI)。它綁定 Github 上面的項目,只要有新的代碼,就會自動抓取。而後,它提供了一個運行環境,可執行測試、完成構建,還能部署到服務器。
持續集成指的是隻要代碼有變動,就自動運行構建和測試,反饋運行結果。確保符合預期之後,再將新代碼"集成"到主幹。
持續集成的好處在於,每次代碼的小幅變動,就能看到運行結果,從而不斷累積小的變動,而不是在開發週期結束時,一會兒合併一大塊代碼。
這裏我只作簡單的介紹,使用教程能夠點擊瞭解更多查看。
Codecov 提供高度集成的工具來分組、合併、歸檔和比較覆蓋率報告。Codecov 與 Travis CI 同樣都支持 Github 帳號登陸,一樣會同步 Github 中的項目。
使用時,先進行安裝 npm i codecov -D
,在 .travis.yml
文件中添加 codecov
執行命令便可。這樣在每次更改代碼時,Travis CI 會執行單側,同時也會執行 codecov
,把結果推給 Codecov。
他們都提供了各自 badge,讓你的項目顯得更加專業。
到這裏關於單元測試部分已經淺顯的講完了,若是你也想在工做中嘗試作單元測試的話,須要本身進行大量的實踐及運用。這個過程當中避免不了挖坑和填坑的重複操做。我認爲能堅持到最後的不僅須要有堅強的毅力,也不僅須要有豐富的知識儲備,而是須要對它有真實的熱愛。祝你們學習進步。