精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

玩轉Node.js單元測試

開發 后端
代碼部署之前,進行一定的單元測試是十分必要的,這樣能夠有效并且持續保證代碼質量。而實踐表明,高質量的單元測試還可以幫助我們完善自己的代碼。這篇博客將通過一些簡單的測試案例,介紹幾款Node.js測試模塊: Mocha和Should,SuperTest。

代碼部署之前,進行一定的單元測試是十分必要的,這樣能夠有效并且持續保證代碼質量。而實踐表明,高質量的單元測試還可以幫助我們完善自己的代碼。這篇博客將通過一些簡單的測試案例,介紹幾款Node.js測試模塊: Mocha和Should,SuperTest。本文側重于解釋原理,各個模塊的詳細使用案例以后單獨再聊。

為啥需要單元測試?

所謂單元測試,就是對某個函數或者API進行正確性驗證。來看個簡單的例子add1.js:

function add(a, b) {
    return a + b;
}

沒錯,我寫了一個加法函數。這有啥好測的呢?不妨用node執行一下:

> add = function(a, b){return a + b}
[Function: add] > add(4) NaN

當add函數僅給定一個參數4的時候,a為4,b為undefined,兩者相加為NaN。

  • 你考慮過只有一個參數的場景嗎?
  • 給定一個參數時,NaN是你想要的結果嗎?
  • 如果參數不是整數怎么辦?

這時,就需要單元測試來驗證各種可能的場景了。

如果我把add函數定義為兩個整數相加,而其他輸入則返回undefined,那么正確的代碼add2.js應該是這樣的:

function add(a, b) {
    if (typeof a === "number" && typeof b === "number")
    {
        return a + b;
    }
    else
    {
        return undefined;
    }
}

發現一個有趣的現象,我們寫代碼的時候很容易陷入思維漏洞,而寫測試的時候往往會考慮各種情況,這就是所謂的TDD(Test-Driven-Development: 測試驅動開發)的神奇之處。因此,進行一定的單元測試是十分必要的:

  • 驗證代碼的正確性
  • 避免修改代碼時出錯
  • 避免其他團隊成員修改代碼時出錯
  • 便于自動化測試與部署

測試框架 - Mocha

下面的測試代碼test2.js用于測試add2.js。這里使用了測試框架Mocha以及Node.js自帶的斷言庫Assert。

var add = require("../add2.js");
var assert  = require("assert");
// 當2個參數均為整數時
it("should return 3", function() {
    var sum = add(1, 2);
    assert.equal(sum, 3);
});
// 當第2個參數為String時
it("should return undefined", function() {
    var sum = add(1, "2");
    assert.equal(sum, undefined);
});
// 當只有1個參數時
it("should return undefined", function() {
    var sum = add(1);
    assert.equal(sum, undefined);
});

測試代碼中使用了測試框架Mocha提供的it函數,3個it函數分別測試了3種不同的案例(test case)。it函數的第1個參數為字符串,用于描述測試,一般會寫期望得到的結果,例如”should return 3”; 而第2個參數為函數,用于編寫測試代碼,一般是先調用被測試的函數或者API,獲取結果之后,使用斷言庫判斷執行結果是否正確。

測試代碼中使用了Node.js自帶的斷言庫Assert的assert.equal函數,用于判定add函數返回的結果是否正確。assert.equal成功時不會發生什么,而失敗時會拋出一個AssertionError。不妨使用node測試一下:

> assert  = require("assert");
> assert.equal(1, 1);
undefined
> assert.equal(1, 2);
AssertionError: 1 == 2
    at repl:1:8
    at sigintHandlersWrap (vm.js:22:35)
    at sigintHandlersWrap (vm.js:96:12)
    at ContextifyScript.Script.runInThisContext (vm.js:21:12)
    at REPLServer.defaultEval (repl.js:313:29)
    at bound (domain.js:280:14)
    at REPLServer.runBound [as eval] (domain.js:293:12)
    at REPLServer.<anonymous> (repl.js:513:10)
    at emitOne (events.js:101:20)
    at REPLServer.emit (events.js:188:7)

原理:

我們按照Mocha的it函數編寫一個個測試案例,然后Mocha負責執行這些案例;當assert.equal斷言成功時,則測試案例通過;當assert.equal斷言失敗時,拋出AssertionError,Mocha能夠捕獲到這些異常,然后對應的測試案例失敗。

使用mocha執行test2.js:

mocha test/test2.js

下面為輸出,表示測試案例全部通過

✓ should return 3
✓ should return undefined
✓ should return undefined
3 passing

而當我們使用test1.js測試add1.js時,則后面2個測試案例失敗:

✓ should return 3
  1) should return undefined
  2) should return undefined
  1 passing (14ms)
  2 failing
  1)  should return undefined:
     AssertionError: '12' == undefined
      at Context.<anonymous> (test/test1.js:18:12)
  2)  should return undefined:
     AssertionError: NaN == undefined
      at Context.<anonymous> (test/test1.js:25:12)

斷言庫 - Should

Node.js自帶的斷言庫Assert提供的函數有限,在實際工作中,Should等第三方斷言庫則更加強大和實用。

我寫了一個merge函數merge.js,實現了類似于_.extend()Object.assign()的功能,用于合并兩個Object的屬性。

function merge(a, b) {
    if (typeof a === "object" && typeof b === "object")
    {
        for (var property in b)
        {
            a[property] = b[property];
        }
        return a;
    }
    else
    {
        return undefined;
    }
}

然后我使用Should寫了對應的測試代碼test3.js:

require("should");
var merge = require("../merge.js");
// 當2個參數均為對象時
it("should success", function() {
    var a = {
        name: "Fundebug",
        type: "SaaS"
    };
    var b = {
        service: "Real time bug monitoring",
        product:
        {
            frontend: "JavaScript",
            backend: "Node.js",
            mobile: "微信小程序"
        }
    };
    var c = merge(a, b);
    c.should.have.property("name", "Fundebug");
    c.should.have.propertyByPath("product", "frontend").equal("JavaScript");
});
// 當只有1個參數時
it("should return undefined", function() {
    var a = {
        name: "Fundebug",
        type: "SaaS"
    };
    var c = merge(a);
    (typeof c).should.equal("undefined");
});

測試代碼稍微有點長,但是使用Should的只有三處:

c.should.have.property("name", "Fundebug");
c.should.have.propertyByPath("product", "frontend").equal("JavaScript");
(typeof c).should.equal("undefined");

可知Should能夠:

  • 驗證對象是否存在某屬性,并驗證其取值
  • 驗證對象是否存在某個嵌套屬性,并使用鏈式方式驗證其取值

那么Should為什么不能直接驗證c的取值為undefined呢?比如這樣寫:

c.should.equal(undefined); // 這樣寫是錯誤的

原理:

Should會為每個對象添加should屬性,然后通過該屬性提供各種斷言函數,我們可以使用這些函數驗證對象的取值。對于undefined,Should無法為其添加屬性,因此失敗。

通過node驗證發現,導入Should之后,空對象a增加了一個should屬性。

> a = {}
> typeof a.should
'undefined'
> require("should")
> typeof a.should
'object'

測試HTTP接口 - SuperTest

Node.js是用于后端開發的語言,而后端開發其實很大程度上等價于編寫HTTP接口,為前端提供服務。那么,Node.js單元測試則少不了對HTTP接口進行測試。

我用Node.js自帶的HTTP模塊寫了一個簡單的HTTP接口server.js

var http = require("http");
var server = http.createServer((req, res) =>
{
    res.writeHead(200,
    {
        "Content-Type": "text/plain"
    });
    res.end("Hello Fundebug");
});
server.listen(8000);

按照Mocha的原理,測試HTTP接口并不難: 訪問接口; 獲取返回數據; 驗證返回結果。使用Node.js原生的http與assert模塊就可以了test4.js:

require("../server.js");
var http = require("http");
var assert = require("assert");
it("should return hello fundebug", function(done) {
    http.get("http://localhost:8000", function(res)     {
        res.setEncoding("utf8");
        res.on("data", function(text)         {
            assert.equal(res.statusCode, 200);
            assert.equal(text, "Hello Fundebug");
            done();
        });
    });
});

值得稍微注意的一點是,http.get訪問HTTP接口是一個異步操作。Mocha在測試異步代碼是需要為it函數添加回調函數done,在斷言結束的地方調用done,這樣Mocha才能知道什么時候結束這個測試。

既然Node.js自帶的模塊就能夠測試HTTP接口了,為什么還需要SuperTest呢?不妨先看一下測試代碼test5.js:

var request = require("supertest");
var server = require("../server.js");
var assert = require("assert");
it("should return hello fundebug", function(done) {
    request(server)
        .get("/")
        .expect(200)
        .expect(function(res)         {
            assert.equal(res.text, "Hello Fundebug");
        })
        .end(done);
});

對比兩個測試代碼,會發現后者簡潔很多。

原理

SuperTest封裝了發送HTTP請求的接口,并且提供了簡單的expect斷言來判定接口返回結果。對于POST接口,使用SuperTest的優勢將更加明顯,因為使用Node.js的http模塊發送POST請求是很麻煩的。

要做多少單元測試?

本文所寫的單元測試案例,都很簡單。然而,在實際工作中,單元測試是一個很頭痛的事情。修改了代碼有時意味著必須修改單元測試,寫了新的函數或者API就得寫新的單元測試。如果較真起來,單元測試可以沒完沒了地寫,但這是沒有意義的。而根據二八原理,20%的測試可以解決80%的問題。剩下的20%問題,事實上我們是力不從心的。換句話說,想通過測試消除所有BUG,是不現實的。

因此,對生產代碼進行實時錯誤監測是非常有必要的,這也是我們Fundebug努力在做的事情。

參考鏈接

責任編輯:張燕妮 來源: KiwenLau
相關推薦

2012-10-24 14:56:30

IBMdw

2017-01-14 23:42:49

單元測試框架軟件測試

2015-03-10 10:59:18

Node.js開發指南基礎介紹

2013-11-01 09:34:56

Node.js技術

2017-01-16 12:12:29

單元測試JUnit

2017-01-14 23:26:17

單元測試JUnit測試

2020-08-18 08:10:02

單元測試Java

2017-03-23 16:02:10

Mock技術單元測試

2021-05-05 11:38:40

TestNGPowerMock單元測試

2020-05-07 17:30:49

開發iOS技術

2011-07-04 18:16:42

單元測試

2023-07-26 08:58:45

Golang單元測試

2011-11-10 08:55:00

Node.js

2011-09-02 14:47:48

Node

2011-11-01 10:30:36

Node.js

2011-09-08 13:46:14

node.js

2011-09-09 14:23:13

Node.js

2011-05-16 16:52:09

單元測試徹底測試

2024-04-26 09:44:39

2021-12-25 22:29:57

Node.js 微任務處理事件循環
點贊
收藏

51CTO技術棧公眾號

欧美午夜精品久久久久久浪潮| 成人免费看视频| 自拍偷拍亚洲欧美| 日韩欧美中文在线视频| 免费在线小视频| 欧美激情一区在线观看| 91福利视频导航| 青草视频在线观看免费| 99热国内精品| 亚洲国产天堂网精品网站| 在线观看免费黄网站| 欧洲黄色一区| 国产日产欧美一区| 岛国一区二区三区高清视频| 99精品视频99| 91精品国产调教在线观看| 亚洲国产精品福利| 亚洲精品20p| 极品在线视频| 亚洲精品va在线观看| 免费一区二区三区| 国产高清不卡视频| 欧美aaa在线| 久久久欧美一区二区| 激情高潮到大叫狂喷水| 台湾亚洲精品一区二区tv| 3d成人动漫网站| 无码人妻h动漫| 麻豆蜜桃在线| 1024亚洲合集| 台湾成人av| 婷婷在线免费视频| 国产盗摄视频一区二区三区| 国产精品麻豆va在线播放| 中文字幕亚洲高清| 亚洲高清不卡| 欧美疯狂性受xxxxx另类| 国产视频不卡在线| 综合色就爱涩涩涩综合婷婷| 精品捆绑美女sm三区| 亚洲自拍第三页| 日韩经典一区| 日韩欧美福利视频| 国产妇女馒头高清泬20p多| 国产三级在线播放| 亚洲欧洲99久久| 亚洲人成网站在线播放2019| 精品美女视频在线观看免费软件| 9l国产精品久久久久麻豆| 亚洲xxx视频| 99热这里只有精品1| 精品一区二区免费在线观看| 国产精品视频一区国模私拍| 日本视频免费观看| 老牛嫩草一区二区三区日本 | 国产日韩精品在线播放| 亚洲精品毛片一区二区三区| 视频一区二区不卡| 国产精品成人一区| 日韩xxx视频| 奇米精品一区二区三区在线观看 | 一区二区三区三区在线| 999在线视频| 亚洲国产成人在线| 一区二区精品免费视频| 1pondo在线播放免费| 国产精品美女一区二区| 亚洲一卡二卡三卡| 黄色的网站在线观看| 亚洲精品视频免费观看| 成人短视频在线观看免费| 丁香花在线影院| 午夜精品影院在线观看| 男人天堂网视频| japanese23hdxxxx日韩| 欧美日韩视频专区在线播放| 手机在线国产视频| jizz性欧美23| 精品呦交小u女在线| 女人又爽又黄免费女仆| 不卡中文一二三区| 欧美成人国产va精品日本一级| 麻豆一区产品精品蜜桃的特点| 激情久久一区| 欧美在线日韩在线| 国产女人18毛片18精品| 国产成人亚洲综合a∨猫咪| 国语精品免费视频| a中文在线播放| 亚洲最新在线观看| 毛片av免费在线观看| 国内自拍亚洲| 亚洲成人精品久久| 蜜桃久久精品成人无码av| 欧美系列电影免费观看| 欧美理论片在线观看| 日韩av大片在线观看| 麻豆精品在线视频| 国产精品v欧美精品v日韩| 欧美xxx.com| 亚洲人成影院在线观看| 国产乱子伦农村叉叉叉| a一区二区三区亚洲| 亚洲国产欧美精品| 亚洲综合久久av一区二区三区| 亚洲性图久久| 国产精品永久免费视频| 成人午夜免费在线观看| 国产精品久久夜| 无码人妻少妇伦在线电影| 精品成人免费一区二区在线播放| 欧美v亚洲v综合ⅴ国产v| 谁有免费的黄色网址| 在线成人h网| 国产精品专区一| 日韩中文字幕免费观看| 中文字幕在线不卡一区| 国产精品97在线| 另类视频一区二区三区| 一本色道久久88亚洲综合88| 久久国产露脸精品国产| 美国一区二区三区在线播放| 国产欧美亚洲日本| 麻豆av在线免费看| 在线一区二区视频| 日本国产在线视频| 亚洲欧美综合久久久| 国产精品高潮粉嫩av| 午夜av免费观看| 亚洲一二三四在线观看| 亚欧精品在线视频| 欧美激情电影| 国产精品久久久精品| 天堂网www中文在线| 亚洲永久免费视频| 香蕉视频xxxx| 91精品国产自产在线观看永久∴| 国产裸体写真av一区二区 | 亚洲欧美中文另类| 日本三级欧美三级| 国产成人亚洲综合a∨猫咪| 天堂av免费看| 日本免费一区二区三区等视频| 亚洲美女免费精品视频在线观看| 日本在线观看中文字幕| 成人免费观看男女羞羞视频| avav在线播放| 超碰精品在线观看| 欧美成在线观看| 国产成人精品av在线观| 亚洲视频香蕉人妖| 国产高清av片| 欧美理论在线| 超碰97人人人人人蜜桃| 黄色在线观看视频网站| 亚洲国内精品在线| 特黄视频免费看| 久久久天堂av| 超碰影院在线观看| 欧美艳星介绍134位艳星| 国产精品久久久久久久久久三级| 2019中文字幕在线视频| 欧美日韩高清影院| 国产一区二区视频在线观看免费| 国产毛片精品视频| 日本免费a视频| 久久久久观看| 欧美在线视频观看免费网站| 国产露出视频在线观看| 欧美日韩成人综合在线一区二区| 久艹在线观看视频| 国产69精品久久久久777| 欧美午夜性视频| 亚洲性视频大全| 国产精品久久久久高潮| 老司机精品视频在线观看6| 日韩欧美三级在线| 毛片毛片女人毛片毛片| 中文字幕不卡一区| 日韩精品在线播放视频| 一本不卡影院| 亚洲午夜精品一区二区| 中文字幕一区图| 国产成人aa精品一区在线播放| 麻豆传媒视频在线观看| 精品嫩草影院久久| 中文字幕av影院| 中文字幕一区二区三区在线播放| 国产男女无遮挡猛进猛出| 一本色道88久久加勒比精品| 日韩精品一区二区三区外面| 国产亚洲高清在线观看| 69精品小视频| 老司机av在线免费看| 日韩电影免费在线观看中文字幕| 懂色av蜜臀av粉嫩av喷吹| 亚洲激情网站免费观看| 深爱五月激情网| 国产精品一区二区91| 97av视频在线观看| 一区二区蜜桃| 日本不卡高清视频一区| 久久久久久久久成人| 日韩免费观看视频| 色爱综合区网| 尤物九九久久国产精品的特点| 亚洲va久久久噜噜噜无码久久| 色综合网站在线| 青青草手机在线观看| 国产欧美日韩亚州综合| 男男一级淫片免费播放| 国内精品视频一区二区三区八戒 | 超免费在线视频| 日韩最新av在线| 亚洲欧美色视频| 欧美成人女星排名| 一区二区三区在线免费观看视频| 亚洲丰满少妇videoshd| 国产精品精品软件男同| 国产午夜精品久久久久久免费视 | 最近中文字幕日韩精品| 爽爽视频在线观看| 欧美变态口味重另类| 97超视频在线观看| 在线免费视频一区二区| 免费观看一区二区三区毛片| 夜夜嗨av一区二区三区四季av| 国产精品一区二区亚洲| 国产欧美中文在线| 草草影院第一页| 99久久久久免费精品国产| 香蕉视频xxxx| 国产呦精品一区二区三区网站| 九九九在线观看视频| 老鸭窝亚洲一区二区三区| 2018中文字幕第一页| 午夜久久久久| 亚洲一区二区高清视频| 日本电影一区二区| 日韩国产精品一区二区三区| 亚洲小说图片| 欧美一级日本a级v片| 亚洲美女15p| 蜜桃视频在线观看成人| 欧美自拍一区| 久久久久久高清| 午夜先锋成人动漫在线| 久久国产精品 国产精品| 人人精品视频| 久久久久久国产精品免费免费| 亚洲69av| 奇米影视首页 狠狠色丁香婷婷久久综合| 日韩欧美国产大片| 欧美日韩一区在线观看视频| 亚洲免费毛片| 日韩一区国产在线观看| 日韩中文欧美| 警花观音坐莲激情销魂小说| 一本一本久久a久久综合精品| 日韩中文在线字幕| 激情成人亚洲| 91精品91久久久中77777老牛| 国产精品腿扒开做爽爽爽挤奶网站| 成人观看免费完整观看| 日韩**一区毛片| 色国产在线视频| 国产酒店精品激情| 69亚洲乱人伦| 久久精品人人做人人爽人人| av资源在线免费观看| 亚洲精品国产成人久久av盗摄| 久久久美女视频| 天天色天天操综合| 日韩综合在线观看| 91精品福利在线一区二区三区 | 国内久久婷婷综合| 丰满少妇xbxb毛片日本| 99精品在线观看视频| 国产又黄又粗视频| 亚洲免费在线播放| 日韩欧美一级视频| 欧美色图在线观看| 性色av蜜臀av| 亚洲欧美激情四射在线日| 日本在线观看| 久久久久久久久久久成人| 国产精品伦理| 91久久精品美女| 欧美激情影院| 日本黄色播放器| 99国产精品99久久久久久粉嫩| 亚洲人成无码www久久久| 国产在线观看一区二区| 欲求不满的岳中文字幕| 中文字幕国产一区| 精品久久免费视频| 欧美日韩在线播| 日本激情一区二区| 中文字幕日韩高清| 精精国产xxxx视频在线播放| 成人av电影天堂| 天堂网av成人| 激情视频小说图片| 日韩精品久久理论片| 美女伦理水蜜桃4| 国产精品久久久久久久久晋中| 日韩毛片在线播放| 91精品国产麻豆国产自产在线| 九色国产在线观看| 久久久久久久久久久av| 亚洲伊人精品酒店| 欧美最大成人综合网| 精品不卡视频| 中文国产在线观看| 中文一区二区在线观看| 草久视频在线观看| 精品国产一区二区三区久久影院| 在线观看精品一区二区三区| 日本久久亚洲电影| 琪琪久久久久日韩精品| 精品人妻人人做人人爽| 国精产品一区一区三区mba视频| 性欧美13一14内谢| 欧美日韩亚洲精品一区二区三区 | 亚洲美女自拍视频| 极品在线视频| 国产精品伊人日日| 午夜欧美精品| 一级 黄 色 片一| 中文字幕一区二区三区四区不卡 | 久久爱av电影| 欧美午夜一区| 午夜影院免费版| 18成人在线观看| 一级黄色小视频| 最近更新的2019中文字幕 | 欧美亚洲一区三区| 欧美女同网站| 4438全国亚洲精品在线观看视频| jizz性欧美23| 日本一区午夜艳熟免费| 国产成人午夜精品影院观看视频 | 丰满人妻一区二区三区大胸| 亚洲欧洲无码一区二区三区| 中文字幕网址在线| 国产亚洲精品美女久久久| 精品91久久| 人偷久久久久久久偷女厕| 久久亚洲欧洲| 先锋影音av在线| 欧美最猛性xxxxx直播| 成人欧美一区| 国产欧美 在线欧美| 91欧美在线| 日本特黄在线观看| 一区二区三区中文免费| 好吊色视频一区二区| 97视频免费在线观看| 婷婷精品在线| 尤蜜粉嫩av国产一区二区三区| 亚洲国产精品ⅴa在线观看| 91久久久久久久久久久久| 久久av红桃一区二区小说| 亚洲成人黄色| 国产免费黄色一级片| 91视频国产观看| 成人黄色激情视频| 俺去啦;欧美日韩| 青草伊人久久| 亚洲熟妇无码另类久久久| 久久精品男人天堂av| 一级做a爱片久久毛片| 免费不卡在线观看av| 噜噜噜狠狠夜夜躁精品仙踪林| 日韩av播放器| 亚洲人成小说网站色在线| 天堂av2024| 国产精品久久久久影院日本| 午夜精品毛片| 欧美熟妇精品一区二区蜜桃视频| 疯狂做受xxxx欧美肥白少妇 | 亚洲精品一区二区三区中文字幕 | 福利在线导航136| 另类视频在线观看+1080p| 蜜桃av一区二区三区| 久久久.www| 亚洲色图第三页| 国产亚洲观看| 50路60路老熟妇啪啪| 亚洲免费av观看| 九色在线视频蝌蚪| 99热在线国产| 日韩国产精品久久久久久亚洲| 亚洲综合网在线| 亚洲欧洲第一视频| 亚洲国产精品免费视频| 欧美伦理片在线看| 亚洲一区二区美女| 1769视频在线播放免费观看| 国产三级精品在线不卡|