deepblue-will’s diary

JS、CSS,Ruby、Railsなど仕事や趣味で試した技術系のことを書いていきます。

CoffeeScript + power-assert + (karma)の環境を作ってみた

RSpec についての議論power-assert なるものを知ったのでCoffeeScript + power-assert + (Karma)の環境を作ってみました。

power-assertとは

TDD(テスト駆動開発)でおなじみの@t_wadaさん作の「Node.js assert拡張」です

アサーションは3つ覚えればOK!

最悪、assert()だけでもなんとかなる気もする

  • aseert()
  • assert.deepEqual()
  • asset.notDeepEqual()

素敵なテスト失敗時のログ

失敗の原因がわかりやすい。
テストの実行前にテストコードをpower-assert用のコードに変換することで、この素敵な出力が可能になるそうです。

   assert(this.target.getFizzBuzzStr(3) === "2")
                  |      |                 |
                  |      "Fizz"            false
                  FizzBuzz{}

      --- [string] "2"
      +++ [string] this.target.getFizzBuzzStr(3)
      @@ -1 +1,4 @@
      -2
      +Fizz

power-assert環境の作り方① (CoffeeScript + power-assert)

サンプルコードがあるリポジトリ

最近、altJS使わずに、生のJSで書いてますって方はあんまりいないような気がする + 私はCoffeeScriptで仕事してるので、CoffeeScriptで出来るような環境を作ってみました。

フォルダ構成

├── src
│   └── fizz_buzz.coffee
└── test
    └── fizz_buzz_test.coffee

必要なNode Module

$ npm install --save-dev mocha power-assert espower-coffee
  • mocha
  • power-assert
  • espower-coffee
    • coffee → js → power-assert用コードの変換をしてくれるやつ

テスト対象コードとテストコード

src/fizz_buzz.coffee

class FizzBuzz

  getFizzBuzzStr: (i) ->
    if i % 15 == 0
      'FizzBuzz'
    else if i % 5 == 0
      'Buzz'
    else if i % 3 == 0
      'Fizz'
    else
      i.toString()

module.exports = FizzBuzz

test/fizz_buzz_test.coffee

FizzBuzz = require "../src/fizz_buzz"
assert = require "power-assert"

describe "FizzBuzz", ->
  beforeEach ->
    @target = new FizzBuzz()

  describe "#getFizzBuzzStr()は", ->
    it "3で割り切れる数字を与えるとFizzを返却すること",  ->
      assert @target.getFizzBuzzStr(3) == "Fizz"

    it "5で割り切れる数字を与えるとBuzzを返却すること",  ->
      assert @target.getFizzBuzzStr(5) == "Buzz"

    it "3と5で割り切れる数字を与えるとFizzBuzzを返却すること",  ->
      assert @target.getFizzBuzzStr(15) == "FizzBuzz"

    it "3と5で割り切れない数字を与えると数字文字列を返却すること",  ->
      assert @target.getFizzBuzzStr(2) == "2"

    it "わざと失敗させるテストです",  ->
      assert @target.getFizzBuzzStr(3) == "2"

npm testで実行できるようにする

package.jsonscriptsに以下を記述するとnpm testで実行できるようになります。

:package.json

...
  "scripts": {
    "test": "mocha --require espower-coffee/guess test/**/*_test.coffee"
  },
...

gulpで実行できるように

gulpfileに数行のタスクを書くだけでgulp testでも実行できるようになります

gulpfile.coffee

g = require 'gulp'
mocha = require 'gulp-mocha'

g.task 'test', ->
  require 'espower-coffee/guess'
  g.src 'test/**/*_test.coffee'
    .pipe mocha()

power-assert環境の作り方② (CoffeeScript + Karma + power-assert)

サンプルコードがあるリポジトリ

上記だとNodeのプロジェクトでないと実行できないので、Karmaを使ってブラウザでテストを実行できる環境を作ってみました。

必要なnode module

$ npm install -g karma-cli # karmaコマンドを使いたい場合
$ npm install -save-dev karma karma-coffee-preprocessor karma-espower-preprocessor karma-chrome-launcher karma-phantomjs-launcher
  • karma
    • テストランナー
    • Angularのチームが開発
  • karma-coffee-preprocessor
    • テスト実行前にcoffeeをjsにしてくれるやつ
  • karma-espower-preprocessor
    • テスト実行前にpower-assert用のコードにしれくれるやつ
  • karma-chrome-launcher
    • Chromeでテストを実行する場合必要
  • karma-phantomjs-launcher
    • ブラウザを起動せずに実行する場合必要

テスト対象コードとテストコード

上記とほぼ同じです。 ブラウザでテストするので、module.exportsrequireの行は除去してください。

karmaの設定

karma initするとkarma設定ファイル(karma.conf.js)が作成され、このファイルを元にkarmaはテストを実行します。 少し修正してpower-assertが動くようにします。(coffeeに書き直してます。) 修正すればkarma startでkarmaが起動してテストが行えるようになるはずです。

:karma.conf.coffee

# Karma configuration

module.exports = (config) ->
  config.set
    basePath: '',
    frameworks: ['mocha'],

    # テストに必要なファイルを記述する
    files: [
      'node_modules/power-assert/build/power-assert.js'
      'src/**/*.coffee'
      'test/**/*_test.coffee'
    ],

    # ↑のなかで除外したいものがあれば記述する
    exclude: [],

    # テスト実行前にしたい処理を挟める
    # ここではcoffeeのコンパイルとpower-assert化をする
    preprocessors:
      '**/*.coffee': ['coffee']
      'test/**/*_test.coffee': ['espower']

    espowerPreprocessor:
    # power-assert化したファイルを出力したければコメントアウトを外す
#      options:
#        # emit espowerified code.
#        # default: false (in-memory)
#        emitActualCode: true
    
    # これを書かないと既存のテストコードを上書きしてしまうので
      transformPath: (path) ->
        path.replace /\.coffee$/, '.espowered.js'

    reporters: ['progress'],

    port: 9876,

    colors: true,

    logLevel: config.LOG_INFO,

    autoWatch: true,
  
  # テストを実行するブラウザ。お好みで
    browsers: [
#      'Chrome'
      'PhantomJS'
    ],

    singleRun: false

gulpで実行できるように

これも数行でgulpで実行できるようにできます。 gulp testで実行です。

:karma.conf.coffee

g = require 'gulp'
karma = require('karma').server

g.task 'test', ->
  karma.start
    configFile: "#{__dirname}/karma.conf.coffee",
    singleRun: true

参考

パーフェクトJavaScript (PERFECT SERIES 4)

パーフェクトJavaScript (PERFECT SERIES 4)