mocha入门学习

作为一个项目而言,单元测试应该是必备的一部分,也是最容易被大家忽略的一部分,这篇文章就介绍一下mocha这个测试框架的用法。

DEMO地址 https://github.com/TimLiu1/study-mocha.git

一、环境搭建

首先先全局安装mocha

npm i mocha -g
二、 简单测试脚本书写

1、新建 calcu.js

//add
exports.add = (a,b) => {
    return a + b
}

2、新建测试脚本 calcu.test.js,一般命名规则测试脚本和原脚本同名,但是后缀名为.test.js

let calcu = require('./calcu');
let should = require("should");

describe("add func test",() => {
    it('2 add 2 should equal 4',() => {
      calcu.add(2,2).should.equal(4)
    })
})

这一段代码就是测试脚本,可以独立运行,使用命令

mocha demo1/mocha demo1/calcu.test.js

describe 表示测试套件,是一序列相关程序的测试

it表示单元测试(unit test),也就是测试的最小单位。

三、断言库简介

断言库可以理解为比较函数,也就是断言函数是否和预期一致,如果一致则表示测试通过,如果不一致表示测试黑失败,一个unit test里面可以包含多个断言语句。

本身mocha是不包含断言库的,所以必须引入第三方断言库,目前比较受欢迎的断言库 有 should.js、expect.js 、chai,具体的语法规则需要大家去查阅相关文档。

因为chai既包含should、expect和assert三种风格,可扩展性比较强。
下面简单的介绍一下这是那种风格

should

let num = 4+5
num.should.equal(9);
num.should.not.equal(10);

//boolean
'ok'.should.to.be.ok;
false.should.to.not.be.ok;

//type
'test'.should.to.be.a('string');
({ foo: 'bar' }).should.to.be.an('object');

expect

let expect = require("chai").expect;


// equal or no equal
let num = 4+5
expect(num).equal(9);
expect(num).not.equal(10);

//boolean
expect('ok').to.be.ok;
expect(false).to.not.be.ok;

//type
expect('test').to.be.a('string');
expect({ foo: 'bar' }).to.be.an('object');

assert

let assert = require("chai").assert;


// equal or no equal
let num = 4+5
assert.equal(num,9);

//type
assert.typeOf('test', 'string', 'test is a string');
四、mocha用法详解

平时长写的测试类型一共三种

  • 常规函数测试
  • 异步函数测试
  • api测试

4.1、常规函数


测试就如我们上面写的第一个测试用例

4.2 异步函数测试


新建文件book.js

let fs = require('fs');

exports.read = (cb) => {
        fs.readFile('./book.txt', 'utf-8', (err, result) => {
            if (err) return cb(err);
            console.log("result",result);
            cb(null, result);
        }) 
}


新建文件book.test.js

let book = require('./book');
let expect = require("chai").expect;

let book = require('./book');
let expect = require("chai").expect;

describe("async", () => {
  it('read book async', function (done) {
    book.read((err, result) => {
      expect(err).equal(null);
      expect(result).to.be.a('string');
      done();
    })
  })
})

运行mocha book.test.js,我们会发现成功了,但是如果我们把book.js增加一个定时函数,改为如下例子

let fs = require('fs');

exports.read = (cb) => {
    setTimeout(function() {
        fs.readFile('./book.txt', 'utf-8', (err, result) => {
            if (err) return cb(err);
            console.log("result",result);
            cb(null, result);
        }) 
    }, 3000);
}

会发现报如下错误

Timeout of 2000ms exceeded.

这是因为mocha默认每个测试用例最多执行2000毫秒,如果到时没有得到结果,就报错。所以我们在进行异步操作的时候,需要额外指定timeout时间

mocha --timeout 5000 book.test.js

这样就保证测试用例成功

4.3、api测试


api测试需要用到一个的是模块 supertest,安装这个模块。

npm i supertest --save-dev

新建文件api.test.js

let expect = require("chai").expect;
let request = require('supertest');

describe("api", () => {
  it('get baidu information', function (done) {
    request('https://www.baidu.com')
      .get('/')
      .expect(200)
      .expect('Content-Type', /html/)
      .end(function (err, res) {
        expect(res).to.be.an('object');
        done();
      });
  })
})

五、命令行参数详解

5.1、--reporter :用来指定报告的格式


mocha --reporter spec

默认报告格式spec,我个人比较喜欢的网页格式是
mochawesome,
需要手动安装

npm i mochawesome --save-dev
./node_modules/.bin/mocha ./demo*/*.test.js -t 5000 --reporter mochawesome

-t 5000是因为我们测试用例中有一个异步执行过程,需要调高mocha的单元测试时间

5.2、--watch :参数用来监视指定的测试脚本。只要测试脚本有变化

5.3、--bail:参数指定只要有一个测试用例没有通过,就停止执行后面的测试用例

5.4、--grep:参数用来搜索单元测试用例的名称,然后运行符合搜索条件的测试用例,支持正则表达


mocha --grep /2/   ./demo*/*.test.js

5.5、--invert:参数表示只运行不符合条件的测试脚本,必须与--grep参数配合使用。
5.6 --recursive


一般如果运行mocha,会执行当前目录下的test目录的一级层级的所有js文件,但是test下的更多层级却没办法运行,这时就需要参数--recursive,这时test子目录下面所有的测试用例----不管在哪一层----都会执行。

六、配置文件mocha.opts的配置

每次我们运行测试用例的时候都需要写很长一段命令行,每次都一样,这样是不可取的,所以我们可以把这些配置维护到配置文件里面。

Mocha允许在test目录下面,放置配置文件mocha.opts,新建test文件夹,放置以下文件
api.test.js

let expect = require("chai").expect;
let request = require('supertest');

describe("api", () => {
  it('get baidu information', function (done) {
    request('https://www.baidu.com')
      .get('/')
      .expect(200)
      .expect('Content-Type', /html/)
      .end(function (err, res) {
        expect(res).to.be.an('object');
        done();
      });
  })
})

运行

 mocha --reporter tap 

然后在test下建mocha.opts

 // mocha.opts
 ```
 --reporter tap 
 ```

运行mocha,得到和上面一样的结果

七、mocha的生命钩子

mocha一共四个生命钩子
before():在该区块的所有测试用例之前执行
after():在该区块的所有测试用例之后执行
beforeEach():在每个单元测试前执行
和afterEach():在每个单元测试后执行

describe('hooks', function () {
    let i = 1
    let j = 1
    let m = 1
    let n = 1
    before(function () {
        console.log("the " + i++ + " start")
    });

    after(function () {
        console.log("the " + j++ + " end")
    });

    beforeEach(function () {
        console.log("the " + m++ + " start")
    });

    afterEach(function () {
        console.log("the " + n++ + " start")
    });

    it('one', function (done) {
        done()
    })
    it('two', function (done) {
        done()
    })
});
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容