使用CircleCI轻松实现NodeJs应用持续集成测试

顺应产品快速迭代的节奏需求,持续集成测试/部署(Continuous Integration)越来越成为大中小开发团队必不可少的工作流程,原始的人肉测试/部署远远不能满足小步快走的需求。对此,@湾区日报 这样评论:

一个团队工程技术水平高低,直接反映在部署代码上。我碰到其他公司的人,都喜欢问你们怎么部署代码的,非常大开眼界。你很难相信,很多(有一定规模的)公司仍然是人肉 SSH 到十几、二十台机器上 git pull、手动重启服务器,部署一次代码几个小时 -- 这么原始,活该加班:)

然而,持续集成测试并不是什么奢侈品(对于中小团队而言,Self Hosted CI Service可能比较奢侈),本文就以NodeJs应用为例,叨一叨如何使用目前流行的CI服务CircleCI实现持续集成测试。涉及的内容包括:

  • 为基于express的NodeJs应用添加Mocha单元测试框架
  • 于CircleCI中创建项目测试

创建NodeJs应用

CircleCI和GitHub的兼容性很好,深度集成了GitHub API,顾推荐使用GitHub进行版本控制和代码Host,并直接使用GitHub账号注册登录CircleCI。首先在GitHub中创建一个项目,通过npm init创建package.json文件并添加以下信息:

{
  ...
  "main": "index.js",
  "scripts": {
    "test": "mocha",
    "run": "node index"
  },
  "devDependencies": {
    "mocha": "^3.5.0",
    "should": "^12.0.0",
    "supertest": "^3.0.0"
  },
  "dependencies": {
    "express": "^4.15.4"
  }
}

配置文件中添加了四个依赖模块:

  • express:用于创建web服务应用
  • mocha:提供单元测试
  • should:用于单元测试样例编写
  • supertest:用于单元测试样例编写

我们将使用express创建一个最简单的web应用:

var express = require('express')
var app = express()
app.get('/', function (req, res) {
  res.send('Hello World')
})
app.listen(3000)
module.exports = app

这里将app导出为模块,以备后用。有了这段代码,就可以在本地启动一个只有一个API的web服务。
接下来我们进Mocha单元测试框架整合至这个项目。首先于项目根目录创建文件夹test,(Mocha被执行时会默认扫描当前目录下test子目录中的js文件,关于更多的路径设置和文件过滤,请参照Mocha官方文档)并创建test.js文件。此时项目文件结构应该是:

.
├── index.js
├── .gitignore
├── node_modules/
├── package-lock.json
├── package.json
└── test/
    ├── mocha.opts
    └── test.js

test.js文件中加入测试代码:

const request = require('supertest'),
    should = require('should'),
    app = require('../index.js')

describe('CI Test App', () => {
	const agent = request.agent(app);
	it('should return hello world', (done) => {
		agent.get('/')
		.expect(200)
		.expect('Hello World', done)
	})
})

这里就会用到index.js文件里导出的app模块,并使用supertest对其进行请求。在命令行中执行npm test后,就能得到测试结果:

CI Test App
  ✓ should return hello world
1 passing (43ms)

至此,基于express的NodeJs web应用创建和Mocha测试框架集成已经完成。

创建CircleCI项目测试

  1. 首先进入CircleCI控制台
  2. 进入PROJECTS标签页
  3. 点击Add Project进行项目创建
  4. 由于CircleCI已获得GitHub账号权限,此时页面会显示出GitHub账号下所有的代码库,选择刚刚创建的项目并点击Setup Project进行项目设置
  5. 随后的页面中只需要更改选择LanguageNode即可按照页面中的步骤进行操作,并最终点击Start building完成项目创建。

在添加并编辑如下的.circleci/config.yml后便可以将代码push到GitHub代码库中:

jobs:
  build:
    docker:
      - image: circleci/node:7.10
    working_directory: ~/repo

    steps:
      - checkout
      - restore_cache:
          keys:
          - v1-dependencies-{{ checksum "package.json" }}
          - v1-dependencies-
      - run: npm install
      - save_cache:
          paths:
            - node_modules
          key: v1-dependencies-{{ checksum "package.json" }}
      - run: npm test

这时就可以在CircleCI控制台的BUILDS标签页中看到项目各个运行步骤的过程和测试结果啦!
WX20170829-221517@2x
与此同时,在GitHub项目中的commits里同样可以看到build结果。
WX20170829-221806@2x

本文简短说明了CircleCI的玩法,实际项目中可能还涉及到其他功能,如持续部署,消息推送,Workflow等,自行挖掘吧。