Help us understand the problem. What is going on with this article?

gulp + karmaでテスト駆動開発

More than 3 years have passed since last update.

経緯

jsの開発をしていて、デグレが多くて辛いのでテスト駆動開発をしたいと思い
オレオレテスト駆動開発環境を作りました。

ローカル環境

  • mac(macOS 10.13.2)
  • Node.js(8.9.3)
  • gulp(3.9.1)
  • karma(2.0.0)

GitHub

  • TravisCI

ローカル環境を準備

1. Node.jsの導入

nvmでNode.jsは管理する

cd ~
git clone https://github.com/creationix/nvm.git ~/.nvm
source ~/.nvm/nvm.sh
nvm install v8.9.3
nvm alias default v8.9.3

macを起動した時に自動でNode.jsが起動するよう設定

vim ~/.bash_profile 

下記を追記

[[ -s ~/.nvm/nvm.sh ]] && . ~/.nvm/nvm.sh
nvm use default
npm_dir=${NVM_PATH}_modules
export NODE_PATH=$npm_dir

反映

source ~/.bash_profile

これでNode.jsの準備は完了。

2. gulp & karma

グローバルにgulpkarmaをインストール

npm install -g gulp karma

プロジェクトに必要なpackageをインストール

package 用途
gulp gulp本体
gulp-concat 複数のJSファイルを一個のJSにしてくれる
gulp-uglify 一個にまとめたJSをminfyする
karma karma本体
karma-coverage レポートを出すためのモジュール
karma-jasmine karmaでjasmineを使えるようにする
karma-phantomjs-launcher phantomjsで動かしたいので入れる
karma-spec-reporter コンソールを見やすくする
phantomjs phantomjs本体
jasmine jasmine本体
browser-sync Browsersync本体

インストール

npm install gulp gulp-concat gulp-uglify karma karma-coverage karma-jasmine karma-phantomjs-launcher karma-spec-reporter phantomjs jasmine browser-sync --save-dev

3. gulpfile.jsを設定

var gulp    = require("gulp");
var browser = require("browser-sync").create();
var concat  = require("gulp-concat");
var uglify  = require("gulp-uglify");
var Server  = require("karma").Server;

/**
 * server setting
 */
gulp.task("server", function ()
{
    browser.init({
        server: {
            baseDir: "./",
            index: "index.html"
        }
    });
});

/**
 * browser reload
 */
gulp.task("reload", function ()
{
    browser.reload();
});

/**
 * output swf2js
 */
gulp.task("output", function ()
{
    gulp.src([
            "src/**/*.js",
        ])
        .pipe(concat("output.js")) // 複数のJSを一個にまとめる
        .pipe(uglify()) // 圧縮
        .pipe(gulp.dest(".")); // 圧縮したファイルを出力
});

/**
 * default setting
 */
gulp.task("default", ["server"], function ()
{
    // JSに変更があればテストを起動
    gulp.watch(["src/**/*.js"], ["tdd"]);
    // テスト通過したファイルが出力されたらブラウザを再読み込み
    gulp.watch(["output.js"], ["reload"]);
});

/**
 * test-driven development
 */
gulp.task("tdd", function (done)
{
    new Server({
        configFile: __dirname + "/karma.conf.js",
        singleRun: false
    }, done)
        .on("run_complete", function (browsers, results)
        {
            // エラーがあれば出力
            if (results.failed) {
                throw new Error("failed");
            }
            // テストが終了したらjsを出力する
            gulp.start.apply(gulp, ["output"]);
        })
        .on("error", function (err) {
            done(err);
        })
        .start();
});

/**
 * Run test once and exit
 */
gulp.task("test", function (done)
{
    new Server({
        configFile: __dirname + "/karma.conf.js",
        singleRun: true
    }, done).start();
});

4. karma.conf.jsを設定

// Karma configuration
// Generated on Wed Sep 06 2017 20:07:29 GMT+0900 (JST)

module.exports = function(config)
{
  config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',


    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['jasmine'],


    // list of files / patterns to load in the browser
    files: [
      "src/**/*.js",
      "test/**/*.js"
    ],


    // list of files to exclude
    exclude: [
    ],


    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
        'src/**/*.js': ['coverage']
    },


    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['spec', 'coverage'],

    coverageReporter: {
      type: 'html',
      dir: 'coverage/'
    },

    // web server port
    port: 9876,


    // enable / disable colors in the output (reporters and logs)
    colors: true,


    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,


    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,


    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['PhantomJS'],


    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: false,

    // Concurrency level
    // how many browser should be started simultaneous
    concurrency: Infinity
  });
};

これで、ローカルの準備が整ったのでgulpを起動して動くか確認。

# gulp
[00:00:00] Using gulpfile ~/**/gulpfile.js
[00:00:00] Starting 'server'...
[00:00:00] Finished 'server' after 
[00:00:00] Finished 'server' after 11 ms
[00:00:00] Starting 'default'...
[00:00:00] Finished 'default' after 140 ms
[Browsersync] Access URLs:
 ---------------------------------------
       Local: http://localhost:3000
    External: http://172.17.100.100:3000
 ---------------------------------------
          UI: http://localhost:3001
 UI External: http://172.17.100.100:3001
 ---------------------------------------
[Browsersync] Serving files from: ./

こんな感じで動けばローカルの準備はOK。

GitHub側の設定

1. .travis.yml

.travis.ymlにテスト環境の設定を書く。

language: node_js
node_js:
  - "8.9.3"

cache:
  directories:
    - "node_modules"

before_install:
  - npm install -g gulp karma

install:
  - npm install

2. package.json

テストのディレクトリと実行スクリプトを追記

{
  "directories": {
    "test": "test"
  },
  "scripts": {
    "test": "gulp test"
  },
}

これでコミットする度にTravisでテストできます。

それでは、楽しいテスト駆動ライフを〜

ienaga
PHP/Phalcon/JavaScript/swf2js/AWS/CircleCI/TravisCI/Redis/Elasticsearch/API Gateway/Lambda/CodeDeploy/MySQL/WebGL/Linux/Nginx/NodeJS/Docker/Ansible
https://github.com/ienaga
sonicmoov
ソニックムーブは最先端のテクノロジーと サービス運用から得たデータで、 企業の『課題解決』『資産の最大化』『新規事業創出』を 支援するR&Dスタジオです。
https://www.sonicmoov.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away