testling-ciとtravis-ciでクライアントサイドもサーバサイドもテストを実行する
まえがき
NHK番組表APIのjavascript版を作りました。
NHKの番組表APIが発表されてて、皆思い思いに好きな言語で実装されていくのを見てました。
Golang : https://github.com/mattn/go-nhk
Scala : https://github.com/seratch/nhk4s
Perl : https://github.com/moznion/WWW-NHKProgram-API
Python : https://github.com/drillbits/nhk-api
Ruby : https://github.com/mitukiii/nhk_program-for-ruby
Emacs : https://github.com/gongo/emacs-nhk-program
Titanium : https://github.com/h5y1m141/TiNHKProgram
それのNode.js版ってよく見ると無いなと思ったんで作ったんですが、これは考えてみればbrowserifyでクライアントサイドでも使えるライブラリとして公開するチャンスだと思ってクライアントサイドjavascriptとしてもサーバーサイドのjavascriptとしても動作するハイブリッドのNHK番組表クライアントを作ってみました。
Node.js : https://github.com/yosuke-furukawa/nhk_api.js
npm : https://www.npmjs.org/package/nhk_api
bower : http://bower.io/search/?q=nhk_api
Getting Started
node.jsの場合
$ npm install nhk_api
browserから使う場合
$ bower install nhk_api
installしたらbowerをscriptで読めるようにする。
<!-- in browser --> <script src="components/nhk_api/client/nhk_api.js"></script>
使い方
var NHK = require("nhk_api"); // KEYを設定してください。 var nhk = new NHK("YOUR_API_KEY"); var callback = function(err, result) { console.log(JSON.stringify(result)); }; // nhk list api nhk.list.get("130", "g1", callback); nhk.list.get("東京", "NHK総合1", callback); nhk.list.get("東京", "NHK総合1", "tomorrow", callback); // nhk genre api nhk.genre.get("130", "g1", callback); nhk.genre.get("東京", "NHK総合1", callback); nhk.genre.get("東京", "NHK総合1", "tomorrow", callback); // nhk info api nhk.info.get("130", "g1", "123456789", callback); // nhk now on air api nhk.now.get("130", "g1", callback);
本題
さて、これは単に作ったというだけで本題はここからなんですが、Node.js版、というかサーバーサイドはtravisとかあって簡単にバージョンを跨いだテストが出来ますよね。
クライアントサイドの場合はどうでしょう。ブラウザ間のバージョンを跨いだテストを実施したいところです。せっかくbrowserifyを使ってサーバーサイドとクライアントサイド両方共同じ使い方で使えているので、testling-ciというサイトを使ってブラウザ間のテストを実行しましょう。
testling-ciでテストを実行すると以下の様なバッジが生成されて見れるようになります。
どのブラウザでサポートされているのか一目瞭然で分かりやすいですね。
ちょっと前にsubstackが公開していた記事があって、それを見るとやり方が書いてあります。ちょっと長いんですが最後までお付き合いをお願いします。
簡単にやり方を紹介していきます。
テストツールのインストール
以下のツールをインストールしておきます。
// phantomjs は必須、そうでなくても何らかのヘッドレスブラウザがないとtestlingが動かない $ brew install phantomjs $ npm install browserify tape testling -g
browserifyはサーバーサイドのコードをクライアントでも使えるようにしてくれるツールですね。
tapeはtapが喋れるテストライブラリです、mochaでもいいんですが、substackが最近issue全部クローズした!!って騒いでたので使ってみました。
no more open issues on tape! https://t.co/WgktE9XWxh
— James Halliday (@substack) March 5, 2014
まずはtapeを使ってテストを書いて、nodeのテストを実行します。
こんな感じのファイルをtestフォルダ以下に用意します。
var NHK = require('../index'); // tapeをrequire var test = require('tape'); // 時間用ライブラリを利用 var moment = require('moment-timezone'); // this apikey for test var apikey = process.env.NHK_API_KEY || "123456789"; // genreのurlがあっているかどうかテスト test(' genre url ', function (t) { var nhk = new NHK(apikey); var url = nhk.genre.createUrl("130", "g1", "0000"); var date = moment().tz("Asia/Tokyo").format("YYYY-MM-DD"); // nhkのgenre apiのurlと合致することを期待 var expected = "http://api.nhk.or.jp/v1/pg/genre/130/g1/0000/" + date + ".json?key=" + apikey; // t.equalで比較、第一引数が actual、第二引数が expected、第三引数がコメント t.equal(url, expected, "url is same"); // t.endでテストが終了される。 // t.endを呼ぶのは必須、非同期テストの場合はこっちのほうが嬉しい。 t.end(); //ちなむとt.planっていうメソッドがあって、それをcallすると指定回数のassetチェックが終わると自動でendされる仕組みになる。 // t.plan(1); }); test(' genre url to specify keyword ', function (t) { var nhk = new NHK(apikey); // 日本語でもgenre生成されるんですよ var url = nhk.genre.createUrl("東京", "NHK総合1", "0000"); var date = moment().tz("Asia/Tokyo").format("YYYY-MM-DD"); var expected = "http://api.nhk.or.jp/v1/pg/genre/130/g1/0000/" + date + ".json?key=" + apikey; t.equal(url, expected, "url is same"); t.end(); });
テストの実行は簡単で
$ tape test/genre.js
で実行できます。
TAP version 13
# genre url
ok 1 url is same
# genre url to specify keyword
ok 2 url is same
# genre url today
ok 3 url is today
# genre url tomorrow
ok 4 url is tomorrow
# get genre url
ok 5 error is not found
ok 6 msg is truthy
ok 7 msg.list is truthy
ok 8 msg.list.g1 is truthy1..8
# tests 8
# pass 8# ok
node-tapをインストールしているならtap
コマンドが使えるようになるので、以下の様な感じになります。
$ tap test/genre.js ok test/genre.js ........................................ 9/9 total ................................................... 9/9 ok
と、ここまでは普通のNode.jsのテストですね。
testlingを使ってbrowserのテストも実行する。
testlingとbrowserifyを使ってbrowser側のテストも実行しましょう。実行はすごく簡単。
$ browserify test/genre.js | testling TAP version 13 # genre url ok 1 url is same # genre url to specify keyword ok 2 url is same # genre url today ok 3 url is today # genre url tomorrow ok 4 url is tomorrow # get genre url ok 5 error is not found ok 6 msg is truthy ok 7 msg.list is truthy ok 8 msg.list.g1 is truthy 1..8 # tests 8 # pass 8 # ok
ってやるだけですね、これはすごく単純なことしかしてなくて、
- browserifyでtestコードをブラウザでも実行できるようにする
- testlingからphantomjsを呼び出してそのコードを実行する
ということをやっているだけです。
※phantomjsを入れる前にtestlingを既にインストールしていると、phantomjsを入れてもtestlingがphantomjsを認識してくれない事があります、この場合は ~/.config/browser-launcher/config.json
を一旦消してから再実行してみましょう。
coverageを取る場合
substackが作っているcoverifyっていうツールを使います。
$ browserify -t coverify test/*.js | testling | coverify ... # /Users/yosuke/Program/nhk-api/lib/base.js: line 53, column 9-28 console.error(data); ^^^^^^^^^^^^^^^^^^^^ # /Users/yosuke/Program/nhk-api/lib/base.js: line 54, column 9-25 console.error(e); ^^^^^^^^^^^^^^^^^ # /Users/yosuke/Program/nhk-api/lib/base.js: line 55, column 9-14 cb(e); ^^^^^^ # /Users/yosuke/Program/nhk-api/lib/base.js: line 59, column 5-10 cb(e); ^^^^^^ # coverage: 860/864 (99.53 %)
コレを使うと通っていないコードとテストのcoverageを取ってくれます。この場合は99.53%のカバレッジですね。
tapeとbrowserifyとtestlingでサーバーサイドもクライアントサイドも同じテストコードでテストできるようになりました。ついでにcoverify使うとカバレッジも計測できます。
CIツールで自動テスト
サーバサイドのCIツールはtravisがあるのでそれを使いましょう。以下のサイトが参考になります。
http://d.hatena.ne.jp/hokaccha/20111110/1320910718
クライアントサイドはCIツールとして、testling-ciを使います、これを使うための前準備として、package.jsonに以下のように記述します。
{ "name": "nhk_api", "version": "0.1.1", "description": "Node.js client for NHK API", "main": "index.js", "scripts": { "test": "tape test/*.js", "build": "browserify -g uglifyify -r ./index.js:nhk_api -o client/nhk_api.js" }, "keywords": [ "nhk", "api" ], "author": "yosuke furukawa", "license": "MIT", "dependencies": {}, "devDependencies": { "tape": "~2.10.2", "uglifyify": "~1.2.3", "browserify": "~3.32.0", "moment-timezone": "0.0.3" }, "testling": { "files": "test/*.js", "browsers": [ "ie/6..latest", "chrome/22..latest", "firefox/16..latest", "safari/latest", "opera/11.0..latest", "iphone/6", "ipad/6", "android-browser/latest" ] } }
こんな感じで、testlingプロパティを設定してください。ここにbrowserのどのバージョンをtestling-ciでテストするかを定義します。
設定したら、githubのwebhookページから、http://git.testling.com
へのhookを設定してください。
git pushを実行したら、以下のページで実行が確認できます。
https://ci.testling.com/$YOUR_USERNAME_HERE/$YOUR_REPOSITORY_NAME
実際の状況はこちら:https://ci.testling.com/yosuke-furukawa/nhk_api.js
バッジを見る
バッジはこんな感じで手に入ります。
https://ci.testling.com/$YOUR_USERNAME_HERE/$YOUR_REPOSITORY_NAME.png
実際のコード
markdownに貼るならこちら
[
](https://ci.testling.com/$YOUR_USERNAME_HERE/$YOUR_REPOSITORY_NAME)