JavaScript BDD Test:mocha + should.js的基本使用介绍

@kvkens 2016-07-31 13:29:22发表于 iuap-design/blog

前言

众所周知对于任何一个项目来说,做好单元测试都是必不可少的一项工作。
(Behavior Driven Development,行为驱动开发是一种敏捷软件开发的技术。)之前重构一个代码库的时候,顺便研究了下这方面,自己捣鼓了一阵之后,好像还蛮有趣的样子,因此把我摸索入门的过程记录下来跟大家分享一下。

1、准备工作

  • 先新建一个项目文件夹,命名为test
  • 然后在test文件夹中创建一个名为test.js的文件,将来用来测试的脚本都放在这个文件夹里面。

2、相关node.js模块安装

首先使用npm以全局方式安装mocha模块:

  • $ npm install -g mocha
    然后通过命令进入cd test文件夹中,安装should模块

$ npm install should

3、一个简单的Demo

准备工作就绪之后,我们可以开始来尝试一些简单的demo实例,看看我们是如何使用mocha和should.js是进行测试工作的。可以直接先在项目根目录下执行mocha命令,看看有什么情况发生,执行后的结果如下示:
mocha ./

 0 passing (1ms)

运行后,发现只输出了这个结果,其他什么都木有哇……
这是因为mocha扫描我们的目录后,没有发现任何的测试脚本文件。

下面我们来编写简单的测试脚本来看一下:

打开文件test.js,输入如下脚本:

require("should");

var name = "Kvkens";

describe("Name", function() {
    it("The name should be Kvkens", function() {
        name.should.eql("Kvkens");
    });
});

var Person = function(name) {
    this.name = name;
};
var Kvkens = new Person(name);

describe("InstanceOf", function() {
    it("Kvkens should be an instance of Person", function() {
        Kvkens.should.be.an.instanceof(Person);
    });

    it("Kvkens should be an instance of Object", function() {
        Kvkens.should.be.an.instanceof(Object);
    });
});
describe("Property", function() {
    it("Kvkens should have property name", function() {
        Kvkens.should.have.property("name");
    });
});

重新执行命令mocha test.js如下所示:

D:\test>mocha test.js


  Name
    √ The name should be Kvkens

  InstanceOf
    √ Kvkens should be an instance of Person
    √ Kvkens should be an instance of Object

  Property
    √ Kvkens should have property name


  4 passing (11ms)


D:\test>

哎哟,看来我们的测试没问题,都跑通了。:)

我们来试着修改一下其中的一处,看看测试通过不?:(

name.should.eql("Kvkens");

修改name为Jay

name.should.eql("Jay");

我们在来跑一下测试:

D:\test>mocha test.js


  Name
    1) The name should be Kvkens

  InstanceOf
    √ Kvkens should be an instance of Person
    √ Kvkens should be an instance of Object

  Property
    √ Kvkens should have property name


  3 passing (13ms)
  1 failing

  1) Name The name should be Kvkens:

      AssertionError: expected 'Kvkens' to equal 'Jay'
      + expected - actual

      -Kvkens
      +Jay

并且下面还有一堆node错误,看来我们得破坏性测试成功了!!!发现了我们的断言写的有问题啦还给我们指出来了,是不是很神奇!

介绍下我们一些断言的含义:
首先为了使用should.js的断言库,在代码的开头部分必须引入should模块,但是mocha模块则无需显式引入。

每一个describe语句都可以看作是一个测试模块,它只是起着划分各个模块部分的作用,describe语句的第一个参数就是对该模块的描述。

在describe语句中的it语句才是测试的主体部分,每一个it语句都是一个测试单元,一个测试模块中可以有很多个测试单元。it语句的第一个参数的作用就是描述该单元的测试任务或要求,以便在测试用例数量较多时可以清楚地知道究竟有哪些功能的测试没有通过。

在it语句的回调函数中就可以通过书写should.js断言库中的语句进行测试了。should模块是assert模块的扩展,它的语法可以在上面的代码中看到,都是类似Kvkens.should.be.an.instanceof(Person) 这样的,跟我们日常用的语法几乎一模一样, 非常易于使用。

具体的使用请去TJ大神github (https://github.com/visionmedia/should.js)

4、提高部分,异步测试相关

这部分是在博客园看到的,觉得有必要说一下:

为了进行异步测试,在test目录下创建一个名为testReadFile.js的文件,代码如下:

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

describe("readFile", function() {
    it("The file content should be Kvkens", function(done) {
        fs.readFile("text.txt", "utf8", function(err, data) {
            data.should.eql("Kvkens");
            done();
        });
    });
});

在创建一个文text.txt件用于读取异步测试内容如下:

Kvkens

继续执行我们的测试输入:

D:\test>mocha testReadFile.js


  readFile
    √ The file content should be Kvkens


  1 passing (10ms)


D:\test>

观察上面的代码,有一点必须注意的是:在进行异步测试的时候,it语句的回调函数会带有一个参数done。我们必须在要测试的异步函数的回调函数的最后加上done()这一句,否则测试就会出错,因为测试不等异步函数执行完毕就结束了。

就介绍到这里,它代替了我们人为的去检测代码,如果用手工来一行行测试,这样效果不是很好,通过这类的测试方法就能代替我们做一些事,何乐而不为呢~ :)

部分参考于博客园各位大神们以及自己动手的修改

(完)