摘要:為什么要寫單元測(cè)試減少提高代碼質(zhì)量,保證你的代碼是可測(cè)試的放心重構(gòu)當(dāng)你每個(gè)方法都寫了單元測(cè)試的時(shí)候,你每一個(gè)改動(dòng)都會(huì)影響相應(yīng)的單元測(cè)試,這樣你不用費(fèi)盡心思的考慮哪里會(huì)有影響,特別是復(fù)雜項(xiàng)目或非核心功能不易被測(cè)試到,從而導(dǎo)致的產(chǎn)生。
為什么要寫單元測(cè)試
減少bug
提高代碼質(zhì)量,保證你的代碼是可測(cè)試的
放心重構(gòu)
當(dāng)你每個(gè)方法都寫了單元測(cè)試的時(shí)候,你每一個(gè)改動(dòng)都會(huì)影響相應(yīng)的單元測(cè)試,這樣你不用費(fèi)盡心思的考慮哪里會(huì)有影響,特別是復(fù)雜項(xiàng)目或非核心功能(不易被測(cè)試到),從而導(dǎo)致bug的產(chǎn)生。
當(dāng)你的代碼不可測(cè)試的時(shí)候,就得考慮你的代碼是否需要重構(gòu)的。好的代碼應(yīng)該是職責(zé)分明且單一,顆粒度小且易于測(cè)試。
當(dāng)你重構(gòu)時(shí),特別是大范圍的重構(gòu),你就有勇氣和信心了。
那么單元測(cè)試需要有那些要素呢
測(cè)試框架
測(cè)試報(bào)表
測(cè)試覆蓋率
斷言
mock
測(cè)試框架選用 mocha 官方文檔
安裝
npm install mocha
package.json
"scripts": { "test": "mocha --recursive --require babel-core/register tests/Js/test" }
mocha默認(rèn)會(huì)找到項(xiàng)目的根目錄下的 test目錄,但是很多人項(xiàng)目目錄中單元測(cè)試目錄并不是test,而是在/tests/Js/test中,在scripts中,后面加上單元測(cè)試路徑,就可以修改默認(rèn)地址
recursive參數(shù)代表查找 目錄的所有子目錄下的單元測(cè)試,否則只會(huì)查找當(dāng)前目錄下的單元測(cè)試
node中并不支持某些es6語(yǔ)法,需要通過(guò)babel編譯,所以需要添加 --require babel-core/register
同時(shí)需要在項(xiàng)目根目錄添加.babelrc文件
{ "presets": [ "es2015" ] }
現(xiàn)在在 tests/Js/test目錄下創(chuàng)建一個(gè)文件 test.js
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); }); }); });
命令行中執(zhí)行 npm run test 結(jié)果如下
以上我們知道了如何引入前端測(cè)試框架,es6語(yǔ)法問(wèn)題,執(zhí)行路徑問(wèn)題
有時(shí)候命令行的結(jié)果看著不明了,想要輸出測(cè)試報(bào)告呢
這時(shí)候可以使用 mochawesome
安裝
npm install --save-dev mochawesome
package.json
"scripts": { "test": "mocha --recursive --reporter mochawesome --require babel-core/register tests/Js/test" }
在scripts命令中,添加 --reporter mochawesome
執(zhí)行命令
npm run test
結(jié)果如圖,將會(huì)生成 html文件和json文件
"代碼覆蓋率"(code coverage)。它有四個(gè)測(cè)量維度。
行覆蓋率(line coverage):是否每一行都執(zhí)行了
函數(shù)覆蓋率(function coverage):是否每個(gè)函數(shù)都調(diào)用了
分支覆蓋率(branch coverage):是否每個(gè)if代碼塊都執(zhí)行了
語(yǔ)句覆蓋率(statement coverage):是否每個(gè)語(yǔ)句都執(zhí)行了
那么如何知道每個(gè)js的覆蓋率呢
這時(shí)候用到了 istanbul 和 babel-istanbul
安裝
npm install istanbul npm install babel-istanbul
package.json
"scripts": { "test:cover": "babel-node ./node_modules/.bin/babel-istanbul cover _mocha -- tests/Js/* -R spec --recursive }
istanbul他也是不支持一些es6語(yǔ)法的,所以也需要babel轉(zhuǎn)譯
使用cover參數(shù)結(jié)合mocha,--代表后面參數(shù)傳遞給mocha
執(zhí)行命令
npm run test:cover
結(jié)果如圖
Mocha本身不帶斷言庫(kù),所以必須先引入斷言庫(kù)。
我們這里使用 chai
npm install chai
chaijs有三種斷言風(fēng)格,詳細(xì)查看官網(wǎng)
jquery作為大部分都在使用的庫(kù),那么如何對(duì)這類的代碼進(jìn)行單元測(cè)試呢
比如以下代碼
hide-element.js
export const hideElement = ($element) => { $element.on("click", ".hide", function() { $(this).hide(); }); };
首先node環(huán)境和瀏覽器環(huán)境是不一樣的,所以我們跑這類的單元測(cè)試就需要模擬出瀏覽器環(huán)境
我們需要安裝 jsdom
npm install jsdom
test.js 如下
const assert = require("chai").assert; const { hideElement } = require("xxxx/hide-element.js"); describe("test:hide-element.js", function(done) { before(function() { let { JSDOM } = require("jsdom"); let dom = new JSDOM(``,{ url: "http://127.0.0.1/", referrer: "http://127.0.0.1/", contentType: "text/html", userAgent: "Mellblomenator/9000", includeNodeLocations: true, }); global.window = dom.window; global.$ = require("jquery"); hideElement($("body")); }); it("click event", function() { $("body").find(".hide").trigger("click"); assert.equal($(".hide").css("display"), "none"); }); });
mocha 由 describe,it基本元素組成
mocha 有四個(gè)鉤子函數(shù) before,after,beforeEach,afterEach
因?yàn)閚ode中引入依賴時(shí)會(huì)緩存模塊,初始化jsdom環(huán)境時(shí),最好在before中,防止污染jsdom環(huán)境,導(dǎo)致不同的單元測(cè)試之間互相影響
需要測(cè)試的代碼中依賴了其他的模塊時(shí),為了測(cè)試需要測(cè)試的代碼,而不去關(guān)心依賴的模塊,這時(shí)候我們需要 sinon 去mock掉相關(guān)依賴
demo.js
import api from "api"; export const demo = (arg) => { if (arg == 1) { return api.get({ params: params }); } return "ok"; };
test.js
import { demo } from "xx/demo.js"; const assert = require("chai").assert; const sinon = require("sinon"); import api from "api"; describe("demo", function() { it("demo(1)", function() { //mock api的get方法,并且指定返回值為 "N" let apiGet = sinon.stub(api, "get").returns("N"); let expectedParams = {params: "yes"}; let res = demo(1); //automate clean-up,防止影響其他單元測(cè)試 apiGet.restore(); //斷言調(diào)用api.get 是傳入的參數(shù)為 {params: "yes"} sinon.assert.calledWith(apiGet, expectedParams); assert.equal(res, "N"); }); });
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/93583.html
摘要:使用集成單元測(cè)試上項(xiàng)目地址安裝依賴測(cè)試框架可視化報(bào)表覆蓋率替換依賴斷言命令命令命令執(zhí)行單元測(cè)試,并打開(kāi)測(cè)試報(bào)告頁(yè)面和覆蓋率頁(yè)面執(zhí)行生成單元測(cè)試覆蓋率并打開(kāi)執(zhí)行單個(gè)單元測(cè)試文 使用 mocha 集成單元測(cè)試(上) 項(xiàng)目地址:https://github.com/Jay-tian/j... 安裝依賴 yarn add jquery mocha mochawesome istanbu...
摘要:加上測(cè)試覆蓋率檢查,就能夠提供足夠的信息,來(lái)斷言代碼的行為是否符合期望。測(cè)試的相關(guān)技術(shù)是程序的代碼覆蓋率工具,以土耳其最大城市伊斯坦布爾命名。 showImg(https://segmentfault.com/img/remote/1460000010260434); 敏捷軟件開(kāi)發(fā)中,最重要實(shí)踐的就是測(cè)試驅(qū)動(dòng)開(kāi)發(fā),在單元測(cè)試層面,我們?cè)囍鴮?shí)現(xiàn)一個(gè)重要的指標(biāo)就是測(cè)試覆蓋率。測(cè)試覆蓋率衡量...
摘要:基本上,測(cè)試金字塔描述你應(yīng)該編寫單元測(cè)試集成測(cè)試和端到端測(cè)試。集成測(cè)試要比端到端測(cè)試多,單元測(cè)試甚至要更多一些。應(yīng)用程序單元測(cè)試編寫單元測(cè)試,是為了看看給定的模塊單元是否工作。 本文轉(zhuǎn)載自:眾成翻譯譯者:網(wǎng)絡(luò)埋伏紀(jì)事鏈接:http://www.zcfy.cc/article/1754原文:https://blog.risingstack.com/node-hero-node-js-un...
摘要:本文只討論單測(cè)的范疇,對(duì)集成測(cè)試有興趣的話,可以看下的集成測(cè)試代碼。前端單測(cè)現(xiàn)狀測(cè)試本質(zhì)上就是假定一個(gè)輸入,然后判斷得到預(yù)期的輸出。 原文發(fā)于我的博客:https://github.com/hwen/blogS... 要不要寫單測(cè)? 關(guān)于這個(gè) cnode 上就有個(gè)很有意思的討論 做個(gè)調(diào)查,你的 Node 應(yīng)用有寫單測(cè)嗎? 看完這個(gè)應(yīng)該會(huì)有結(jié)論?如果沒(méi)有,就回帖跟別人探討下~ 測(cè)試 測(cè)試...
摘要:安裝注意版本為為支持語(yǔ)法安裝依賴包注意為了使支持語(yǔ)法,在加入注意為了使支持語(yǔ)法,在加入小貓快跳最終運(yùn)行或都可以參考 安裝 mocha, chai,mochawesome,istanbul npm install mocha chai mochawesome istanbul@1.0.0-alpha.2 --save-dev 注意1: istanbul 版本為 ^1.0.0-alpha....
閱讀 1422·2021-11-15 11:45
閱讀 3186·2021-09-27 13:36
閱讀 2920·2019-08-30 15:54
閱讀 1043·2019-08-29 12:38
閱讀 2974·2019-08-29 11:22
閱讀 3063·2019-08-26 13:52
閱讀 2099·2019-08-26 13:30
閱讀 654·2019-08-26 10:37