Skip to content

Instantly share code, notes, and snippets.

@azu
Last active August 29, 2015 13:58
Show Gist options
  • Save azu/c837cb79a848d3d73c04 to your computer and use it in GitHub Desktop.
Save azu/c837cb79a848d3d73c04 to your computer and use it in GitHub Desktop.
記事にしました => http://efcl.info/2014/0406/res3809/

Power Assertとはassert(a === b); のような単純なアサーションでも、 Assert失敗時(テストが通らなかった時)に分かりやすい情報を表示できるようにする機能の事を言います。

Power assert

JasmineChaiが持つshouldexpect等言った豊富なアサーションを覚える必要なく、 シンプルにassertを使うだけでも十分な失敗時の情報が得られるため、沢山のアサーションを使い分けしなくていいというメリットがあります。

実際に書くことはrequire('power-assert'); 以外は殆どassertモジュールを使った場合と同じ事がわかります。

var assert = require('power-assert');

describe('Array', function(){ beforeEach(function(){ this.ary = [1,2,3]; }); describe('#indexOf()', function(){ it('should return index when the value is present', function(){ var zero = 0, two = 2; assert(this.ary.indexOf(zero) === two); }); }); });

この記事ではPower AssertのJavaScript実装であるtwada/power-assertの使い方について紹介します。

power-assert の役割について簡単に解説します。

power-assertはchai等のようなアサーションのライブラリというわけではなく、コードの変換や失敗時の出力等がまとまったツールに近い位置のものです。

簡単に流れを見ると以下のような事をします。 (この流れは自動化できるので単純に実行時に全部やってるわけじゃないということがわかればいいと思います)

  1. テストコードをpower-assert用に変換したコードを生成します
  2. power-assert化されたテストコードを実行します
  3. テストが失敗してる時は、ロードしてるpower-assertモジュールが整形してエラー情報を出力します

1 でテストコードを変換する事で、3でテストが失敗した時に詳細な情報が出力出来るように書き換えたテストコードを作成しています。

2 で実行する際に使われる assert() といったアサーションは、Node.jsのAssert等をそのまま使うようになっています。

詳しくは下記を見るといいと思います

使い方

本題のpower-assertの使い方について実行環境別に紹介します。

gif

実行環境

  • Node.jsh
  • ブラウザ
  • ハイブリッド(ブラウザ/Node.js)
  • Browserify

それぞれ実行するまでの設定をしていくので、必要な部分だけ見ていくといいでしょう。

twada/power-assert - HOW TO USE にも使い方が書いてあるためそちらも参照して下さい。


Node.js

使い方の前にで紹介したように、power-assertは変換と実行の2つフェーズがあります。

変換のフェーズはgulp-espowergrunt-espowerというタスクが用意されているので、これを使うのが簡単でしょう。

power-assertはアサーション周りについてのみ扱うので、describe() や Qunitのtest() といった部分に何を使うかというのは特に制限はありません。

基本的にはMochaで実行するのが一番相性がよいため、Test RunnerはMochaを使っていきます。

Mocha + Grunt は下記にかかれているので、 Mocha + Gulpでやってみたいと思います。

power-assert+gulpのサンプルプロジェクト

サンプルプロジェクトは以下に置いてあります。

まずは、必要なモジュールをインストールします

npm install --save-dev power-assert gulp gulp-espower testem

次にgulpの設定ファイルであるgulpfile.jsを書きます。

gulpのtaskでは次の2つを定義しています。

  1. power-assert化されたテストコードに変換する "power-assert" タスク
  2. 変換されたテストコードをmochaで実行する "test" タスク

2の "test" タスクを行う前に、自動的に変換しておいて欲しいのでgulp.taskの依存関係も定義しておくと、 gulpfile.jsは以下のように書けると思います。

"use strict";
var gulp = require("gulp");
var espower = require("gulp-espower");
var mocha = require("gulp-mocha");
var paths = {
    test: "./test/*.js",
    powered_test: "./powered-test/*.js",
    powered_test_dist: "./powered-test/"
};
gulp.task("power-assert", function () {
    return gulp.src(paths.test)
        .pipe(espower())
        .pipe(gulp.dest(paths.powered_test_dist));
});
gulp.task("test", ["power-assert"], function () {
    gulp.src(paths.powered_test)
        .pipe(mocha());
});

これでnodeで実行出来る環境が出来ました。

test/ 以下にテストを書いていって、テストを実行したい時は以下のようにコマンドを叩くと実行結果が出力されるようになります。

gulp test

次は、これをブラウザでも実行出来るようにしたいと思います。

ブラウザ

ブラウザで実行するには、power-assert化したテストコード(これは既にありますね)と、ブラウザ向けのpower-asserのアサーションライブラリ、test runnerとなるhtmlページ が必要となります。

素でHTMLページを作って変換したコード等を読み込んで実行するのでもいいですが、 その辺はKarmatestem等を使って出来ると思うので、今回はtestemを使ってやってみたいと思います。

方針としては次のようになります。

  1. ブラウザ向けpower-asserライブラリをbower install
  2. testem.json でブラウザでmocha + power-assertで実行出来る環境を作る

ブラウザ向けpower-asserBowerを使うことで簡単にインストールできます。

bower init
bower install power-assert --save

で1のインストールが完了です。

Test runnerとなるhtmlページは、testemが内蔵しているため気にする必要はありませんが、 ブラウザで実行するために<script>タグで必要なアサーションライブラリやpower-asssert等を読み込む必要があります。

その読み込みを、testemの設定ファイルであるtestem.jsonに定義します。

{
    "framework": "mocha",
    "src_files": [    
        "./bower_components/assert/assert.js",
        "./bower_components/empower/lib/empower.js",
        "./bower_components/power-assert-formatter/lib/power-assert-formatter.js",
        "./bower_components/power-assert/lib/power-assert.js",
        "./powered-test/*.js"
    ]
}

ブラウザで読み込むべきJavaScriptファイルはusing grunt-espowerの部分にも書いてありますが、 Bowerでインストールしたpower-assertの関連ファイルを読み込み、その後にpower-assert化したテストファイルを読み込む用に定義しています。

これでブラウザでpower-assert化したテストを実行準備は完了です。

testemの実行

実行の前に、テストを書き換えた時にpower-assert化の変換をgulp power-assertで行うのは面倒なので、gulpfileにテストファイルの変更を監視して変換を行うgulp watch-power-assertを追加しました。

実行する時は、以下のようになります

gulp watch-power-assert # 1. テストファイルのpower-assert化
testem # 実行したいブラウザで開く

Power mov

やっている流れとしては以下のような事をやっています(遠いですね…)

testem と gulp watchを起動 -> テストコードのpower-assert化変換 -> testemが変換コードの更新検知 -> testemがテストを実行する

ハイブリッドテスト

最初に書いたテストコードではrequireを使ってpower-assertを読み込んでいたので、そのままでは実行時エラーになります。

Node.js環境なら読み込むようにして、ブラウザでは既にglobalで読み込まれているので読み込まないようにすることが出来ます。

if (typeof require == "function" && typeof module == "object") {
    var assert = require('power-assert');
}

これで、Node.js と ブラウザ どちらでも動くテストが書けるようになりました。


Task Runner + Test Runner を使って何とかブラウザでも実行出来るようになりましたが、 上のハイブリッドテストを見て「Nodeで書いたコードをブラウザで実行すればいいのでは」と思った方にはespowerifyを使うことでもっと楽に出来ます。

espowerifyはその名前の通り、browserifyの変換時にpower-assert化を行うモジュールです。

browserifyとはNode.jsのコードをブラウザで実行出来るように変換するツールで詳しくは下記を参照して下さい

Browserify

espowerifyはBroserifyの変換モジュールとして扱います。

使い方は単純で browserify -t espowerify のように変換モジュールとして指定するだけで、 browserifyによるnode.jsのコードの変換 + power-assert化を行ってくれます。

この方法のメリットは

  • Node.jsとブラウザで同じテストコードが共有できる
  • 一つのファイルにまとまるため、読み込むファイルの順番などをきにしくなくていい
  • power-asert化も行えるので、他のビルドツールなどは必要としない
  • 2014年4月2日現在ではソースマップが対応されてるのでデバッガーが使いやすい

デメリットとして、browserifyの変換も入るため変換にかかる時間が増える事があげられます。

後は、変換してまとまったJavaScriptをtest runnerとなるhtmlページで読みこめばテストが出来ますが、今回はKarmaを使ってテストしてみましょう。

azu/power-assert-karma-seed

karmaにはプリプロセッサという機能があり、 この機能ではプラグインでcoffeescriptのコンパイルなどの処理を行う事が出来ます。

そのプリプロセッサで先ほどのbrowserifyによる変換を行う事が出来ます。

browserifyを扱う事が出来るプリプロセッサとしてkarma-browserifastを使います。

Karmaを使ったプロジェクト設定

まずは必要なものをインストールします(数が多いのでpackage.jsonを見るといいです)

npm install -g karma-cli
npm install --save-dev espowerify karma karma-browserifast browserify mocha

必要なモジュールをインストールしたら、Karmaのセットアップを行います。

詳しいKarmaの使い方はKarma - Configuration等を見ましょう

karma init # mochaを選択する

次に、browserifyの設定を行います。

詳しくはkarma-browserifastの説明を見ると良いのですが、本来はfilesでテスト時に読み込むファイルを指定しますが、今回テストしたいファイルはプリプロセッサでbrowserifyしたファイルになります。

そのため、files は空でよくて代わりにbrowserifyというプロパティにテストしたいファイルを指定しています。

  • frameworksbrowserify を入れる
  • browserify の設定をする
  • browserifytransform"espowerify" を指定する
  • preprocessors を設定する(これは常に同じ)
frameworks: ['mocha', "browserify"],
files: [
],
browserify: {
    debug: true,
    files: [
        "test/**/*.js"
    ],
    transform: [
        "espowerify"
    ]
},
preprocessors: {
    "/**/*.browserify": "browserify"
},

という感じでKarmaの設定は終わりです。

この状態で、karma start + ブラウザでキャプチャ または karma start --browsers Chrome --single-run"という感じでテストを実行すると以下のような事をしてくれます。

  • test/**/*.js 以下のファイルをそれぞれ power-assert化 + browserify化
  • キャプチャしてるブラウザで変換されたテストファイルを読み込んでテストを実行

Karmaのテストサイクルの中で変換、テストの実行をしてくれるので、 見た目的には一時ファイルが必要なくなったり、karma.conf.jsという設定ファイル一つだけ良くなるのがメリットかもしれません。

karma+browserify

SourceMapがあるためブレークポイントを貼ったりデバッグがしやすいです。 (他の方法でもpower-assert化するときにsourcemapを作成すれば対応できそう)


Node.js専用

power-assert はNode.js環境で動かすのが一番簡単です。

Mochaには--requireというテスト実行にnode moduleを読み込む仕組みがあります。

この読み込むモジュールにespower-loaderを使う事で簡単にpower assertを導入できます。

espower-loaderの説明を読むと、enable-power-assert.js 設定ファイルが必要になりますが、毎回書くことは同じなので、intelli-espower-loaderを使うと余計な設定ファイルなしに利用できます。

intelli-espower-loader では設定をnpmのpackage.jsonに持たせることで設定ファイルをなくしています。

そもそも何を設定する必要があるかというと、テストファイルがどこにあるかという事を指定する必要があります。

power-assertを使いたいプロジェクトにintelli-espower-loaderをインストールします。

npm install power-assert intelli-espower-loader --save-dev

package.jsonに"directories"という項目を追加して、"test" の値にテストディレクトリを指定します。(そのディレクトリ以下にあるファイルがpower assert化の対象になります)

"directories": {
    "test": "test/"
}

後は、mochaで実行するときに--requireでintelli-espower-loaderを指定するだけです。

mocha --require intelli-espower-loader

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment