Beace Lee

Beace Blog

Written by Beace Lee who lives and works in China building useful things. You should follow him on Twitter

关于 CI 及测试有关知识工具总结

November 01, 2018

JavaScript 测试相关工具和库的对比和总结,以及自动化测试以及持续集成的的相关实践。

单元测试

assert 断言

Assert | Node.js v11.0.0 Documentation是 node.js 提供的断言测试的模块。该模块的方法较少,顾名思义,此模块更多是验证boolean是否成立。

assert 又分为两种模式,strict 与 legacy,强烈推荐严格模式,一个是在写法上开启严格模式后不再需要增加额外的 strict,并且错误信息会有个 diff 的展示,更重要的是 任何 assert 函数都会使用严格函数模式的等式。通常一些优秀的 Node.js 开源项目都会再严格模式下执行。

'use strict'

class Controller extends BaseController {
	// ...
}

另外需要特别说明的是 assert 的 equal 用来比较实际与预期结果,当实际结果比较复杂,需要深入比较时,assert 提供了 deepStrictEqual 方法,具体比较了对象的类型、对象的原型等等。参考 assertassertdeepstrictequalactualexpected_message

Should.js

GitHub - shouldjs/should.js: BDD style assertions for node.js — test framework agnostic 作为 JavaScript 中的 行为驱动开发 - 维基百科,自由的百科全书 测试工具。其用法相当语义化,在进行书写时像是在和自己的代码对话,这也是 BDD 的优势所在。

should 相对于 assert 具有丰富的 API ,通过链式调用的方式,使得非开发人员可以参与。例如下面的代码

// 用户需要有pets属性,并且长度为4
user.should.have.property('pets').with.lengthOf(4);

should 还可以和其他模块相结合来使用,例如测试简单的 http 请求,结合immutableJS,jQuery 等。

参考 https://github.com/shouldjs/should.js#additional-projects

should-sinon - adds additional assertions for sinon.js

should-immutable - extends different parts of should.js to make immutable.js first-class citizen in should.js

should-http - adds small assertions for assertion on http responses for node only

should-jq - assertions for jq (need maintainer)

karma-should - make more or less easy to work karma with should.js

should-spies - small and dirty simple zero dependencies spies

Chai.js

与 should 类似, Chai 声称是 BDD/TDD 的断言库,兼容node和浏览器平台,由一点重要的是 chai 具有丰富的插件,比如 chai-webdriver, 提供了浏览器端的测试方法,例如以下代码(参考chai-webdriver - Chai

// Start with a webdriver instance:
var sw = require('selenium-webdriver');
var driver = new sw.Builder()
  .withCapabilities(sw.Capabilities.chrome())
  .build()

// And then...
var chai = require('chai');
var chaiWebdriver = require('chai-webdriver');
chai.use(chaiWebdriver(driver));

// And you're good to go!
driver.get('http://github.com');
chai.expect('#site-container h1.heading').dom.to.not.contain.text("I'm a kitty!");

通过引入 webdriver , chai 可以想 should 一样去操作和测试浏览器。

Expect.js

基于 should,这里可以看他的Feature, GitHub - Automattic/expect.js: Minimalistic BDD-style assertions for Node.JS and the browser.

  • Cross-browser: works on IE6+, Firefox, Safari, Chrome, Opera.
  • Compatible with all test frameworks.
  • Node.JS ready (require(‘expect.js’)).
  • Standalone. Single global with no prototype extensions or shims.

Mocha

Mocha - the fun, simple, flexible JavaScript test framework 提供了线性的持续测试。提供了各种生命周期的钩子函数,甚至可以利用上一次的测试用例进行下次的使用。

describe('hooks', function() {

  before(function() {
    // runs before all tests in this block
  });

  after(function() {
    // runs after all tests in this block
  });

  beforeEach(function() {
    // runs before each test in this block
  });

  afterEach(function() {
    // runs after each test in this block
  });

  // test cases
});

mocha 惊艳到我的是可视化的自动测试以及详细的测试报告。

mocha 可以将测试信息的信息再网页上显示,即使你测试的是nodejs程序,当你保存你的测试用例,mocha会自动进行测试并在网页上输出相应结果。

另外,你可以借助 nyc - npm 帮你生成测试报告

"script": {
	"cover": "nyc --reporter=text --reporter=html npm test",
}

这里是 text reporter

text-reporter

这里是 file-repoter

打开 index.html 可以查看

点到具体的某个函数可以按照行来查看具体哪行没有被覆盖,来继续提高测试的覆盖率

持续集成(CI)

Code Quality

codacy 是免费的代码质量工具,可以通过同步你的github代码,选择仓库之后通过相应的配置文件来检查你的代码是否规范,并且给出友好的提示。例如下面的代码没有声明 match 类型,codacy 提示了如下错误和改正方法。

通过代码的质量工具可以更好的约束和规范自己的代码,在避免低级的错误之外培养良好的习惯,尤其是在其报错之后引发自己的思考,反复地琢磨更好的是实现方式,从而进一步提高自己的编码水平。

Travis

代码质量检测是第一步,还是相当低级的一个检测,只会检测语法、类型、风格等等。逻辑的部分就需要交给CI来跑测试代码了。

Travis 是免费的 CI 工具,可以通过其自动构建你的项目,并跑测试最终release 产品。Travis提供了各种监控代码提交的方式 branch、tag等等,提交代码后自动构建,这也是CI 工具必备的技能。

说到CI 工具,必须有平台 platform 在起基础的支撑。每次触发 CI 的时候,travis 默认会基于 linux来构建,目前支持 linux和macos,不支持windows,所以很多electron的项目想要构建windows都会借助另外一个工具 appveyor。

Travis几乎是所有开源项目的必备了,其生命周期有以下几个概念。

Jobs 可以说是一个最小的单元,负责克隆代码后的编译 Builds 多个版本的build Stages 不同的阶段,例如开始之前你需要发个通知告诉自己CI开始了start stage,开始build build stage,build 结束之后再发一条通知end build stage,build出错了 build notify stage等等。

在使用 CI 时,需要了解他的配置文件是如何书写的,travis 通过声明式的yaml文件,在书写时就像在配置一台电脑的环境,参考Building a JavaScript and Node.js project - Travis CI

language: node_js # 你的语言node
node_js:
  - "8" # 版本 8
before_install:
  - "curl -L https://raw.githubusercontent.com/arunoda/travis-ci-laika/6a3a7afc21be99f1afedbd2856d060a02755de6d/configure.sh | /bin/sh"
services:
  - mongodb # 你需要mongodb服务
env:
  - LAIKA_OPTIONS="-t 5000"

CircleCI

Continuous Integration and Delivery - CircleCI 具有和Travis相同的功能,不过相对于 Travis 来说支持多语言比较少,而且不支持MacOS平台,不过构建速度很快,而且cache功能可以避免重复的 npm install。我最喜欢它的是对每个stage分的很清楚,不像travis只给一个最终结果,下面图片是我测试eggjs项目的stage。

Gitlab

在这里只做个简单的附加餐。作为企业内部来讲,不可能把代码开源。因此需要寻找自主搭建的CI服务,因此 gitlab 可以作为一种选择。

以下是我在github找到的 TDD JavaScript 开源项目 GitHub - rmurphey/js-assessment: A test-driven approach to assessing JS skills,我将答案填了上去,并且将其改成了node版本。Beace / js-assessment · GitLab

可以参考其CI以及相关构建过程 Pipelines · Beace / js-assessment · GitLab

总结

还有些其他的测试库有待更新,例如

通过对JavaScript的各种测试工具的调研,分析了工具的优势,具体的使用方法还是在相应文档中浏览并且实践比较好。

另外,对于CI的选择,CircleCI具有非常好的性能,并且构建速度非常快,但由于其平台和语言支持的不够多,所以比较适合小项目的构建。Travis 具有强大的功能以及平台支撑,可以用来构建大型的开源项目。gitlab用于企业私有的项目构建,而且gitlab需要gitlab-runner来作为支撑,需要有一定的运维经验。

参考文档

https://hackernoon.com/continuous-integration-circleci-vs-travis-ci-vs-jenkins-41a1c2bd95f5