power-assertでJavaScriptのテストをする ブラウザ編
power-assert
power-assertという単純なアサーションでも、テストが失敗した時に分かりやすい情報を出せるテストライブラリ/ツールについての記事です。
前回、power-assertの使い方 Node.js編 | Web scratchではpower-assertの動作やNode.jsプロジェクトでの簡単な導入方法について解説しました。
前回のpower-assert + gulpで紹介したプロジェクトをそのまま使っていくので、見ていない場合はそちらから見ていたほうがいいかと思います。
今回は、ブラウザでのpower-assertの動かし方とデバッグについて書いていきたいと思います。
今回扱う実行環境
- Node.js <= 前回
- ブラウザ
- Browserify
前回やったこと
まずは前回紹介したgulp + power-assertのプロジェクトを元にやっていきます。
どんな事をやったかを簡単にまとめてみます。
必要なモジュールのインストール
$ npm install --save-dev power-assert gulp gulp-espower
$ npm install -g gulp
テストコードをpower-assert化、mochaでテストを実行するgulpfile.jsのタスクを書きました。
そして、gulp test
とするとNode.jsでのテストが動くところまでやりました。
$ gulp test
今回は、これにtestemを使ってブラウザでも同じpower-assertを使ったテストが動くようにしたいと思います。
Testemを使ったブラウザ対応
ブラウザでpower-assertを実行するには、次のようなものが必要です。
- power-assert化したテストコード(これは既にありますね)
- test runnerとなるHTMLページ
- HTMLページで読み込むブラウザ向けの
power-assert
の関連ライブラリ- Node.jsの場合は
require("power-assert");
で済みますがブラウザは自分で依存関係を解決する必要があります。
- Node.jsの場合は
素でHTMLページを作り、変換したコード等を読み込んで実行するのでもよいのですが、
その辺はKarmaやtestem等を使って出来ると思うので、今回はtestemを使ってやってみたいと思います。
そのため、方針としては次のようになります。
ブラウザ向けの0.10.2でnpmにもブラウザ向けのファイルが含まれるようになったのでBowerは不要ですpower-assert
ライブラリをbower install
testem.json
でブラウザでmocha + power-assertで実行出来る環境を作る
完成したサンプルプロジェクトは以下に置いてあります。
追記: 0.10.2からはnpmのみで完結するのでBowerは不要になりました。
次にTestemをインストールしてない場合はインストールしておきましょう
npm install testem -g
Test runnerとなるHTMLページは、testemが内蔵しているため気にする必要はありません。
しかし、<script>
タグで必要なアサーションライブラリやpower-asssert
等を読み込む必要があります。(require("power-assert");
の代わりですね)
その読み込みを、testemの設定ファイルであるtestem.json
に定義します。
{
"framework": "mocha",
"before_tests": "gulp power-assert",
"on_exit": "rm -rf ./powered-test/",
"src_files": [
"./test/*.js"
],
"serve_files": [
"./node_modules/power-assert/build/power-assert.js",
"./powered-test/*.js"
]
}
設定ファイルの内容を簡単に紹介します。
"src_files"
は監視対象のファイルです- ファイルが変更されたらテストが実行されます
"before_tests"
はテスト実行前に行う処理ですgulp power-assert
でpower-assert化しています
"on_exit"
はtestemが終了した時のクリーンアップ処理です"serve_files"
はHTMLページで読み込むファイルです- ブラウザで読み込まれるファイルはここに記述します
ブラウザで読み込むべきpower-assertのライブラリ関係はusing grunt-espowerの部分にも書いてあります。
追記 : power-assert 0.7.2から、依存するライブラリをまとめたbuild/power-assert.js
を読み込むだけでよくなりました。
これに加えて、power-assert化したテストファイル("./powered-test/*.js"
)を読み込みます。
これでブラウザでのテスト準備は完了です。
Testemの実行
設定が面倒くさい分実行は簡単でtestem
とすると、ブラウザを受付状態になるので、後はテストしたいブラウザでアクセスするだけです。
$ testem
以下のような感じでテストが出来ます。
Testemの中ではmochaでテストが実行されてるので、基本はあまり変わらないと思います。
power-assert化したコードはsourcemapに対応しているため、
デバッガー等を使ってデバッグも普通に行えます。
- azu/power-assert-testem-seed
- testemで任意のHTMLでテストを動かす方法とJavaScriptデバッガ連携 | Web scratch
- Testem + WebStormのデバッグの参考
ハイブリッドテスト
最初に書いたテストコードではrequire
を使ってpower-assertを読み込んでいたので、そのままでは実行時エラーになります。
Node.js環境なら読み込むようにして、ブラウザでは既にglobalで読み込まれているので読み込まないようにすることが出来ます。
if (typeof require == "function" && typeof module == "object") {
var assert = require("power-assert");
}
これで、Node.js と ブラウザ どちらでも動くテストが書けるようになりました。
先ほどのプロジェクトもNode.jsとブラウザを同時にテスト出来るようにしています。
注記: ブラウザだけがテスト対象なら、上記のrequire
そのものを削除しても問題ありません。(というか削除すべき)
また、global.assert = require("power-assert");
と定義したものを別のhelperファイルで読み込む等もありでしょう。
Task Runner + Test Runner を使って何とかブラウザでも実行出来るようになりましたが、
上のハイブリッドテストを見て「Nodeで書いたコードをBrowserifyで変換してブラウザで実行すればいいのでは?」と思った方もいると思います。
そういう需要にもpower-assertは対応していて、espowerifyを使うことで出来ます。
espowerifyはその名前の通り、browserifyの変換時にpower-assert化を行えるbrowserifyの変換モジュールです。
browserifyとはNode.jsのコードをブラウザで実行出来るように変換するツールで詳しくは下記を参照して下さい
Browserify
espowerifyはBroserifyの変換モジュールとして扱います。
使い方は単純で browserify -t espowerify
のように変換モジュールとして指定するだけで、
browserifyによるnode.jsのコードの変換 + power-assert化を行ってくれます。
この方法のメリットは
- Node.jsとブラウザで同じテストコードが共有できる
- 一つのファイルにまとまるため、読み込むファイルの順番などを気にしなくてよい
- power-asert化も行えるので、他のビルドツール(gulpとか)などは必要としない
- ソースマップも対応してるのでデバッグできる
デメリットとして、browserifyの変換も入るため変換にかかる時間が増える事があげられます。
先ほどのプロジェクトでやったような依存するライブラリの読み込み等は、
変換して1つになったJavaScriptをtest runnerとなるHTMLページで読み込むだけで良くなるので単純です。
今度はKarmaを使ってブラウザテストしてみましょう。
Karma + Browserify
Testemでも出来なくはないですが、karmaにはプリプロセッサという機能があります。
この機能ではプラグインを追加することで、テストを行う前に処理をすることが出来ます。(testemの"before_tests"
をより柔軟にできる感じですね)
karma-coffee-preprocessorでcoffeescriptをコンパイルする等色々とプラグインがあります。
そのプリプロセッサで先ほどのbrowserifyによる変換も行う事が出来ます。(これがKarmaを選んだ理由です)
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の説明を見ると良いです。
実際のkarma.confの設定はazu/power-assert-karma-seedを参照して下さい
frameworks: ["mocha", "browserify"],
files: [
],
browserify: {
debug: true,
files: [
"test/**/*.js"
],
transform: [
"espowerify"
]
},
preprocessors: {
"/**/*.browserify": "browserify"
},
本来はfiles
でテスト時に読み込むファイルを指定しますが、今回テストしたいファイルはプリプロセッサでbrowserifyしたファイルになります。
そのため、files
は空でよくて、代わりにbrowserify
というプロパティのfiles
にテストしたいファイルを指定しています。
"frameworks"
に"browserify"
を入れるbrowserify
の設定をするbrowserify
の"transform"
に"espowerify"
を指定する
preprocessors
を設定する(これは常に同じ)
という感じでKarmaの設定は終わりです。
この状態で、karma start
+ ブラウザでキャプチャ または karma start --browsers Chrome --single-run"
という感じでテストを実行すると以下のような事をしてくれます。
test/**/*.js
以下のファイルをそれぞれ power-assert化 + browserify化- キャプチャしてるブラウザで変換されたテストファイルを読み込んでテストを実行
Karmaのテストサイクルの中で変換、テストの実行をしてくれるので、
見た目的には一時ファイルが必要なくなったり、karma.conf.jsという設定ファイル一つだけ良くなるのがメリットかもしれません。
こちらもsourcemapに対応してるので、ブレークポイントを貼ったデバッグも可能です。
上記でやってるのは、karma start
でサーバを立ち上げて、ブレークポイントを貼って、http://localhost:9876/debug.html
に対してChromeでアクセスしてデバッグという感じです。(KarmaのConfigurationをDebug実行だと上手くできない?)
(WebStormでの)Karmaのデバッグ実行は少し特殊な感じなので下記を参照して下さい。
デバッグ
さきほどからsourcemapによるデバッグが可能 ということが書いてありますが、
sourcemapとは何かが気になる人は下記などを見るといいでしょう。
- Source Mapについて | mixiページ
- Debugging JavaScript – Chrome DevTools — Google Developers
- Chrome DevToolsでの利用法
- デバッガ – 開発ツール | MDN
- Firefox DevToolsでの利用法
- Introduction to JavaScript Source Maps – HTML5 Rocks
- 開発者ツールでの利用法、内部構造
- #JSオジサンで Source Map について話してきました : document
- sourcemapファイルの構造について。
- どちらかというとツールを作る人向け
簡単に言うと変換したコード(power-assert化したテストコード)と元のコードの関係をマッピングしたファイルがあることにより、通常のJavaScriptのようにデバッグが可能になる感じです。
現在のブラウザに載ってる開発者ツールやWebStorm等のIDEやエディタでも対応してるものが多いため、デバッグ時にかなり有用になると思います。
こうしたsourcemapの対応が比較的に簡単にできるのもJavaScript ASTをベースとしたツールの特徴でもあるかもしれません。
まとめ
この記事では、以下の事について解説しました。
- power-assertをブラウザで動かすのに必要なもの
- Testem + gulp でのブラウザテスト対応
- Karma + browserifyでのブラウザテスト
power-assertの使い方 Node.js編に比べると、Mocha以外にもtest runnerが必要だったり(両方共内部的にMochaを利用してます)、設定が必要だったりしますが、
power-assert化したテストファイルも問題なくブラウザで動かすことができました。
また、sourcemapにも対応しているのでデバッグも問題なくできることがわかりました。
どんなテストライブラリ(アサーション)を使うか迷ってる人は、一度 power-assert を試してみるのも楽しいと思います。
より良きJavaScriptテストを!
お知らせ欄
JavaScript Primerの書籍版がAmazonで購入できます。
JavaScriptに関する最新情報は週一でJSer.infoを更新しています。
GitHub Sponsorsでの支援を募集しています。