国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

在Nodejs中貫徹單元測試

enali / 2909人閱讀

摘要:原文鏈接在中貫徹單元測試在團(tuán)隊合作中,你寫好了一個函數(shù),供隊友使用,跑去跟你的隊友說,你傳個值進(jìn)去,他就會返回結(jié)果了。如果你也為社區(qū)貢獻(xiàn)過,想更多人使用的話,加上單元測試吧,讓你的值得別人信賴。

原文鏈接:BlueSun | 在Nodejs中貫徹單元測試

在團(tuán)隊合作中,你寫好了一個函數(shù),供隊友使用,跑去跟你的隊友說,你傳個A值進(jìn)去,他就會返回B結(jié)果了。過了一會,你隊友跑過來說,我傳個A值卻返回C結(jié)果,怎么回事?你丫的有沒有測試過啊?

大家一起寫個項目,難免會有我要寫的函數(shù)里面依賴別人的函數(shù),但是這個函數(shù)到底值不值得信賴?單元測試是衡量代碼質(zhì)量的一重要標(biāo)準(zhǔn),縱觀Github的受歡迎項目,都是有test文件夾,并且buliding-pass的。如果你也為社區(qū)貢獻(xiàn)過module,想更多人使用的話,加上單元測試吧,讓你的module值得別人信賴。

要在Nodejs中寫單元測試的話,你需要知道用什么測試框架,怎么測試異步函數(shù),怎么測試私有方法,怎么模擬測試環(huán)境,怎么測試依賴HTTP協(xié)議的web應(yīng)用,需要了解TDD和BDD,還有需要提供測試的覆蓋率。

本文的示例代碼會備份到 Github : unittest-demo

目錄

測試框架

斷言庫

需求變更

異步測試

異常測試

測試私有方法

測試Web應(yīng)用

覆蓋率

使用Makefile把測試串起來

持續(xù)集成,Travis-cli

一些觀點

彩蛋

整理

測試框架

Nodejs的測試框架還用說?大家都在用,Mocha。

Mocha 是一個功能豐富的Javascript測試框架,它能運(yùn)行在Node.js和瀏覽器中,支持BDDTDDQUnitExports式的測試,本文主要示例是使用更接近與思考方式的BDD,如果了解更多可以訪問Mocha的官網(wǎng)

測試接口

Mocha的BDD接口有:

describe()

it()

before()

after()

beforeEach()

afterEach()

安裝

npm install mocha -g

編寫一個穩(wěn)定可靠的模塊

模塊具備limit方法,輸入一個數(shù)值,小于0的時候返回0,其余正常返回

exports.limit = function (num) {
  if (num < 0) {
    return 0;
  }
  return num;
};
目錄分配

lib,存放模塊代碼的地方

test,存放單元測試代碼的地方

index.js,向外導(dǎo)出模塊的地方

package.json,包描述文件

測試
var lib = require("index");

describe("module", function () {
  describe("limit", function () {
    it("limit should success", function () {
      lib.limit(10);
    });
  });
});
結(jié)果

在當(dāng)前目錄下執(zhí)行mocha

$ mocha

  ?

  ? 1 test complete (2ms)
斷言庫

上面的代碼只是運(yùn)行了代碼,并沒有對結(jié)果進(jìn)行檢查,這時候就要用到斷言庫了,Node.js中常用的斷言庫有:

should.js

expect.js

chai

加上斷言

使用should庫為測試用例加上斷言

it("limit should success", function () {
  lib.limit(10).should.be.equal(10);
});
需求變更

需求變更啦:?limit這個方法還要求返回值大于100時返回100。

針對需求重構(gòu)代碼之后,正是測試用例的價值所在了,

它能確保你的改動對原有成果沒有造成破壞。

但是,你要多做的一些工作的是,需要為新的需求編寫新的測試代碼。

異步測試 測試異步回調(diào)

lib庫中新增async函數(shù):

exports.async = function (callback) {
  setTimeout(function () {
    callback(10);
  }, 10);
};    

測試異步代碼:

describe("async", function () {
  it("async", function (done) {
    lib.async(function (result) {
      done();
    });
  });
});
測試Promise

使用should提供的Promise斷言接口:

finally | eventually

fulfilled

fulfilledWith

rejected

rejectedWith

then

測試代碼

describe("should", function () {
  describe("#Promise", function () {
    it("should.reject", function () {
      (new Promise(function (resolve, reject) {
        reject(new Error("wrong"));
      })).should.be.rejectedWith("wrong");
    });

    it("should.fulfilled", function () {
      (new Promise(function (resolve, reject) {
        resolve({username: "jc", age: 18, gender: "male"})
      })).should.be.fulfilled().then(function (it) {
          it.should.have.property("username", "jc");
        })
    });
  });
});
異步方法的超時支持

Mocha的超時設(shè)定默認(rèn)是2s,如果執(zhí)行的測試超過2s的話,就會報timeout錯誤。

可以主動修改超時時間,有兩種方法。

命令行式

mocha -t 10000

API式
describe("async", function () {
  this.timeout(10000);
  it("async", function (done) {
    lib.async(function (result) {
      done();
    });
  });
});

這樣的話async執(zhí)行時間不超過10s,就不會報錯timeout錯誤了。

異常測試

異常應(yīng)該怎么測試,現(xiàn)在有getContent方法,他會讀取指定文件的內(nèi)容,但是不一定會成功,會拋出異常。

exports.getContent = function (filename, callback) {
  fs.readFile(filename, "utf-8", callback);
};

這時候就應(yīng)該模擬(mock)錯誤環(huán)境了

簡單Mock
describe("getContent", function () {
  var _readFile;
  before(function () {
    _readFile = fs.readFile;
    fs.readFile = function (filename, encoding, callback) {
      process.nextTick(function () {
        callback(new Error("mock readFile error"));
      });
    };    
  });
  // it();
  after(function () {
    // 用完之后記得還原。否則影響其他case
    fs.readFile = _readFile;
  })
});
Mock庫

Mock小模塊:muk ,略微優(yōu)美的寫法:

var fs = require("fs");
var muk = require("muk");

before(function () {
  muk(fs, "readFile", function(path, encoding, callback) {
    process.nextTick(function () {
      callback(new Error("mock readFile error"));
    });
  });
});
// it();
after(function () {
  muk.restore();
});
測試私有方法

針對一些內(nèi)部的方法,沒有通過exports暴露出來,怎么測試它?

function _adding(num1, num2) {
  return num1 + num2;
}
通過rewire導(dǎo)出方法

模塊:rewire

it("limit should return success", function () {
  var lib = rewire("../lib/index.js");
  var litmit = lib.__get__("limit");
  litmit(10);
});
測試Web應(yīng)用

在開發(fā)Web項目的時候,要測試某一個API,如:/user,到底怎么編寫測試用例呢?

使用:supertest

var express = require("express");
var request = require("supertest");
var app = express();

// 定義路由
app.get("/user", function(req, res){
  res.send(200, { name: "jerryc" });
});

describe("GET /user", function(){
  it("respond with json", function(done){
    request(app)
      .get("/user")
      .set("Accept", "application/json")
      .expect("Content-Type", /json/)
      .expect(200)
      .end(function (err, res) {
        if (err){
          done(err);
        }
        res.body.name.should.be.eql("jerryc");
        done();
      })
  });
});
覆蓋率

測試的時候,我們常常關(guān)心,是否所有代碼都測試到了。

這個指標(biāo)就叫做"代碼覆蓋率"(code coverage)。它有四個測量維度。

行覆蓋率(line coverage):是否每一行都執(zhí)行了?

函數(shù)覆蓋率(function coverage):是否每個函數(shù)都調(diào)用了?

分支覆蓋率(branch coverage):是否每個if代碼塊都執(zhí)行了?

語句覆蓋率(statement coverage):是否每個語句都執(zhí)行了?

Istanbul?是 JavaScript 程序的代碼覆蓋率工具。

安裝

$ npm install -g istanbul

覆蓋率測試

在編寫過以上的測試用例之后,執(zhí)行命令:

istanbul cover _mocha

就能得到覆蓋率:

JerryC% istanbul cover _mocha                                                                                                                                                                


  module
    limit
      ? limit should success
    async
      ? async
    getContent
      ? getContent
    add
      ? add

  should
    #Promise
      ? should.reject
      ? should fulfilled


  6 passing (32ms)


================== Coverage summary ======================
Statements   : 100% ( 10/10 )
Branches     : 100% ( 2/2 )
Functions    : 100% ( 5/5 )
Lines        : 100% ( 10/10 )
==========================================================

這條命令同時還生成了一個 coverage 子目錄,其中的 coverage.json 文件包含覆蓋率的原始數(shù)據(jù),coverage/lcov-report 是可以在瀏覽器打開的覆蓋率報告,其中有詳細(xì)信息,到底哪些代碼沒有覆蓋到。

上面命令中,istanbul cover 命令后面跟的是 _mocha 命令,前面的下劃線是不能省略的。

因為,mocha 和 _mocha 是兩個不同的命令,前者會新建一個進(jìn)程執(zhí)行測試,而后者是在當(dāng)前進(jìn)程(即 istanbul 所在的進(jìn)程)執(zhí)行測試,只有這樣, istanbul 才會捕捉到覆蓋率數(shù)據(jù)。其他測試框架也是如此,必須在同一個進(jìn)程執(zhí)行測試。

如果要向 mocha 傳入?yún)?shù),可以寫成下面的樣子。

$ istanbul cover _mocha -- tests/test.sqrt.js -R spec

上面命令中,兩根連詞線后面的部分,都會被當(dāng)作參數(shù)傳入 Mocha 。如果不加那兩根連詞線,它們就會被當(dāng)作 istanbul 的參數(shù)(參考鏈接1,2)。

使用Makefile串起項目
TESTS = test/*.test.js
REPORTER = spec
TIMEOUT = 10000
JSCOVERAGE = ./node_modules/jscover/bin/jscover

test:
    @NODE_ENV=test ./node_modules/mocha/bin/mocha -R $(REPORTER) -t $(TIMEOUT) $(TESTS)

test-cov: lib-cov
    @LIB_COV=1 $(MAKE) test REPORTER=dot
    @LIB_COV=1 $(MAKE) test REPORTER=html-cov > coverage.html

lib-cov:
    @rm -rf ./lib-cov
    @$(JSCOVERAGE) lib lib-cov

.PHONY: test test-cov lib-cov

make test
make test-cov

用項目自身的jscover和mocha,避免版本沖突和混亂

持續(xù)集成,Travis-cli

Travis-ci

綁定Github帳號

在Github倉庫的Admin打開Services hook

打開Travis

每次push將會hook觸發(fā)執(zhí)行npm test命令

注意:Travis會將未描述的項目當(dāng)作Ruby項目。所以需要在根目錄下加入.travis.yml文件。內(nèi)容如下:

language: node_js
node_js:
  - "0.12"

Travis-cli還會對項目頒發(fā)標(biāo)簽,

or?

如果項目通過所有測試,就會build-passing,

如果項目沒有通過所有測試,就會build-failing

一些觀點

實施單元測試的時候, 如果沒有一份經(jīng)過實踐證明的詳細(xì)規(guī)范, 很難掌握測試的 "度", 范圍太小施展不開, 太大又侵犯 "別人的" 地盤. 上帝的歸上帝, 凱撒的歸凱撒, 給單元測試念念緊箍咒不見得是件壞事, 反而更有利于發(fā)揮單元測試的威力, 為代碼重構(gòu)和提高代碼質(zhì)量提供動力.

這份文檔來自 Geotechnical, 是一份非常難得的經(jīng)驗準(zhǔn)則. 你完全可以以這份準(zhǔn)則作為模板, 結(jié)合所在團(tuán)隊的經(jīng)驗, 整理出一份內(nèi)部單元測試準(zhǔn)則.

單元測試準(zhǔn)則

彩蛋

最后,介紹一個庫:faker

他是一個能偽造用戶數(shù)據(jù)的庫,包括用戶常包含的屬性:個人信息、頭像、地址等等。

是一個開發(fā)初期,模擬用戶數(shù)據(jù)的絕佳好庫。

支持Node.js和瀏覽器端。

整理 Nodejs的單元測試工具

測試框架 mocha

斷言庫:should.js、expect.js、chai

覆蓋率:istanbul、jscover、blanket

Mock庫:muk

測試私有方法:rewire

Web測試:supertest

持續(xù)集成:Travis-cli

參考

https://github.com/JacksonTian/unittesting

]()[http://html5ify.com/unittesting/slides/index.html

http://www.ruanyifeng.com/blog/2015/06/istanbul.html

http://coolshell.cn/articles/8209.html

http://stackoverflow.com/questions/153234/how-deep-are-your-unit-tests

https://github.com/yangyubo/zh-unit-testing-guidelines

http://www.codedata.com.tw/java/unit-test-the-way-changes-my-programming

http://wiki.ubuntu.org.cn/%E8%B7%9F%E6%88%91%E4%B8%80%E8%B5%B7%E5%86%99Makefile:MakeFile%E4%BB%8B%E7%BB%8D

https://github.com/yangyubo/zh-unit-testing-guidelines

https://github.com/visionmedia/superagent/blob/master/Makefile

如果本文對您有用
請不要吝嗇你們的Follow與Start
這會大大支持我們繼續(xù)創(chuàng)作

「Github」
MZMonster :@MZMonster
JC_Huang :@JerryC8080

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/78938.html

相關(guān)文章

  • 深入貫徹閉包思想,全面理解JS閉包形成過程

    摘要:下面我們就羅列閉包的幾個常見問題,從回答問題的角度來理解和定義你們心中的閉包。函數(shù)可以通過作用域鏈相互關(guān)聯(lián)起來,函數(shù)內(nèi)部的變量可以保存在其他函數(shù)作用域內(nèi),這種特性在計算機(jī)科學(xué)文獻(xiàn)中稱為閉包。 寫這篇文章之前,我對閉包的概念及原理模糊不清,一直以來都是以通俗的外層函數(shù)包裹內(nèi)層....來欺騙自己。并沒有說這種說法的對與錯,我只是不想擁有從眾心理或者也可以說如果我們說出更好更低層的東西,逼格...

    snowell 評論0 收藏0
  • 測試你的前端代碼 - part2(單元測試

    摘要:單元測試上一節(jié)有討論過,單元測試就是以代碼單元為單位進(jìn)行測試,代碼單元可以是一個函數(shù),一個模塊,或者一個類。單元測試是最容易理解也最容易實現(xiàn)的測試方式。在寫單元測試的時候,盡量將你的單元測試獨(dú)立出來,不要幾個單元互相引用。 showImg(https://segmentfault.com/img/remote/1460000008823416?w=997&h=350); 本文作者:G...

    daydream 評論0 收藏0
  • 測試你的前端代碼 - part2(單元測試

    摘要:單元測試上一節(jié)有討論過,單元測試就是以代碼單元為單位進(jìn)行測試,代碼單元可以是一個函數(shù),一個模塊,或者一個類。單元測試是最容易理解也最容易實現(xiàn)的測試方式。在寫單元測試的時候,盡量將你的單元測試獨(dú)立出來,不要幾個單元互相引用。 showImg(https://segmentfault.com/img/remote/1460000008823416?w=997&h=350); 本文作者:G...

    shadajin 評論0 收藏0
  • 消息系統(tǒng)設(shè)計與實現(xiàn)「上篇」

    摘要:原文鏈接消息系統(tǒng)設(shè)計與實現(xiàn)上篇由于文章篇幅較長,而作者精力有限,不希望這么早就精盡人亡,故分成上下篇來寫消息系統(tǒng)的設(shè)計與實現(xiàn)。更新于關(guān)聯(lián)文章消息系統(tǒng)設(shè)計與實現(xiàn)下篇如果本文對您有用請不要吝嗇你們的與這會大大支持我們繼續(xù)創(chuàng)作 原文鏈接:Bluesun | 消息系統(tǒng)設(shè)計與實現(xiàn)「上篇」 由于文章篇幅較長,而作者精力有限,不希望這么早就精盡人亡,故分成上下篇來寫消息系統(tǒng)的設(shè)計與實現(xiàn)。上篇主要講...

    v1 評論0 收藏0
  • 關(guān)于前端開發(fā)談?wù)?em>單元測試

    摘要:很快我發(fā)現(xiàn)有一個誤區(qū),許多人認(rèn)為單元測試必須是一個集中運(yùn)行所有單元的測試,并一目了然。許多人認(rèn)為單元測試,甚至整個測試都是在編碼結(jié)束后的一道工序,而修復(fù)也不過是在做垃圾掩埋一類的工作。 單元測試Unit Test 很早就知道單元測試這樣一個概念,但直到幾個月前,我真正開始接觸和使用它。究竟什么是單元測試?我想也許很多使用了很久的人也不一定能描述的十分清楚,所以寫了這篇文章來嘗試描述它...

    0x584a 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<