前端單元測試(一) - 入門向

目錄

概述

為何要寫測試?

從自己的經(jīng)驗來說,在開發(fā)階段,寫測試能幫助自己對功能的實現(xiàn),有一個較為全面的思考,并且降低后續(xù)修改引入 Bug 的幾率。在交付之前,就能排除大量的 Bug。在后續(xù)測試,或需求變更的情況下,修改代碼之后,可以保證不對已經(jīng)穩(wěn)定的功能引入新 Bug。從別人處接手項目時,也能大大避免因新接手人員對項目不熟悉,引入的新問題。
總體上來說,為自己的代碼寫測試,是一項首次繁瑣、后續(xù)便利的工作,并且從長遠來看,一個項目后續(xù)修改的頻率要遠遠大于首次的構建和開發(fā),不論對測試、開發(fā)、交接都是利大于弊的╮(╯_╰)╭。
這篇以本人入手時的體驗,簡單介紹前端測試的部分內(nèi)容。

前端測試的類型

有一種關于測試的分類,稱為前端測試金字塔,將前端測試從塔底到塔尖分為:

  • 單元測試(Unit Tests)
    顧名思義,對一個功能單元進行測試,如一個對日期進行格式化的方法。
    單元測試是非常細化和相對全面的,要保證一個單元代碼的可靠性,需要盡可能地對所有情況編寫測試腳本。
  • 快照測試(Snapshot Tests)
    快照測試是對 UI 組件渲染結果的測試。
    在 Jest 中,快照測試并不是對圖片進行比對,而是保存渲染組件的標記,使得快照文件體積小,而測試速度快。
    更多關于 Jest snapshot test
  • 端到端測試(End to End Tests)
    是對模擬我們對項目的實際操作,測試過程較為復雜和繁瑣,耗時長。

想了解更多關于這幾種測試類型的細節(jié),請看 前端測試金字塔

TDD vs BDD

測試驅動開發(fā)(TDD)是先寫測試,根據(jù)測試的內(nèi)容實現(xiàn)具體的功能代碼,再用之前的測試進行驗證。TDD 是用測試來推動功能的實現(xiàn)。
行為驅動開發(fā)(BDD)是從行為的角度來定義測試的內(nèi)容,用自然語言描述測試用例。
有關于 TDD 和 BDD 的思考,可以參考 The Difference Between TDD and BDD

常用前端單元測試框架

常見的測試框架有 Jest,MochaJasmine 等。
這里舉例說明一下 Jest 和 Mocha。

Jest

  • 配置簡單(開箱即用)
  • 自帶斷言庫(在 Jest 中稱為 matchers
  • 內(nèi)置的覆蓋率(coverage)統(tǒng)計
  • 內(nèi)置的快照功能
    Jest 由 Facebook 團隊開發(fā)維護,故對于測試 React、ReactNative 項目支持友好。

使用

(來自官網(wǎng)的例子)
新建一個項目(npm init),新建一個 /src 目錄和 /test 目錄,用于存放功能代碼和測試代碼。
安裝 Jest,無需額外配置:

npm install --save-dev jest
// or
yarn add --dev jest

完成后的目錄如下:

/project
    -/node_modules
    -/src
    -/test

在 /src 文件目錄下新建一個 sum.js 文件,

function sum(a, b) {
    return a + b;
}
module.exports = sum;

在 /test 中新建一個 sum.test.js 文件,引入 sum.js 的方法:

const sum = require('./sum');

test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3);
});

在 package.json 的 scripts 中新增:

"scripts": {
  "test": "jest"
}

之后運行:

npm run test
// or
yarn test

就可以得到結果:

PASS  ./sum.test.js
? adds 1 + 2 to equal 3 (5ms)

上面例子中的“expect(sum(1, 2))”稱為斷言,在 Jest 中叫做“matchers”,Jest 提供了多種 API 滿足不同的情況。
Jest 為每個測試文件預置了一些全局方法和對象,“test” 用來包裹一個最小的測試單元,一系列相關的測試單元可以用 “describe”包裹:

const myBeverage = {
  delicious: true,
  sour: false,
};

describe('my beverage', () => {
  test('is delicious', () => {
    expect(myBeverage.delicious).toBeTruthy();
  });

  test('is not sour', () => {
    expect(myBeverage.sour).toBeFalsy();
  });
});

Mocha

  • 配置自由靈活
  • 自行引入需要的斷言庫
  • 支持幾種不同的測試代碼的組織形式(包括 BDD、TDD 等)
  • 可運行在 Node 環(huán)境和瀏覽器
    Mocha 的有更高的自由度,更能配合需要高度定制化的項目,插件配置方面也能找到大量的參考信息。

使用

安裝方式類似。
Mocha 需要自行引入斷言庫(即需要自行額外安裝對應的庫),在使用上,和 Jest 并沒有太大區(qū)別:

var assert = require('assert')
describe('Array', function() {
  describe('#indexOf()', function() {
    it('should return -1 when the value is not present', function() {
      assert.equal([1,2,3].indexOf(4), -1)
    })
  })
})

可以直接運行:

./node_modules/mocha/bin/mocha

或者也在 package.json 中新增 scripts:

"scripts": {
    "test": "mocha"
}
...
npm test

Mocha 中 describe 是作為 BDD 的一種接口,它同時提供適用 TDD 的接口:suite(), test(), suiteSetup(), suiteTeardown(), setup(), and teardown()等:

suite('Array', function() {
  setup(function() {
    // ...
  });

  suite('#indexOf()', function() {
    test('should return -1 when not present', function() {
      assert.equal(-1, [1,2,3].indexOf(4));
    });
  });
});

除了 BDD、TDD,Mocha 還支持 Exports,QUnit,和 Require-style 接口,具體參考文檔

More

前端測試該寫些什么

剛開始接觸入門前端測試時,最困擾我的就是測試到底該寫什么了。
對 UI 進行測試的目的較為明確,只要根據(jù)頁面需要達到的效果,對照著加入測試即可。但若進行單元測試,或者針對功能進行測試時,我們總是希望覆蓋面能廣一點、考慮的情況能全面一點,以達到更好的測試效果。不同的項目代碼的功能、組織方式大相徑庭,很難有一套通用的定論來指明我們的測試代碼具體應該怎么寫,但一些思考角度是可以分享和借鑒的。
以下是我針對一個功能型(或者說工具型)項目進行測試的幾個方面:

  • 明確的功能點
    即需求方給的明確的需求,以及為了實現(xiàn)這些需求,需要達到的一些標準。
  • 輸入值、輸出值、邊緣數(shù)據(jù)校驗(特別是工具類型的單元)
    如輸入值不符合標準的情況,輸入值不符合標準的情況也可能存在多種情形,都需要分情況考慮。
  • 測試過程中出現(xiàn) Bug 的情況
    即使在開發(fā)過程中通過測試規(guī)避了很多問題,但不可避免仍會有一些特定場景會引出 Bug,功能修復后添加針對該場景的測試腳本,可以規(guī)避該場景 Bug 的重復出現(xiàn)。

寫什么都比沒有開始好

對于不同的項目,需要側重的測試方面也大不相同,真正開始思考如何全面地測試一個項目,并且轉換成測試代碼之后,能大大提升代碼質(zhì)量,提升代碼的復用性、模塊化劃分、全面性。
從長遠上來看也能顯著提升大型項目的開發(fā)效率,特別是參與開發(fā)人員多、交接頻繁、迭代頻率高的項目。

Thanks.

其他參考

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 什么是單元測試 單元測試(unit testing)是指對軟件中的最小可測試單元進行檢查和驗證。 簡單來說,單元就...
    kyleBoy閱讀 1,661評論 0 3
  • 前言 隨著Web業(yè)務的日益復雜化和多元化,前端開發(fā)也有了前端工程化的概念,前端工程化成為目前前端架構中重要的一環(huán),...
    CharmSun閱讀 1,361評論 0 1
  • 大多數(shù)開發(fā)者都知道需要寫單元測試,但是不知道每個單元測試應用的主要內(nèi)容以及如何做單元測試,在介紹jest測試框架前...
    糖小工閱讀 6,221評論 0 11
  • 前言 本篇文章是我在學習前端自動化單元測試時的一些思路整理,之前也從未接觸過單元測試相關工具,如有錯漏,請讀者斧正...
    Awey閱讀 12,917評論 8 37
  • 今天把兩輪卸掉,寶貝兒學騎自行車。 這段時間看到很多同齡小朋友都可以騎兩輪自行車,寶貝兒也是羨慕!她也想自己學習兩...
    東澤666閱讀 155評論 0 0

友情鏈接更多精彩內(nèi)容