Code Coverage with CircleCI + Codecov

Code Coverage with CircleCI + Codecov


最近的案子用到 Redux + React,因為它 Pure Function 的特性,所以 單元測試 很容易寫,順便也趁機會玩一下 程式碼覆蓋率(Code Coverage)。

單元測試 Unit Test

這裡就不講單元測試怎麼寫了,網路上有很多大神的好文可以爬,我是用 Mocha + Chai
  • mocha 是 test framework,提供 describeit
  • chai 是 assertion library,提供 assertshouldexpect
安裝 Gulp
npm install --save-dev gulp gulp-mocha
安裝 Babel 讓程式支援 ES6 語法:
npm install --save-dev babel
加入 mocha 到 gulpfile.babel.js
// gulpfile.babel.js

import gulp from 'gulp';
import mocha from 'gulp-mocha';

gulp.task('mocha', () => {
  return gulp.src('test/**/*.js')
    .pipe(mocha());
});
使用 npm test 取代 gulp mocha
// package.json

{
  "scripts": {
    "test": "gulp mocha"
  }
}
這樣做的好處:
  • gulp 可不用 -g 全域安裝
  • CI 會自動執行測試

程式碼覆蓋率 Code Coverage

有許多提供 code coverage review 的服務,例如:Code ClimateCodecovCoveralls。這裡選擇 Codecov,因為它的 GitHub public repo 方案是免費的。


安裝 istanbul 產生 coverage report:
npm install --save-dev gulp-istanbul isparta
isparta 讓 istanbul 支援 ES6
加入 coverage 到 gulpfile.babel.js
// gulpfile.babel.js

import istanbul from 'gulp-istanbul';
import { Instrumenter } from 'isparta';

gulp.task('coverage:instrument', () => {
  return gulp.src('src/**/*.js')
    .pipe(istanbul({
      instrumenter: Instrumenter,
      includeUntested: true
    }))
    .pipe(istanbul.hookRequire())
})

gulp.task('coverage:report', () => {
  return gulp.src('src/**/*.js')
    .pipe(istanbul.writeReports())
})

gulp.task('coverage', done => {
  runSequence('coverage:instrument', 'mocha', 'coverage:report', done)
})
gulp coverage 會依順序執行:
  1. gulp coverage:instrument 配置單元測試的原始碼
  2. gulp mocha 執行單元測試
  3. gulp coverage:report 產生覆蓋率報告
npm test 換成 gulp coverage
// package.json

{
  "scripts": {
    "test": "gulp coverage"
  }
}
最後配置 CircleCI,當測試成功之後,自動上傳覆蓋率報告至 Codecov
npm install --save-dev codecov.io
# circle.yml

test:
  post:
    - cat ./coverage/lcov.info | codecov
以上,當你 push 程式碼到 GitHub 上、並且通過 CircleCI 的單元測試之後,Codecov 就會產生覆蓋率報告了!

完整範例請參考我的 GitHub

留言

這個網誌中的熱門文章

COSCUP 2012

Hahow 為什麼沒有 iOS App

swfobject - 網頁輕鬆嵌入Flash