由於常常須要維護一些大型的業務項目和一些本身的開源項目,因此爲了更好的「規範」代碼質量和迭代的穩定性,開始寫了一些單測。下面也主要是本身的一些總結吧,因爲測試工具和框架不少,這裏只介紹一些browser端經常使用的測試工具,文中若是有問題也歡迎拍正!!🙂javascript
以前咱們開發項目的時候,老是會忽略去寫一寫單測,大多數緣由多是以爲沒有時間或者是浪費時間。並且還須要去維護測試用例。 其實通常項目隨着時間的遷移,會變得愈來愈複雜和龐大,這時候若是咱們對某一個公共模塊改動,而其餘人也依賴了這個模塊,可能就會致使別人的功能出現bug。 有了自動化測試,開發者會更加信任本身的代碼。開發者不再會害怕將代碼交給別人維護,不用擔憂別的開發者在代碼裏搞「破壞」。後人接手一段有測試用例的代碼,修改起來也會更加從容。測試用例裏很是清楚的闡釋了開發者和使用者對於這端代碼的指望和要求,也很是有利於代碼的傳承。html
TDD 也就是測試驅動開發,簡單的說,即在寫任何功能代碼以前,先寫它的測試代碼。具體步驟:前端
BDD 即 行爲驅動開發,能夠理解爲也是 TDD 的分支,即也是測試驅動,但 BDD 強調的是寫測試的風格,即測試要寫得像天然語言,運用一些好比expect、should
等跟天然語言相近的斷言,讓項目的各個成員甚至產品都能看懂測試,甚至編寫測試。java
不論是 TDD 仍是 BDD,咱們來對比一些兩者的寫法:node
// TDD
suite('Array', function() {
setup(function() {
});
test('equal -1 when index beyond array length', function() {
assert.equal(-1, [1,2,3].indexOf(4));
});
});
// BDD
describe('Array', function() {
before(function() {
});
it('should return -1 when no such index', function() {
[1,2,3].indexOf(4).should.equal(-1);
});
});
複製代碼
簡單的看, BDD 風格寫的會更容易理解,更加語義化。webpack
在單元測試時,開發預計在程序運行到某個節點位置,須要判斷某些邏輯條件必須知足,這樣下面的一些業務邏輯才能夠進行下去,若是不知足,程序就會"報錯"甚至是"崩潰"。斷言在單測中,也是主要用來肯定某段程序執行結果應該是某個值這樣的一個預期。git
斷言庫即提供一套 API 幫助開發者在單元測試的過程當中斷定某個值是否符合預期,好比:es6
value.should.equal(1);
value.should.be.an.Object();
複製代碼
expect(value).to.be(1)
expect(value).to.be.an('object')
複製代碼
Chai is a BDD / TDD assertion library for node and the browser that can be delightfully paired with any javascript testing framework.github
chai 提供了三種斷言風格來分別適用於 BDD 和 TDD。expect/should
API 對應BDD風格,Assert API
對應TDD風格。 web
所謂"測試框架",就是運行測試的工具。經過它,能夠爲JavaScript
應用添加測試,從而保證代碼的質量。
Mocha
(發音"摩卡")誕生於2011年,是如今最流行的JavaScript測試框架之一,在瀏覽器和Node環境均可以使用。 更多關於mocha
的使用和介紹能夠參考阮老師的這篇文章測試框架 Mocha 實例教程
Jasmine 不依賴於任何框架,因此適用於全部的 Javascript 代碼。使用一個全局函數 describe
來描述每一個測試,而且能夠嵌套。describe
函數有2個參數,一個是字符串用於描述,一個是函數用於測試。在該函數中可使用全局函數it
來定義Specs
,也就是單元測試的主要內容, 使用 expect
函數來測試:
describe("A suite is just a function", function() {
var a;
it("and so is a spec", function() {
a = true;
expect(a).toBe(true);
});
});
複製代碼
相比於服務端開發,前端開發在測試方面始終面臨着一個嚴峻的問題,那就是瀏覽器兼容性。前端開發中瀏覽器兼容性是一個永遠的問題,並且我認爲即便解決了瀏覽器的兼容性問題,將來在移動開發方面,設備兼容性也是一個問題。
因此在自動化測試方面也是如此,即便全部的單元測試集中在了一個runner中,前端測試仍然要面對至少4個瀏覽器內核以及3個電腦操做系統加2個或更多移動操做系統,況且還有令移動開發人員頭疼的Android的碎片化問題。不過能夠安心的是,早已存在這樣的工具能夠捕獲不一樣設備上的不一樣瀏覽器,並使之隨時更新測試結果,甚至能夠在一個終端上看到全部結果。下面咱們主要介紹 Karma
Karma是一個基於 Node.js 的 JavaScript 測試執行過程管理工具(Test Runner)。該工具可用於測試全部主流Web瀏覽器,也可集成到 CI(Continuous integration)工具,也可和其餘代碼編輯器一塊兒使用。這個測試工具的一個強大特性就是,它能夠監控(Watch)文件的變化,而後自行執行,經過console.log
顯示測試結果。
測試的時候,咱們經常關心,是否全部代碼都測試到了。 這個指標就叫作"代碼覆蓋率"(code coverage)。它有四個測量維度。
這個軟件以土耳其最大城市伊斯坦布爾命名,由於土耳其地毯世界聞名,而地毯是用來覆蓋的。
詳細的文檔參考阮老師的代碼覆蓋率工具 Istanbul 入門教程
下面咱們來搭建一個ES6 + jasmine + karma + Istanbul + webpack 的基礎測試工具。 首先來搭建一個簡單的es6
環境:
mkdir example
cd example
npm i babel-core bable-loader babel-preset-env --save
複製代碼
而後建立.babelrc
文件
{
"presets": [
"env"
]
}
複製代碼
接着咱們須要安裝 karma
測試工具:
$ npm install karma --save-dev
$ npm install karma-jasmine karma-chrome-launcher jasmine-core --save-dev
複製代碼
接下來初始化karma
:
karma init
複製代碼
這樣目錄中便會多了一個karma.conf.js
這樣的一個文件。爲了在測試的時候可使用es6
,咱們須要使用karma-webpack
:
npm i webpack karma-webpack --save
複製代碼
接下來,就是咱們熟悉的工做了,寫一個加載測試腳本的webpack
配置文件,好比webpack.test.js
:
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
}
]
}
};
複製代碼
再改寫一下咱們的karma.conf.js
, 引入webpack
:
const webpack = require('../webpack.config')
module.exports = function(config) {
config.set({
basePath: '',
frameworks: ['jasmine'],
files: [
'test/**/*.spec.js'
],
exclude: [
],
preprocessors: {
'test/add.spec.js': ['webpack']
},
webpack: webpack,
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
concurrency: Infinity
})
}
複製代碼
運行karma start
。
當前咱們的reporters
設置的是progress
,因此只會展現最終測試結果,和執行錯誤的語句。若是你想看到每一條的執行結果,能夠安裝karma-spec-reporter
npm install karma-spec-reporter --save-dev
複製代碼
而後加入spec
到karma.conf.js 的 reporters
中:
reporters: ['spec']
複製代碼
這樣就會生成這樣的形式報告:
其次咱們須要添加istanbul
進行代碼覆蓋率測試。首先咱們須要安裝一個babel
插件:
npm install babel-plugin-istanbul --save-dev
複製代碼
而後修改咱們的.babelrc
文件:
{
// ...
"env": {
"test": {
"presets": ["env"],
"plugins": ["istanbul"]
}
}
}
複製代碼
經過使用.babelrc
裏的env
屬性,當咱們經過設置BABEL_ENV=test
的時候即可以去執行代碼測試的相關插件,這在複雜項目中的測試配置中頗有用。 接下來,爲了能生成覆蓋率測試報告,咱們還須要安裝一個 karma Istanbul 插件karma-coverage
:
npm install karma karma-coverage --save-dev
複製代碼
而後咱們改一下package.json
裏面的script
腳本:
"scripts": {
"test": "cross-env BABEL_ENV=test karma start test/karma.conf.js"
}
複製代碼
運行
npm run test
複製代碼
打開 coverage
裏面的index.html
文件:
能夠看到覆蓋率的一些測試結果。可是這樣有點不太方便,但願能能夠直接在控制檯輸出就行了。因此咱們須要改一下karma.conf.js
文件,加上這樣一個屬性:
coverageReporter: {
dir: './coverage',
reporters: [
{ type: 'lcov', subdir: '.' },
{ type: 'text-summary' } // 在控制檯輸出摘要
]
}
複製代碼
這樣咱們在控制檯即可以打印出基本的覆蓋率測試結果:
至此。已經完成了一個測試環境的搭建,能夠知足大部分工程的單測配置。
可能平時因爲你們更加關心業務代碼,而會忽略一些前端的測試工做,網上的資料也是零零碎碎的,沒有一個系統的總結和介紹。這裏整理了一些測試工具的使用方法,但願能夠對你有所幫助。而後本文全部代碼和原始出處發表在我的博客中。也歡迎閱讀以前的博文: