前端測試工具也和前端的框架同樣紛繁複雜,其中常見的測試工具,大體可分爲測試框架、斷言庫、測試覆蓋率工具等幾類。在正式開始本文以前,咱們先來大體瞭解下它們:前端
測試框架的做用是提供一些方便的語法來描述測試用例,以及對用例進行分組。
測試框架可分爲兩種: TDD (測試驅動開發)和 BDD (行爲驅動開發)
常見的測試框架有 Jasmine, Mocha以及本文要介紹的 Jest。react
斷言庫主要提供語義化方法,用於對參與測試的值作各類各樣的判斷。這些語義化方法會返回測試的結果,要麼成功、要麼失敗。常見的斷言庫有 Should.js, Chai.js等。面試
用於統計測試用例對代碼的測試狀況,生成相應的報表,好比istanbul。npm
Jest 是 Facebook 出品的一個測試框架,相對其餘測試框架,其一大特色就是就是內置了經常使用的測試工具,好比自帶斷言、測試覆蓋率工具,實現了開箱即用。
而做爲一個面向前端的測試框架, Jest 能夠利用其特有的快照測試功能,經過比對 UI 代碼生成的快照文件,實現對 React 等常見框架的自動測試。
此外, Jest 的測試用例是並行執行的,並且只執行發生改變的文件所對應的測試,提高了測試速度。目前在 Github 上其 star 數已經破萬;而除了 Facebook 外,業內其餘公司也開始從其它測試框架轉向 Jest ,好比 Airbnb 的嘗試,相信將來 Jest 的發展趨勢仍會比較迅猛。json
Jest 能夠經過 npm 或 yarn 進行安裝。以 npm 爲例,既可用npm install -g jest
進行全局安裝;也能夠只局部安裝、並在 package.json 中指定 test 腳本:前端工程化
{ "scripts": { "test": "jest" } }
Jest 的測試腳本名形如*.test.js
,不論 Jest 是全局運行仍是經過npm test
運行,它都會執行當前目錄下全部的*.test.js
或 *.spec.js
文件、完成測試。promise
表示測試用例是一個測試框架提供的最基本的 API , Jest 內部使用了 Jasmine 2 來進行測試,故其用例語法與 Jasmine 相同。test()
函數來描述一個測試用例,舉個簡單的例子:前端框架
// hello.js module.exports = () => 'Hello world' // hello.test.js let hello = require('hello.js') test('should get "Hello world"', () => { expect(hello()).toBe('Hello world') // 測試成功 // expect(hello()).toBe('Hello') // 測試失敗 })
其中toBe('Hello world')
即是一句斷言( Jest 管它叫 「matcher」 ,想了解更多 matcher 請參考文檔)。寫完了用例,運行在項目目錄下執行npm test
,便可看到測試結果:框架
若測試失敗,會標識出失敗的斷言位置,結果以下:異步
有時咱們想在測試開始以前進行下環境的檢查、或者在測試結束以後做一些清理操做,這就須要對用例進行預處理或後處理。對測試文件中全部的用例進行統一的預處理,可使用 beforeAll()
函數;而若是想在每一個用例開始前進行都預處理,則可以使用 beforeEach()
函數。至於後處理,也有對應的 afterAll()
和 afterEach()
函數。
若是隻是想對某幾個用例進行一樣的預處理或後處理,能夠將先將這幾個用例歸爲一組。使用 describe()
函數便可表示一組用例,再將上面提到的四個處理函數置於 describe()
的處理回調內,就實現了對一組用例的預處理或後處理:
describe('test testObject', () => { beforeAll(() => { // 預處理操做 }) test('is foo', () => { expect(testObject.foo).toBeTruthy() }) test('is not bar', () => { expect(testObject.bar).toBeFalsy() }) afterAll(() => { // 後處理操做 }) })
異步代碼的測試,關鍵點在於告知測試框架測試什麼時候完成,讓其在恰當的時機進行斷言。針對幾種常見的異步代碼形式, Jest 也提供了相應的異步測試語法。首先對於異步回調,向其傳入並執行 done
函數, Jest 會等 done 回調執行結束後,結束測試:
// asyncHello.js module.exports = (name, cb) => setTimeout(() => cb(`Hello ${name}`), 1000) // asyncHello.test.js let asyncHello = require('asyncHello.js') test('should get "Hello world"', (done) => { asyncHello('world', (result) => { expect(result).toBe('Hello world') done() }) })
此外,對於 Promise 控制的異步代碼,能夠直接在 then
回調中進行斷言,只要保證在用例中返回該 Promise 對象便可:
// promiseHello.js module.exports = (name) => { return new Promise((resolve) => { setTimeout(() => resolve(`Hello ${name}`), 1000) }) } // promiseHello.test.js let promiseHello = require('promiseHello.js') it('should get "Hello world"', () => { expect.assertions(1); // 確保至少有一個斷言被調用,不然測試失敗 return promiseHello('world').then((data) => { expect(data).toBe('Hello world') }) })
Jest 也支持 async/await 語法的測試,無需多餘的操做,只要在 await 後進行斷言便可,和同步測試的寫法一致。
Jest 內置了測試覆蓋率工具istanbul,要開啓,能夠直接在命令中添加 --coverage
參數,或者在 package.json 文件進行更詳細的配置。
運行 istanbul 除了會再終端展現測試覆蓋率狀況,還會在項目下生產一個 coverage 目錄,內附一個測試覆蓋率的報告,讓咱們能夠清晰看到分支的代碼的測試狀況。好比下面這個例子:
// branches.js module.exports = (name) => { if (name === 'Levon') { return `Hello Levon` } else { return `Hello ${name}` } } // branches.test.js let branches = require('../branches.js') describe('Multiple branches test', ()=> { test('should get Hello Levon', ()=> { expect(branches('Levon')).toBe('Hello Levon') }); // test('should get Hello World', ()=> { // expect(branches('World')).toBe('Hello World') // }); })
運行 jest --coverage
可看到產生的報告裏展現了代碼的覆蓋率和未測試的行數:
若是咱們把branches.test.js
中的註釋去掉,跑遍測試對象中的全部分支,測試覆蓋率就是100%了:
若是對軟件測試、接口測試、自動化測試、面試經驗交流。感興趣能夠加軟件測試交流:1085991341,還會有同行一塊兒技術交流。
針對前端框架的測試, Jest 的一大特點就是提供了快照測試功能。首次運行快照測試,會讓 UI 框架生產一個可讀的快照,再次測試時便會經過比對快照文件和新 UI 框架產生的快照判斷測試是否經過。對於 React ,咱們能夠經過下面的方法生產一個快照:
import React from 'react'; import Link from '../Link.react'; import renderer from 'react-test-renderer'; it('renders correctly', () => { const tree = renderer.create( <Link page="http://www.facebook.com">Facebook</Link> ).toJSON(); expect(tree).toMatchSnapshot(); });
運行測試,咱們能夠看到生成一個快照文件以下:
exports[`renders correctly 1`] = ` <a className="normal" href="http://www.facebook.com" onMouseEnter={[Function]} onMouseLeave={[Function]} > Facebook </a> ;
這個可讀的快照文件以可讀的形式展現了 React 渲染出的 DOM 結構。相比於肉眼觀察效果的 UI 測試,快照測試直接由Jest進行比對、速度更快;並且因爲直接展現了 DOM 結構,也能讓咱們在檢查快照的時候,快速、準確地發現問題。
除了 React ,Jest 文檔中也提供了針對其餘框架進行測試的指南。
若是你的項目中已經使用了別的測試框架,好比 Mocha,有一個第三方工具jest-codemods能夠自動把用例遷移成 Jest 的用例,下降了遷移成本。
近幾年前端工程化的發展風起雲涌,可是前端自動化測試這塊內容你們卻彷佛不過重視。雖然項目迭代過程當中會有專門的測試人員進行測試,但等他們來進行測試時,代碼已經開發完成的狀態。與之相比,若是咱們在開發過程當中就進行了測試(直接採用 TDD 開發模式、或者針對既有的模塊寫用例),會有以下的好處:
固然,凡事都有兩面性,好處雖然明顯,卻並非全部的項目都值得引入測試框架,畢竟維護測試用例也是須要成本的。對於一些需求頻繁變動、複用性較低的內容,好比活動頁面,讓開發專門抽出人力來寫測試用例確實得不償失。
而那些適合引入測試場景大概有這麼幾個:
以上就是我對前端測試的一點淺見,歡迎斧正。以上內容就是本篇的所有內容以上內容但願對你有幫助,有被幫助到的朋友歡迎點贊,評論。