本篇並不是完整指導讀者如何進行單元測試,可是會結合部分例子講解如何編寫測試代碼,從而引起讀者自行思考,而後會給出編寫單元測試途中建議。javascript
舉個例子,咱們本身寫了一個校驗密碼格式(同時知足數字大小寫字母)的函數以下:html
function isRightPassWord(password) {
const pattern = new RegExp(/^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])[a-zA-Z0-9]{8,16}$/);
const isMatched = pattern.test(password);
if (!isMatched) {
return false;
}
return true;
}
複製代碼
那問題來了,咱們如何去進行測試呢?若咱們並無寫過任何的單元測驗,其實很難下手,咱們並不清楚測試點在哪裏?那咱們一塊兒思考幾個問題吧。vue
這部分咱們要描述好,咱們對應測試的函數是什麼,轉化成代碼就以下:java
describe('isRightPassWord function', () => {});
複製代碼
這部分咱們須要想一想,該函數的做用究竟是什麼,已經想一想對應的邊際狀況。因此該函數是幫助咱們校驗字符串是否同時知足數字大小寫字母的,想到一個如傳空的邊際狀況,如上思路轉成代碼,就是以下:react
test('with empty params', () => {});
test('with wrong params Aasdfxzs', () => {});
test('with correct params 123aAbBCc', () => {});
複製代碼
這部分咱們須要講對應的上述條件的參數傳入被測函數,斷言對應的預期輸出,而後運行程序,查看實際輸出是否知足咱們預期,轉化成對應的代碼段,就是以下:git
// with empty params
expect(isRightPassWord()).toBe(false);
// with wrong params Aasdfxzs
expect(isRightPassWord('Aasdfxzs')).toBe(false);
// with correct params 123aAbBCc
expect(isRightPassWord('123aAbBCc')).toBe(true);
複製代碼
最後一步,運行程序查看實際輸出是否符合咱們的預期,而後繼續書寫其餘測試代碼,以後即是紅綠燈遊戲了。github
有一個問題,按照上文思路咱們是在函數完成後,進行補充對應的單測。過程實際體驗上和直接在業務層使用並無什麼差異,只是幫助咱們後續維護對應模塊有了一層保障機制。api
可是可否先寫好對應的測試,而後根據測試在驅動咱們編寫對應的函數呢?這就是TDD概念。其實這樣更符合咱們的編寫代碼習慣,只是將部分前置條件轉化爲對應的測試代碼。app
解釋一下,在編寫代碼以前會思考對應的需求,更可能是實現部分是如何實現該需求,而後邊在業務邏輯層使用,邊修改對應的代碼段,然則這樣循環機制中跳出的條件,直觀的是知足了直接需求條件,但部分邊界條件或許在需求測試期間被發現,而後從新開啓循環機制,而跳出的條件就是修復對應問題並知足直接條件。框架
咱們一塊兒優化對應的流程,起點咱們會思考對應的需求,將其拆解出若干個問題。如何對應的直接需求?對應的邊際狀況有哪些?而後根據對應的問題,進行書寫測試代碼,完成後運行測試,開始根據紅綠燈遊戲進行編寫功能。
這時候你應該會有一個問題,這樣作會形成時長大量增多吧?固然,其實思考的時候二者是差很少的,或是隻是多了一步將思考轉化成對應測試的步驟。那咱們的問題簡化爲如何減小書寫測試的時間?多寫,提取對應的模型,加入編輯器的 live Template 中。
推薦官方教程,結合澳大利亞小哥的指南進行食用。若使用的CLI建立,可借鑑此文。
借用Edd Yerburgh文中的一個例子,改寫以下:
// src/components/Foo.vue
<template>
<div class="foo">
<button id="change-message" @click="changeMessage">Change message</button>
</div>
</template>
<script>
export default {
data() {
return {
msg: 'Welcome to Your Vue.js App'
};
},
methods: {
changeMessage() {
this.msg = 'new message'
}
}
}
</script>
複製代碼
注意:你須要根據官網去安裝一堆的依賴包,而後如果自建項目,你須要處理好 Webpack 對應的loader問題。
// src/components/Foo.spec.js
import { expect } from 'chai'
import { mount } from '@vue/test-utils'
import Foo from './Foo.vue'
describe('Foo.vue', () => {
it('changes h1 text when #change-text is clicked', () => {
const wrapper = mount(Foo)
const changeMessage = wrapper.find('#change-message')
changeMessage.trigger('click')
const h1 = wrapper.find('h1')
expect(h1.text()).to.equal('new message')
})
})
複製代碼
@vue/test-utils
提供了對應的函數,在測試環境實現了不一樣的掛載方式,或是你不清楚掛載方式的區別,請查看對應的官網,或是React單元測試筆記中的部分概念。官網也總結了對應的經常使用技巧。
很久沒主要寫過了 React 測試相關代碼,因此就不一一贅述對應的思路以及流程,畢竟單測方式是同樣的。查看了對應官網是有提供對應的測試依賴的。但我記得通常都是測試框架使用Jest + Enzyme。Enzyme
和@vue/test-utils
包裹組件,而後暴露出來的接口使用習慣仍是和jQuery的使用習慣差很少的。
還記得引言篇的問題嗎?
你是否信任你寫的代碼嗎?
你如何檢測代碼質量?
你如何驗證你的記性?
將單測加入咱們實踐中,確實存在不少阻力,其做用是長遠的。不只幫助咱們細化自身處理方式,還幫助咱們引起自身的思考。如何將函數/函數抽離的更符合單一原則?如何區分功能界限?單測要不要強調覆蓋率?