コマンドラインツールをpower-assertとcoffee-scriptでテスト

Node.js Advent Calendar 2014の10日目の記事として、node.jsのコマンドラインツールをpower-assertとcoffee-scriptによってテストする方法を紹介します。

はじめに

Power assertとはassertテスト失敗時の情報を分かりやすく表示できる機能のことで、nodeで利用できるライブラリとして@t_wadaさん作のpower-assertというものがあります。

東京Node学園祭2014にて@t_wadaさんのpower-assertの発表を聴き、アサーション戦争に終止符を打つ!という熱い思いに感銘を受け、自作のツールにも積極的にpower-assertを使いたいと思っています。

本記事ではnode.jsでの簡単なコマンドの実装とpower-assertを使ったテストをcoffee-scriptで書く方法について順を追って解説します。

事前準備

ツール作成の準備

始めにclitestディレクトリを作成し移動します

package.jsonの作成

各種パッケージを利用するために、npm initコマンドを実行しpackage.jsonを作成します。
コマンド実行時の質問にはツールの情報を適当に入力していきます。
テスト用ツールなのでEnter連打で適当に入力してもかまいません。

ツール用のライブラリ作成とテスト

テスト対象として文字列「hello!」を返却するライブラリ hello.js を実装し、テストを行います。

hello.jsを実装

hello.js

1-3行目で文字列”hello!”を返却する関数helloを定義しています。
5行目はこのjsファイルがインポートされた場合に関数helloにアクセスできるようにするための記述です。

hello.jsをテストしてみる

テストに必要なパッケージをインストール

テスト用に、mocha, power-assert, espower-coffeeパッケージをインストールしていきます。

始めにテストフレームワークのmochaをグローバルにインストール

次に、power-assertとcoffee-scriptでテストを実行するために必要なespower-coffeeをインストール

テスト用のcoffee-scriptを書く

coffee-scriptでテストを書きtestディレクトリに保存します。

test/libtest.coffee

1行目で先ほど作成したhello.jsをライブラリとして読み込みます。
2行目でpower-assertパッケージを読み込み。
4行目、6行目はテスト内容の説明。
7行目がテスト本体で、読み込んだhelloライブラリのhello関数の実行結果と文字列”hello!”を比較しています。

mochaを使ってテストしてみる

coffee-scriptで書いたテストをそのまま実行するために
–require ‘espower-coffee/guess’ オプションをつけてmochaでテストを実行します。

テストが成功しました。

テストを失敗させてみる

試しにテストを失敗させてみましよう。

libtest.coffeeの7行目の”hello!”を”world!”に変更して再度テストを実行してみます。

hello関数の出力に”world!”を期待しているのに、”hello!”が返ってくるためテストが失敗し、上記のようにテストがなぜ失敗したのかが詳細に出力されます。power-assertすごい!

ライブラリを読み込んで動作するコマンドラインツールの実装

先ほど作成したhello.jsは単体では動作しないライブラリでしたが、これを読み込んで動作するコマンドを実装します。

index.js

1行目でhello.jsをライブラリとして読み込み。
3行目でhello()関数の戻り値をコンソールに出力します。
このコマンドを実行するとコンソールに”hello!”と出力されるはずです。

コマンドを実行

期待どおり”hello!”がシェルに出力されました。

コマンド出力をテストするためのcoffee-scriptを書く

コマンド出力のテストを作成し、ライブラリのテストと同様にtestディレクトリに保存します。

clitest.js

1行目でpower-assertを読み込み。
2行目でテスト用にコマンドを実行するためのchild_process.execメソッドを読み込み。
4行目で実行するコマンドを定義。
6行目8行目はテスト内容の説明。
9行目でコマンドを実際に実行します。
また、テストスクリプト側ではコマンド実行の終了を待つ必要があるため、8行目と9行目でコールバックを記述しています。
10行目でコマンドの出力stdoutと文字列”hello!n”を比較しています。
(コンソール出力であるため末尾に改行文字が入ります※1)

index.jsをテストしてみる

テストが成功しました。

試しにテストを失敗させてみる

clitest.coffeeの10行目の”hello!”を”world!”に変更して再度テストしてみる。

コマンドの出力に”world!n”を期待しているのに、”hello!n”が返ってくるためテストが失敗し、なぜ失敗したのかが詳細に出力されます。やっぱりpower-assertすごい!※2

gulpでテストを自動化する

タスクランナーのgulpを使ってpower-assertを使ったテストを自動化します

gulpと関連パッケージのインストール

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

ローカル側gulpと関連パッケージをインストール

gulpfile.coffeeを作成

gulpfile.coffee

1行目と2行目でパッケージの読み込み。
4行目で自動テストのためのタスク”mocha”を定義。
5行目でcoffee-scriptでpower-assertするためのespower-coffee/guessを読み込み。
6行目7行目でtestディレクトリのcoffee-scriptを実行してテストを行う。

gulpでテストしてみる

libtest.coffeeとclitest.coffeeの両方のテストが実行されます。
試しにテストが失敗するようにテストスクリプトを修正してpower-assertのパワーを感じてみてください!
以降は、随時必要なテストを追加し、いつでもgulp mochaコマンドでテストを実施できます。

おわりに

node.jsで簡単なコマンドを実装し、ライブラリの関数出力およびコマンドライン出力を
power-assertとcoffee-scriptにてテストする方法を紹介しました。
(サンプルコードはknjcode/clitestに置いてあります)

さらなる発展として、複数行のコマンド出力のテストや配列比較のテスト方法、
さらにはTravis CIと連携した自動テスト手法等を紹介したいと考えていますが、
また、別途記事にしたいと思います。

明日のNode.js Advent Calendarchocopie116さんです。

補足

※1.コマンド出力の改行コードは環境により異なる場合があります。
※2.大事なことなので2回言いました。
また、東京Node学園祭にてt_wadaさんにpower-assertのコードを個別解説頂いた際、
鮮やかなEmacs操作に対して「それVimですか?」と聞いてしまったのは私です。大変失礼致しました。

参考

power-assertの使い方 Node.js編
Coffee-scriptでpower-assertを使ったテストを書く
twada / gulpfile.js
power-assert / mechanism and philosophy