Testing Node.js With Mocha and Chai

原文: http://mherman.org/blog/2015/09/10/testing-node-js-with-mocha-and-chai/#.ViO8oBArIlJ

为什么要测试?

在此之前了解为什么要测试非常重要.

通过下面的地址获取一个Node/Express的简单的CRUD应用:

$ git clone https://github.com/mjhea0/node-mocha-chai-tutorial.git
$ git checkout tags/v1

现在可以通过食用curl(或者Postman)来测试CRUD了:

  1. 添加一个新的blob
  2. 查看所有的blob
  3. 查看一个blob
  4. 更新一个blob
  5. 删除一个blob

这个过程十分乏味. 如果我们在这个应用中没添加一个新功能就需要手动做这样的测试, 不仅会占用大量的时间而且可能还会因为手误或忘记测试某个功能使得测试不可信. 所以我们需要自动测试, 有了自动测试我们可以在几秒钟内测试玩几百个这样的功能.

首先, 安装Mocha:

$ npm install -g [email protected]

结构

在应用的根目录创建一个文件夹test, 然后在这个test文件夹中创建一个test-server.js. 现在项目的结构如下:

├── package.json
├── server
│   ├── app.js
│   ├── models
│   │   └── blob.js
│   └── routes
│       └── index.js
└── test
    └── test-server.js

现在, 在test-server.js中添加下面的代码:

describe(‘Blobs‘, function() {
  it(‘should list ALL blobs on /blobs GET‘);
  it(‘should list a SINGLE blob on /blob/<id> GET‘);
  it(‘should add a SINGLE blob on /blobs POST‘);
  it(‘should update a SINGLE blob on /blob/<id> PUT‘);
  it(‘should delete a SINGLE blob on /blob/<id> DELETE‘);
});

describe用来分组测试. it语句包含了每个独立的测试用例.

逻辑

Chai是一个assertion库, 我们使用chai-http做一些HTTP请求, 然后测试响应:

使用下面的命令同时安装chai和chai-http:

$ npm install [email protected] [email protected] --save-dev

更新test-server.js如下:

var chai = require(‘chai‘);
var chaiHttp = require(‘chai-http‘);
var server = require(‘../server/app‘);
var should = chai.should();

chai.use(chaiHttp);

describe(‘Blobs‘, function() {
  it(‘should list ALL blobs on /blobs GET‘);
  it(‘should list a SINGLE blob on /blob/<id> GET‘);
  it(‘should add a SINGLE blob on /blobs POST‘);
  it(‘should update a SINGLE blob on /blob/<id> PUT‘);
  it(‘should delete a SINGLE blob on /blob/<id> DELETE‘);
});

现在可以写测试了

测试-GET(all)

更新第一个it():

it(‘should list ALL blobs on /blobs GET‘, function(done) {
  chai.request(server)
    .get(‘/blobs‘)
    .end(function(err, res){
      res.should.have.status(200);
      done();
    });
});

我们传递了一个只用一个参数(done function)的匿名函数给it. 这个匿名函数的最后一行是done(). 这个测试十分简单, Get /blobs 判断响应的http status code是否是200.

简单的运行mocha就能测试了:

$ mocha

  Blobs
Connected to Database!
GET /blobs 200 19.621 ms - 2
    ? should list ALL blobs on /blobs GET (43ms)
    - should list a SINGLE blob on /blob/<id> GET
    - should add a SINGLE blob on /blobs POST
    - should update a SINGLE blob on /blob/<id> PUT
    - should delete a SINGLE blob on /blob/<id> DELETE

  1 passing (72ms)
  4 pending

因为简单的判断HTTP状态码对我们判断是否返回整个blobs来说意义不大, 现在来添加更多的断言:

it(‘should list ALL blobs on /blobs GET‘, function(done) {
  chai.request(server)
    .get(‘/blobs‘)
    .end(function(err, res){
      res.should.have.status(200);
      res.should.be.json;
      res.body.should.be.a(‘array‘);
      done();
    });
});

  

测试-POST

当添加blob成功, 响应如下:

{
  "SUCCESS": {
    "__v": 0,
    "name": "name",
    "lastName": "lastname",
    "_id": "some-unique-id"
  }
}

现在我们来写测试:

it(‘should add a SINGLE blob on /blobs POST‘, function(done) {
  chai.request(server)
    .post(‘/blobs‘)
    .send({‘name‘: ‘Java‘, ‘lastName‘: ‘Script‘})
    .end(function(err, res){
      res.should.have.status(200);
      res.should.be.json;
      res.body.should.be.a(‘object‘);
      res.body.should.have.property(‘SUCCESS‘);
      res.body.SUCCESS.should.be.a(‘object‘);
      res.body.SUCCESS.should.have.property(‘name‘);
      res.body.SUCCESS.should.have.property(‘lastName‘);
      res.body.SUCCESS.should.have.property(‘_id‘);
      res.body.SUCCESS.name.should.equal(‘Java‘);
      res.body.SUCCESS.lastName.should.equal(‘Script‘);
      done();
    });
});

  

Hooks

专门有一个test数据库并且插入一些样例数据用来测试. 我们可以使用beforeEach和afterEach hooks-用来在每一个单元测试运行之前添加一些样例数据, 运行之后删除这些样例数据.

使用Mocha来做这些特别简单!

在server文件夹下面创建一个配置文件_config.js, 使用它为测试指定一个不通的数据库uri:

var config = {};

config.mongoURI = {
  development: ‘mongodb://localhost/node-testing‘,
  test: ‘mongodb://localhost/node-test‘
};

module.exports = config;

接下来更新app.js文件:

// *** config file *** //
var config = require(‘./_config‘);

// *** mongoose *** ///
mongoose.connect(config.mongoURI[app.settings.env], function(err, res) {
  if(err) {
    console.log(‘Error connecting to the database. ‘ + err);
  } else {
    console.log(‘Connected to Database: ‘ + config.mongoURI[app.settings.env]);
  }
});

最后更新测试脚本:

process.env.NODE_ENV = ‘test‘;

var chai = require(‘chai‘);
var chaiHttp = require(‘chai-http‘);
var mongoose = require("mongoose");

var server = require(‘../server/app‘);
var Blob = require("../server/models/blob");

var should = chai.should();
chai.use(chaiHttp);

describe(‘Blobs‘, function() {

  Blob.collection.drop();

  beforeEach(function(done){
    var newBlob = new Blob({
      name: ‘Bat‘,
      lastName: ‘man‘
    });
    newBlob.save(function(err) {
      done();
    });
  });
  afterEach(function(done){
    Blob.collection.drop();
    done();
  });

...snip...

现在, 每个单元测试(it)运行之前数据库会被清空, 接下来会添加一个blob. 运行之后有会清空数据库.

测试-GET(all)

有了hooks的设置后, 我们修改get(all)的单元测试:

it(‘should list ALL blobs on /blobs GET‘, function(done) {
  chai.request(server)
    .get(‘/blobs‘)
    .end(function(err, res){
      res.should.have.status(200);
      res.should.be.json;
      res.body.should.be.a(‘array‘);
      res.body[0].should.have.property(‘_id‘);
      res.body[0].should.have.property(‘name‘);
      res.body[0].should.have.property(‘lastName‘);
      res.body[0].name.should.equal(‘Bat‘);
      res.body[0].lastName.should.equal(‘man‘);
      done();
    });
});

测试-GET(single)

it(‘should list a SINGLE blob on /blob/<id> GET‘, function(done) {
    var newBlob = new Blob({
      name: ‘Super‘,
      lastName: ‘man‘
    });
    newBlob.save(function(err, data) {
      chai.request(server)
        .get(‘/blob/‘+data.id)
        .end(function(err, res){
          res.should.have.status(200);
          res.should.be.json;
          res.body.should.be.a(‘object‘);
          res.body.should.have.property(‘_id‘);
          res.body.should.have.property(‘name‘);
          res.body.should.have.property(‘lastName‘);
          res.body.name.should.equal(‘Super‘);
          res.body.lastName.should.equal(‘man‘);
          res.body._id.should.equal(data.id);
          done();
        });
    });
});

测试-PUT

it(‘should update a SINGLE blob on /blob/<id> PUT‘, function(done) {
  chai.request(server)
    .get(‘/blobs‘)
    .end(function(err, res){
      chai.request(server)
        .put(‘/blob/‘+res.body[0]._id)
        .send({‘name‘: ‘Spider‘})
        .end(function(error, response){
          response.should.have.status(200);
          response.should.be.json;
          response.body.should.be.a(‘object‘);
          response.body.should.have.property(‘UPDATED‘);
          response.body.UPDATED.should.be.a(‘object‘);
          response.body.UPDATED.should.have.property(‘name‘);
          response.body.UPDATED.should.have.property(‘_id‘);
          response.body.UPDATED.name.should.equal(‘Spider‘);
          done();
      });
    });
});

测试-删除

it(‘should delete a SINGLE blob on /blob/<id> DELETE‘, function(done) {
  chai.request(server)
    .get(‘/blobs‘)
    .end(function(err, res){
      chai.request(server)
        .delete(‘/blob/‘+res.body[0]._id)
        .end(function(error, response){
          response.should.have.status(200);
          response.should.be.json;
          response.body.should.be.a(‘object‘);
          response.body.should.have.property(‘REMOVED‘);
          response.body.REMOVED.should.be.a(‘object‘);
          response.body.REMOVED.should.have.property(‘name‘);
          response.body.REMOVED.should.have.property(‘_id‘);
          response.body.REMOVED.name.should.equal(‘Bat‘);
          done();
      });
    });
});

  

时间: 2024-08-08 08:03:41

Testing Node.js With Mocha and Chai的相关文章

[Node.js] Testing ES6 Promises in Node.js using Mocha and Chai

Writing great ES6 style Promises for Node.js is only half the battle. Your great modules must include tests as well to ensure future iterations don't break them. In this lesson, I show you a simple ES6 Promise in Node.js, then walk you through creati

带你入门带你飞Ⅱ 使用Mocha + Chai + SuperTest测试Restful API in node.js

目录 1. 简介 2. 准备开始 3. Restful API测试实战 Example 1 - GET Example 2 - Post Example 3 - Put Example 4 - Delete 4. Troubleshooting 5. 参考文档 简介 经过上一篇文章的介绍,相信你已经对mocha, chai有一定的了解了, 本篇主要讲述如何用supertest来测试nodejs项目中的Restful API, 项目基于express框架. SuperTest 是 SuperAge

Practical Node.js第3章:测试

TDD and BDD for Node.js with Mocha TDD测试驱动开发.自动测试代码. BDD: behavior-driven development行为驱动开发,基于TDD.一种自然化的测试语言. 例如,使用expect(response.status).to.equal(200)代替了TDD的assert.equal(response.status, 200) Mocha  摩卡?? (点击连接看git)(方法:文档) 本章介绍:比较流行的javascript test

10+ 最佳的 Node.js 教程和实例

如果你正在找Node.js的学习资料及指南,那么请继续(阅读),我们的教程将会覆盖即时聊天应用.API服务编写.投票问卷应用.人物投票APP.社交授权. Node.js on Raspberry Pi等等. 以下是Node.js入门的简单介绍,如果你对Node.js略有了解可以直接跳过此部分. 那什么是Node.js呢? Node.js是迄今运用最多的服务端JavaScript运行时环境,使用JavaScript开发跨平台的实时WEB应用. Node.js基于Google的V8 JavaScri

Understanding node.js

Understanding node.js Posted on 29/4/10 by Felix Geisendörfer Node.js has generally caused two reactions in people I've introduced it to. Basically people either "got it" right away, or they ended up being very confused. If you have been in the

带你入门带你飞Ⅰ 使用Mocha + Chai + Sinon单元测试Node.js

目录 1. 简介 2. 前提条件 3. Mocha入门 4. Mocha实战 被测代码 Example 1 Example 2 Example 3 5. Troubleshooting 6. 参考文档 简介 Mocha 是具有丰富特性的 JavaScript 测试框架,可以运行在 Node.js 和浏览器中,使得异步测试更简单更有趣.Mocha 可以持续运行测试,支持灵活又准确的报告,当映射到未捕获异常时转到正确的测试示例. Chai 是一个针对 Node.js 和浏览器的行为驱动测试和测试驱动

[Node.js] Test Node RESTful API with Mocha and Chai

In this lesson, we will use Chai's request method to test our Node application's API responses.By the end of this lesson, you will know how to:- install the prerequisites to use mocha and chai in your application- test for HTTP status response codes-

e2e 自动化集成测试 架构 京东 商品搜索 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step (四) Q 反回调

上一篇文章“e2e 自动化集成测试 架构 京东 商品搜索 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step (三) SqlServer数据库的访问” 下面讲一下,对于在写Node.js自动化测试脚本过程中,的编写回调问题, 大家可能会发现, Node.js对于高并发处理的性能非常不错, 即使是在使用单核的情况下, 那是因为它是基于事情,说白了就是callback, 回调. 这样的话,对于写代码的人来说, 回调的深度一深就会晕了

e2e 自动化集成测试 架构 京东 商品搜索 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step 一

大前有发布一篇文章“e2e 自动化集成测试 环境搭建 Node.js Selenium WebDriverIO Mocha Node-Inspector”, 主要是讲了,如何搭建环境, 其中开发环境使用的是微软的Visual Studio, 使用之后, 我发现,其它并不怎么好用, 发面收费版的WebStorm对于开发Node.js其实是更为方便. 建议使用WebStorm来作为开发环境. 可以试用30天,当前你可以获得License, 方法你懂的... 前言 Node.js是开源的,基于Java