換一種思路寫代碼,前端測試驅動開發模式(TDD)快速入門

什麼是測試驅動開發模式

測試驅動開發(Test-Driven Development)是一種軟件開發的思惟和方法,個人理解是它是一種開發的循環,先寫測試代碼,再用最小的代碼實現這個測試,再繼續寫測試代碼,繼續用最小的代碼實現。當實現全部的測試用例,代碼也就完成了。javascript

最近也在實踐Tdd開發,和以前先開發,再自測的方向不一樣,此次的開發順序是, 文檔--->測試用例--->代碼--->測試經過--->下一個測試用例。這樣作有如下優缺點:前端

優勢

  • 在開始能夠比較明確本身要作什麼,把錯誤暴露在整個開發流程比較靠前的位置,修改的成本也比較小
  • 在以後對代碼優化的過程當中,由於有測試代碼的存在,能夠更好的優化代碼,優化完以後再執行一遍代碼,而不用擔憂優化過程當中又出錯
  • 經過測試代碼,能夠幫助理清楚程序中關鍵點
  • 也更有利於以後的維護

缺點

  • 加上測試的代碼,會適當增長一些工做量
  • 可能會測的不全面

整體來講,若是對一些基數設施的建設,好比基礎組件等,須要長期維護的項目,Tdd的應用,仍是利大於弊。vue

前端TDD開發環境的搭建

若是想應用Tdd的方法到前端的開發中,主要用到如下幾個工具(工具的用法在後面介紹):java

mocha.js

mocha 主要提供了describe的語法,用來描述測試用例,而且把執行測試後的結果清楚的返回到終端上。
官網:mochajs.org
github: github.com/mochajs/moc…react

chai.js

chai 主要提供了斷言函數assert,用來斷言和比較測試的結果和代碼執行的結果。
官網: www.chaijs.com/
github: github.com/chaijs/chai
assert庫方法文檔:www.chaijs.com/api/assert/…git

sinon.js

sinon 主要用來mock一些東西,好比能夠用sinon mock一個假的函數,sinon也能夠返回這個函數執行與否。
官網: sinonjs.org
github: github.com/sinonjs/github

基礎環境搭建

先npm init生成一個項目。 再執行如下安裝語句:npm

npm install sinon moncha chai sinon-chai --save-dev
複製代碼

創建一個test文件夾,能夠把寫測試用例的Js放在這個文件夾中, 爲了能夠方便執行單元測試,能夠加一個npm scripts,在package.json的scripts中加入以下語句,表示使用mocha去執行test文件夾下的js測試:json

"scripts":{
  "test": "mocha test/**/*.js"
}
複製代碼

在test中創建一個js文件,在文件的中引入這些工具,爲了鏈接sinon 和 chai,要使用到sinon-chai小程序

const chai = require("chai")
const sinon = require("sinon")
const sinonChai = require("sinon-chai")
chai.use(sinonChai)
const assert = chai.assert // 從chai中引出assert
複製代碼

如何實施TDD

如何寫一個單元測試

首先咱們看一個簡單的單元測試代碼:

describe('測試navigateTo方法', ()=>{
  it("new router後存在navigateTo方法", ()=>{
    let newRouter = new VictRouter()
    assert.isFunction(newRouter.navigateTo)
  })
})
複製代碼
  • describe()表示測試的一個大範圍,第一個參數是範圍的名字,第二個是一個回調函數,其中能夠放單元測試代碼
  • it()裏寫單元測試的代碼,第一個參數仍是這個測試的名字,第二個回調函數中放入單元測試代碼
  • assert 就是斷言代碼執行後的結果是什麼,好比這個例子中,由於要測試"實例化後存在navigateTo方法",就斷言new以後的實例包含navigateTo這個函數,因此用到了assert的isFunction的方法
  • 寫完以後運行npm run test, 就能看到測試的運行結果了,若是沒有報錯就是測試成功了

如何寫多個單元測試代碼:

直接在describe中加入多個it函數便可:

describe('測試navigateTo方法',()=>{
    it(`new router 後存在navigateTo方法`, ()=> {
      let newRouter = new VictRouter()
      assert.isFunction(newRouter[key])
    })
  it(`navigateTo的入參類型必須爲object`, ()=>{
    let newRouter = new VictRouter()
    let badFn = function() { throw new newRouter[navigateTo]('1111')}
    assert.throws(badFn, 'this.commonDirectFn is not a function')
  })
})
複製代碼

npm run test以後能夠執行全部的測試

通常的測試思路

  • 能夠先從最簡單的開始測試,好比存在某個方法,入參的類型等等
  • 最好是先寫測試用例,再寫業務代碼
  • 用盡可能小的成本實現測試

善用throw拋出錯誤

在執行的代碼中,特別在開始一些對入參的判斷的代碼,可使用throw出錯誤,再用assert捕獲這個錯誤,這樣能夠比較方便的測試入參是否符合預期。可是使用assert.throws的時候,要用一個函數包裝要測試的代碼:

it(`navigateTo的入參類型必須爲object`, ()=>{
    let newRouter = new VictRouter()
    let badFn = function() { throw new newRouter[navigateTo]('1111')} // 這裏用一個函數包裝
    assert.throws(badFn, 'this.commonDirectFn is not a function') // 再把包裝後的函數傳入throws
  })
複製代碼

使用sinon模擬函數

若是須要模擬一個函數,能夠用sinon去模擬,使用方法:sinon.fake(),而且課已經過這個sinon的called方法判斷函數是否被執行。

let fn = sinon.fake() //生成一個模擬函數
assert(fn.called) //斷言這個函數是否被執行
複製代碼

小結

本文只是對Tdd的一個簡單介紹,適用於快速入門。mocha,chai,sinon的一些高級的用法,還須要經過實踐去學習。 另,本文只是對但純js的測試,react,vue和小程序都有他們本身的ui測試的方案。 想經過本文,讓你們能夠簡單瞭解Tdd,而且學到一種新的思路去寫代碼。

相關文章
相關標籤/搜索