單元測試簡介
單元測試(unit testing),是指對軟件中的最小可測試單元進行檢查和驗證。
簡單來說,單元就是人爲規定的最小的被測功能模塊。單元測試是在軟件開發過程中要進行的最低級別的測試活動,軟件的獨立單元將在與程序的其他部分相隔離的情況下進行測試。
端到端測試(e2e測試)
e2e測試是把我們的程序堪稱是一個黑盒子,我不懂你內部是怎麼實現的,我只負責打開瀏覽器,把測試內容在頁面上輸入一遍,看是不是我想要得到的結果。
e2e代碼是測試所有的需求是不是都可以正確的完成,而且最終要的是在代碼重構,js改動很多之後,需要對需求進行測試的時候測試代碼是不需要改變的,你也不用擔心在重構後不能達到客戶的需求。
單元測試的目的
當你的項目足夠大的時候,在疊加模塊和組件的過程中,是很有可能影響之前的模塊。但是被影響的模塊已經通過了測試,我們在迭代的時候,很少有測試人員會去重新測試這個系統。所以,被影響的模塊很可能就有了一個隱形的bug被部署到線上。因此我們採用自動化測試。
最主要的作用是對於大型項目,在每次迭代的時候, 可以保證整個系統的正確運行, 確保系統的健壯。
單元測試的比較
jest + Vue Test Utils
1.Jest是 Facebook 的一套開源的 JavaScript 測試框架, 它自動集成了斷言、JSDom、覆蓋率報告等開發者所需要的所有測試工具,配置較少,對vue框架友好。
2.Vue Test Utils 是 Vue.js 官方的單元測試實用工具庫,爲jest和vue提供了一個橋樑,暴露出一些接口,讓我們更加方便的通過Jest爲Vue應用編寫單元測試。
3.vue-cli 默認的單元測試也是使用的這套方案
對於不瞭解Vue Test Utils 的同學可以先看這裏 VueTestUtils,
想了解Jest 的同學可以看這裏 Jest
Karma + Mocha+ + Chai+ Vue-Test-Utils
1 多個框架配合在一起,配製繁瑣
2 解決問題需要對多個框架熟悉才能進行精準定位,學習成本高
組件的單元測試有很多好處:
(官方文檔)
- 提供描述組件行爲的文檔
- 節省手動測試的時間
- 減少研發新特性時產生的 bug
- 改進設計
- 促進重構
自動化測試使得大團隊中的開發者可以維護複雜的基礎代碼。
組件之所以難以測試,是因爲其有太多的 props、依賴、引用的模型和對全局變量的訪問 – 這都是不良設計的標誌。
一個設計不佳的組件,就會變成無法測試的,進而你就會簡單的跳過單元測試,又導致了其保持未測試狀態,變成一個惡性循環。
斷言庫
斷言庫主要提供上述斷言的語義化方法,用於對參與測試的值做各種各樣的判斷。這些語義化方法會返回測試的結果,要麼成功、要麼失敗。常見的斷言庫有 Should.js, Chai.js 等。
測試用例 test case
爲某個特殊目標而編制的一組測試輸入、執行條件以及預期結果,以便測試某個程序路徑或覈實是否滿足某個特定需求。
一般的形式爲:
it('should ...', function() {
...
expect(sth).toEqual(sth);
});
測試套件 test suite
通常把一組相關的測試稱爲一個測試套件
一般的形式爲:
describe('test ...', function() {
it('should ...', function() { ... });
it('should ...', function() { ... });
...
});
Jest
編寫單元測試的語法通常非常簡單;對於jest來說,由於其內部使用了 Jasmine 2 來進行測試,故其用例語法與 Jasmine 相同。
實際上,只要先記這住四個單詞,就足以應付大多數測試情況了:
describe: 定義一個測試套件
it:定義一個測試用例
expect:斷言的判斷條件
toEqual:斷言的比較結果
describe('test ...', function() {
it('should ...', function() {
expect(sth).toEqual(sth);
expect(sth.length).toEqual(1);
expect(sth > oth).toEqual(true);
});
});
Vue Test Utils
它模擬了一部分類似 jQuery 的 API,非常直觀並且易於使用和學習,提供了一些接口和幾個方法來減少測試的樣板代碼,方便判斷、操縱和遍歷 Vue Component 的輸出,並且減少了測試代碼和實現代碼之間的耦合。
一般使用其 mount() 或 shallowMount() 方法,將目標組件轉化爲一個 Wrapper 對象,並在測試中調用其各種方法,例如:
import { mount } from '@vue/test-utils'
import Foo from './Foo.vue'
describe('Foo', () => {
it('renders a div', () => {
const wrapper = mount(Foo)
expect(wrapper.contains('div')).toBe(true)
})
})
總結
單元測試作爲一種經典的開發和重構手段,在軟件開發領域被廣泛認可和採用;前端領域也逐漸積累起了豐富的測試框架和方法。
單元測試可以爲我們的開發和維護提供基礎保障,使我們在思路清晰、心中有底的情況下完成對代碼的搭建和重構。
封裝好則測試易,反之不恰當的封裝讓測試變得困難。
可測試性是一個檢驗組件結構良好程度的實踐標準。