Nodejs测试:从0到90(实践篇)

继上一篇理论,本篇重点说明实践,包括nodejs中异步、Promises、私有方法、mock及web等的测试方法。

方法

以下示例均基于mocha.

异步

在异步操作完成时,调用回调(通常是 done) 即可。

describe('User', function() {
  describe('#save()', function() {
    it('should save without error', function(done) {
      var user = new User('Luna');
      user.save(done);
    });
  });
});

Mocha的超时设定默认是2s,如果执行的测试超过2s的话,就会报timeout错误。可以修改超时时间,有两种方法:

  • 命令行式
mocha -t 10000
  • API式
describe('async', function () {
  this.timeout(10000);

  it('async', function (done) {
    lib.async(function (result) {
      done();
    });
  });
});

Promises

如果异步操作的返回结果是 Promise,可以使用 Chai as Promised

'use strict';

require('should');
require('chai').use(require('chai-as-promised'));

describe('test/app/simple/promise.test.js', () => {

  it('#Promise', ()=> {
    (new Promise(function(resolve) {
      resolve(10);
    })).should.be.a.Promise();

    (10).should.not.be.a.Promise();
  });

  it('#fulfilled', () => {
    return new Promise(resolve => resolve(10))
        .should.be.fulfilled();
  });

  it('#fulfilledWith', () => {
    return new Promise((resolve) => resolve(10))
        .should.be.fulfilledWith(10);
  });

  it('#rejected', () => {
    return new Promise((resolve, reject) => reject(new Error('boom')))
        .should.be.rejected();
  });
});

私有方法

一般测试只测试接口或公共方法,并不直接测试私有方法。但是如果当私有方法特别多且复杂时,测试私有方法比测试接口或公共方法更直接、有效。

严格上讲,javascript并没有私有方法的概念,这里所讨论的私有方法指未被导出(exports)的方法。

一个简单的盒子,在一个 cal.js 里有一个 add 方法,如下所示:

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

此方法为私有方法,无法直接通过 cal 测试,但可以通过 rewire 获取。

rewire adds a special setter and getter to modules so you can modify their behaviour for better unit testing.

获取上面的私有方法,并测试:

it('1 + 1 should equals 2', function () {
  let cal = rewire('./cal.js');
  let add = cal.__get__('add');
  add(1, 1).should.be.eql(2);
});

除了获取私有方法,rewire 还可以设置私有变量或方法, 以便测试。

比如有这样一个模块,

// lib/myModules.js
// With rewire you can change all these variables
var fs = require("fs"),
    path = "/somewhere/on/the/disk";

function readSomethingFromFileSystem(cb) {
    console.log("Reading from file system ...");
    fs.readFile(path, "utf8", cb);
}

exports.readSomethingFromFileSystem = readSomethingFromFileSystem;

设置并获取私有变量。

myModule.__set__("path", "/dev/null");
myModule.__get__("path"); // = '/dev/null'

还可以用作mock。

var fsMock = {
    readFile: function (path, encoding, cb) {
        expect(path).to.equal("/somewhere/on/the/disk");
        cb(null, "Success!");
    }
};
myModule.__set__("fs", fsMock);

更多用法见 文档

mock

mock就是在测试过程中,对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法。nodejs中常用的mock工具有 muksinon 等,以sinon为例简要说明一下其用法。

需要测试的方法:

function once(fn) {
    var returnValue, called = false;
    return function () {
        if (!called) {
            called = true;
            returnValue = fn.apply(this, arguments);
        }
        return returnValue;
    };
}
  • Spy
it("calls the original function", function () {
    var spy = sinon.spy();
    var proxy = once(spy);
    proxy();

    assert(spy.called);
});
  • Stubs
it("returns the return value from the original function", function () {
    var stub = sinon.stub().returns(42);
    var proxy = once(stub);

    assert.equals(proxy(), 42);
});
  • Mocks
it("returns the return value from the original function", function () {
    var myAPI = { method: function () {} };
    var mock = sinon.mock(myAPI);
    mock.expects("method").once().returns(42);

    var proxy = once(myAPI.method);

    assert.equals(proxy(), 42);
    mock.verify();
});

更多参考 文档

web

主要依赖 SuperTest ,已在工具部分说明,不再赘述。

更多

持续集成

持续集成(CI, Continuous integration)是一种软件开发实践,即团队开发成员经常集成它们的工作。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。

github 上大部分 ci 都是基于 Travis CI。详细接入方案见官方文档,不在此讨论。

代码风格

当写js代码的时候,一个校验工具可以确保一个项目遵循代码规范、帮助我们避免愚蠢的错误。目前比较流行js校验工具有 JSLintJSHintJSCSESLint, 它们之前的差异比较可以参考 A Comparison of JavaScript Linting Tools,推荐使用 ESLint

代码风格检查同样也可以集成到 ci,只需要在 ci 命令前追加检查命令即可。以 eslint 为例:

  "scripts": {
    // ..
    "lint": "eslint .",
    "cov": "istanbul cover .",
    "ci": "tnpm run lint && TEST_TIMEOUT=60000 istanbul cover ."
  },

此时构建会先做代码风格检查,再做单元测试、覆盖率统计,如代码风格检查失败,会直接导致构建中断。

写在后面的

原本计划写一个nodejs的测试参考,帮助还不太了解nodejs测试的同学快速入门,在写的过程中才发现,需要的东西太多,而自己又知道的太少。虽然在一个应用的测试中覆盖率达到了90%,但并不代码在测试方面可以拿到90分。

正如前面写到的,”剩下的10,还有很长的路“,甚至比从0到90更长,唯有不断的学习才能进一步提升,希望自己还能再写个下篇《Nodejs测试:从90到100》。

References

上一篇:Nodejs测试:从0到90(理论篇)

时间: 2024-11-10 01:04:28

Nodejs测试:从0到90(实践篇)的相关文章

NodeJS Testing: From 0 to 90

Recently, I was responsible for a NodeJS-based application. In this process, I had to learn about many new things, one of which was testing. At the start, I was not able to write much code, much less test it. At that time, my testing coverage rate wa

苹果拟邀请部分用户测试iOS5.0.1系统

[赛迪网讯]11月10日消息,据国外媒体报道,苹果计划邀请部分用户测试iOS5.0.1系统,据悉在这项活动中苹果用户被邀请测试尚未正式发布的软件,AppleSeed活动旨在为苹果公司的软件工程师提供真实世界中质量与使用性能的反馈. 据报道,那些抱怨iOS 5耗电快的用户将收到一份通知:苹果邀请您参加一个软件播种项目,根据AppleCare 客服提供的推荐,公司选择了您参加这次活动,让您帮苹果测试即将发布的iSO 5的软件升级. 据悉,在用户们了解了接受这个项目的意义之后,苹果提供给用户们一些软件

Nodejs开发框架Express3.0开发手记–从零开始

转载请注明出处:http://blog.fens.me/nodejs-express3/ 程序代码已经上传到github有需要的同学,自行下载.https://github.com/bsspirit/nodejs-demo 从零开始nodejs系列文章 从零开始nodejs系列文章, 将介绍如何利Javascript做为服务端脚本,通过Nodejs框架web开发.Nodejs框架是基于V8的引擎,是目前速度最快的 Javascript引擎.chrome浏览器就基于V8,同时打开20-30个网页都

link中产生随机数0~999产生10个,999~9999产生90个,请问怎么实现?

问题描述 link中产生随机数0~999产生10个,999~9999产生90个,请问怎么实现? link中产生随机数0~999产生10个,999~9999产生90个,请问怎么实现? 解决方案 int[] r1 = Enumerable.Range(0, 1000).OrderBy(_ => Guid.NewGuid()).Take(10).ToArray(); int[] r2 = Enumerable.Range(1000, 10000).OrderBy(_ => Guid.NewGuid(

Nodejs学习笔记之测试驱动_node.js

分享第二章,关于测试驱动.这里的测试主要针对Web后端的测试 -- 你为什么要写测试用例(即测试用例的完善是否是浪费时间),如何完善你的测试用例,代码设计如何简化测试用例的书写,以及一些后期的构想. 1. 你为什么要写测试用例 这个习惯通常会被认为是一种耽误开发进度的行为,你需要花费几乎和开发代码相同的时间来逐步完善你的测试用例.但是在开发过程中,在开发完成一段代码后如果负责任而不是说完全把问题交给测试人员去发现的话,这个时候通常都会去做一些手动的测试.例如: 在代码中执行某些方法,查看输出的值

Scache 0.90.4发布 PHP会话数据管理

Scache是一个不同方法的PHP会话数据管理.它提供了一个通用的键-值数据高速缓存,用于瞬态会话数据的存储.Scache还提供一个共享的密钥空间,共享计数器和简单的缓存功能. Scache区别其他的实现是一个树状结构的密钥空间,人们可以轻松操作只存储会话数据所需的零部件和失效过期的整个子树中存储的数据组.Scache存储所有的会话数据插入,直到数据被破坏,因此减少了冗余存储的相同数据在其他地方的需求.Scache包含一个守护进程和PHP扩展. Scache 0.90.4此版本缓存功能已被重写以

【工具】TPCC-MySQL 测试结果详解

TPCC-MySQL输出结果详解 前面的一篇文章介绍了测试工具tpcc-mysql的安装与使用,奈何网上基本没有对于tpcc-mysql 结果的分析,本文介绍如何对测试结果进行分析: 一 测试例子 [root@rac1 tpcc-mysql]# tpcc_start  -hlocalhost  -d tpcc  -u root  -p '' -w 5  -c  5  -r 120   -l  300 -f tpcc_mysql_20130403.xls *********************

《点睛:ActionScript3.0游戏互动编程》——2.3 使用斜角滤镜模拟Photoshop的斜面样式

2.3 使用斜角滤镜模拟Photoshop的斜面样式 滤镜列表中,[斜角]似乎最接近斜面的含义,我们不妨点出来看看,如图2-45所示. 嗯,是这个效果了.现在把Photoshop的斜面样式重新打开,我们按之前对Photoshop的设置来修改Flash里的参数."大小"参数我们没有使用默认值,而是从原来的5改成了3.在Flash里我们也应用同样的设置,如图2-46所示. 出来的效果并不好看.细心的读者应该不难发现,斜角滤镜加上以后,整个字好像带上了重影一样,第一眼看上去还以为是自己的眼睛

fFFmpeg 命令、案例、测试集中营

gitbook: https://www.gitbook.com/book/xdsnet/other-doc-cn-ffmpeg/details ffmpeg [全局选项] {[输入文件选项] -i 输入文件} ... {[输出文件选项] 输出文件} ... ffmpeg [global_options] {[input_file_options] -i input_file} ... {[output_file_options] output_file} ... 一.FFmpeg拉去RTSP摄