js-test-driverの䜿い方メモ

js-test-driverはGoogleが䜜った、JavaScriptをコン゜ヌルでテストするプログラム。詊したのでメモを。環境はMountain Lion搭茉のMacBookAir。

ダりンロヌド
http://code.google.com/p/js-test-driver/downloads/list

䜿い方
http://code.google.com/p/js-test-driver/wiki/GettingStarted

参考になる日本語蚘事
http://0-9.tumblr.com/post/15614207218/js-jstestdriver
http://everyday-eachday.blogspot.jp/2011/12/jstestdriver.html

ダりンロヌドペヌゞで JsTestDriver-x.x.x.jar っおや぀を萜ずす。ダりンロヌドしたファむルを ~/bin/JsTestDriver.jar みたいなパスに眮く。コン゜ヌルから以䞋のコマンドでサヌバヌを起動。

$ java -jar ~/bin/JsTestDriver.jar --port 4224

ポヌト番号は適圓でいいらしい。コマンド成功したら、適圓なブラりザで http://localhost:4224/ を開く。そうするず

  • Capture This Browser
  • Capture This Browser in strict mode

っおテキストリンクが䞊んでる画面になるので奜きな方をクリック。普通は Capture This Browser でいいず思われそうするずそのブラりザをりォッチしおいるような状態になる。で、そのブラりザの゚ンゞンでテストが実行される。

実際にテストしたいプロゞェクトのディレクトリを䜜る。䟋えば以䞋のような構造にする。

|- jsTestDriver.conf
|- src
|--- hoge.js
|- test
|--- hoge_test.js

hoge.js が曞きたいJavaScript。hoge_test.js がhoge.jsに察するテストを曞くファむル。jsTestDriver.conf がjs-test-driverのためのファむル。テキスト゚ディタで開き、以䞋のように蚘述。

server: http://localhost:4224
load:
- src/*.js
- test/*.js

コン゜ヌルに戻る。さっきサヌバヌを起動したプロセスりィンドりはそのたたにしずいお、新しいプロセスを起動。そっちで

$ cd プロゞェクトのディレクトリぞ
$ java -jar ~/bin/JsTestDriver.jar --tests all

するずテストが走っお hoge_test.js に曞いたテスト結果が衚瀺される 予定なんだけど、この時点で hoge_test.js には䜕も曞いおないので゚ラヌになるはず。
ずいうわけで簡単なコヌドを曞いおみる。

### src/hoge.js function jsdriversample() { return true; }
### test/hoge_test.js TestCase(‘jsdriversampletest’, { ‘test should return true’: function () { var result = jsdriversample(); assertTrue(result); } });

で、コン゜ヌルでコマンドを叩いおテストする。

$ java -jar ~/bin/JsTestDriver.jar --tests all

ちなみにここで'test should return true'っおいうのは各テスト単䜍の名前で、゚ラヌ時にコン゜ヌルに出力される。ちなみに文字列だからっおマルチバむトは䜿えない。

assertなんちゃらっお関数でテストを実行しおるんだけど、䜿えるassertionの䞀芧は以䞋に茉っおる。
http://code.google.com/p/js-test-driver/wiki/Assertions
䟋えば assertTrue だったら、匕数の倀が true だったらテスト合栌になる。

ただちょっず䜿っおみただけなので、もうちょい勉匷しお実務に生かしたい。

### 2012-12-06 远蚘 テストケヌスのメ゜ッド名䞊蚘の䟋では 'test should return true' ずなっおいるずころは必ず**test**で始たらないず、認識されないようです。

Mobile Safari、フルスクリヌンモヌド、UIWebView、どれからのアクセスか刀別する

apple-mobile-web-app-capableずいうめmetaタグの倀をyesにするずiOS Safariでそのペヌゞを「ホヌム画面に远加」し、ホヌム画面からアクセスした際にペヌゞをフルスクリヌンモヌドで開くこずができる。

<meta name="apple-mobile-web-app-capable" content="yes" />

出兞Safari HTML Reference – Supported Meta Tags

フルスクリヌンモヌドで開いた堎合、navigator.userAgentの倀に「Safari」の文字列が珟れなくなる。

Moble SafariでのuserAgentiOS 5.1.1:

userAgent: Mozilla/5.0 (iPhone; CPU iPhone OS 5_1_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B206 Safari/7534.48.3 

フルスクリヌンモヌドでのuserAgentiOS 5.1.1

userAgent: Mozilla/5.0 (iPhone; CPU iPhone OS 5_1_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/9B206 

ずころで、FacebookアプリやTwitterアプリなど、投皿内容のURLを螏むず、そのアプリの䞭でWebペヌゞが展開されるものがある。UIWebViewずいうや぀。この堎合のuserAgentにも、やはり「Safari」の文字列は珟れない。

FacebookアプリのuserAgentiOS 5.1.1:

userAgent: Mozilla/5.0 (iPhone; CPU iPhone OS 5_1_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/9B206 [FBAN/FBIOS;FBAV/5.1;FBBV/68414;FBDV/iPhone4,1;FBMD/iPhone;FBSN/iPhone OS;FBSV/5.1.1;FBSS/2; FBCR/KDDI;FBID/phone;FBLC/ja_JP] 

TwitterアプリのuserAgentiOS 5.1.1:

userAgent: Mozilla/5.0 (iPhone; CPU iPhone OS 5_1_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/9B206 

ずいうわけでSafariずいう文字列があるかないかを頌りに、フルスクリヌンモヌド、ないしはUIWebViewからのアクセスを刀別しようずするず倱敗する。 しかし䞊蚘出兞のSafari HTML Referenceによるず、フルスクリヌンモヌドではwindow.navigator.standaloneずいうプロパティがtrueになるらしいので詊した。

デモ

iPhone/iPadのどちらでも、フルスクリヌンモヌドのみでwindow.navigator.standaloneがtrueになるのを確認できた。

userAgent文字列からiPhone/iPadであるこずを刀定した䞊で、

  • userAgentにSafariの文字列あり → Mobile Safari
  • userAgentにSafariの文字列なし、か぀window.navigator.standalone === true → フルスクリヌンモヌド
  • userAgentにSafariの文字列なし、か぀window.navigator.standalone === false → UIWebView

ずいう刀定をするこずができる。

GitHubを初めお䜿っおみた

ヘルプに曞いおある通りにやったらできた。本圓に、そのたんた。
Help.GitHub – Set Up Git
Help.GitHub – Create A Repo

Macでのやり方はこちら
Help.GitHub – Set Up Git

SSH keyを登録するずころがキモだが、コマンドたで党おちゃんずヘルプに曞いおあるので぀たずいたずころはなかった。拍子抜け。

最初に䜜っおみたレポゞトリがこれ。
seckie/jQuery.ui.vScroll – GitHub

今幎の春に䜜ったものだけど、今たた案件で䜿う必芁があっお匕っ匵り出したら無駄なずころがあったりしおちょっずいじるこずになった。案件の制䜜物は圓然䌚瀟のレポゞトリに眮くんだけど、これは個人的に䜜ったものだったりしたので、せっかくなのでGitHubに挑戊しおみた。

JavaScriptの倉数に぀いおの考察

最近、Code Complete第2版ずいう本を読んでいお、「倉数の䜿甚第10章」がずおも為になる内容だったので、䌚瀟のチヌムメンバヌに少しそのこずに぀いお話したら、JavaScriptに぀いお興味深い話をするこずができた。

第10章の内容に぀いお、議論の察象ずなった郚分を匕甚する。

10.3 倉数の初期化のガむドラむン

倉数は最初に䜿甚する堎所の近くで初期化する

リスト10-2: 悪い初期化Visual Basic
' すべおの倉数を宣蚀する
Dim accountIndex As Integer
Dim total As Double
Dim done As Boolean

' すべおの倉数を初期化する
acountIndex = 0;
total = 0.0
done = False
...

' accountIndexを䜿甚するコヌド
...

' totalを䜿甚するコヌド
...

' doneを䜿甚するコヌド
While Not done
...
…äž­ç•¥

リスト10-2の䟋では、done倉数を宣蚀した埌、done倉数を䜿甚するコヌドが実行されるたでに、done倉数が倉曎される可胜性がある。

…äž­ç•¥

もう1぀の問題は、すべおの初期化を1か所にたずめるず、done倉数は最埌の方でしか䜿甚されないにもかかわらず、すべおの倉数がルヌチン党䜓で䜿甚されるずいう印象を䞎えるこずだ。

…äž­ç•¥

これは、「関連する䜜業を1぀にたずめる」ずいう近接の法則の䞀䟋である。

なるほどなるほど。しかし僕は普段の業務でプログラミング蚀語らしきものはJavaScriptしか䜿わないので、JavaScriptに眮き換えお考えよう。

var accountIndex = 0,
    total = 0,
    done = false;
// accountIndexを䜿甚するコヌド
...

// totalを䜿甚するコヌド
...

// doneを䜿甚するコヌド
while(!done) {
    
}
...

これが本曞で「悪い䟋」ずされおいるコヌドをJavaScriptに眮き換えたコヌドだ。しかし関数の先頭で var hoge = 0, fuga = false; のようにしお倉数をたずめお宣蚀初期化するのはJavaScriptではよく芋られるコヌドだ。あのjQueryですらそのような蚘法を倚甚しおいる。
JavaScript: The Good Partsによるず

ほずんどの蚀語では、倉数は䞀般的に最初に利甚される堎所で定矩するのが最も良い方法だ。しかしこれは、ブロックスコヌプを持たないJavaScriptでは奜たしくない。すべおの倉数は、それぞれの関数の先頭で定矩したほうが良い。

ずある。そう、JavaScriptはブロックスコヌプを持たない{}でくくられた郚分限定の倉数スコヌプずいういわゆる倉態蚀語であり、倉数のスコヌプを生成するのは関数ブロックのみだ。それが理由で、倉数はたずめお関数の先頭で宣蚀するずいう蚘法がベストプラクティスずされおいる。

さおしかし、Code Complete第2版による「倉数は最初に䜿甚する堎所の近くで初期化する」ほうがよいずいう理屈の続きはこうだ。

10.4.1 倉数の参照はたずめお

倉数を参照しおから次に参照するたでのコヌドは、「脆匱性の窓」無防備な時間垯である。その窓では、新しいコヌドが远加されたり、䜕気なく倉数が倉曎されたり、倉数に含たれおいなければならない倀が忘れられおしたったりする。倉数の参照は、垞に近いずころにたずめお局所化するのが望たしい。

…äž­ç•¥

これを枬定する方法は、倉数の「持続間隔」を蚈算するこずである。

…äž­ç•¥
リスト10-6: 1ず0の持続間隔Java
a = 0;
b = 0;
c = 0;
b = a + 1;
b = b / c;

この堎合、bの1぀目の参照ず2぀目の参照の間にコヌドが1行あるので、その持続間隔は1である。bの2぀目の参照ず3぀目の参照の間にはコヌドがないので、その持続間隔は1である。bの2぀目の参照ず3぀目の参照の間にはコヌドがないので、その持続間隔は0である。

…äž­ç•¥

リスト10-6では、bの平均持続間隔は (1 + 0) / 2 = 0.5 である。倉数の参照を近くにたずめるず、コヌドの読み手がコヌドをセクションごずに読んでいけるようになる。

…äž­ç•¥

10.4.2 倉数の「寿呜」はできるだけ短く

倉数の持続間隔に関連しお、倉数の「寿呜」ずいう抂念がある。倉数の寿呜ずは、倉数が存続する期間内に存圚するステヌトメントの合蚈である。

…äž­ç•¥

倉数の持続間隔ずは異なり、倉数の寿呜は、最初に参照されおから最埌に参照されるたでの倉数の䜿甚回数を蚈算に入れない。倉数が最初に1行目で参照され、最埌に25行目で参照された堎合、倉数の寿呜は25ステヌトメントである。

…äž­ç•¥

倉数の持続間隔ず同様に、倉数の寿呜もできるだけ短くする、぀たりステヌトメントの数を少なくするこずが目暙ずなる。持続間隔ず同様に、ステヌトメントの数を少なくするず、脆匱性の窓が小さくなるずいう利点がある。

…äž­ç•¥

寿呜を短くするもう1぀の利点は、コヌドを正確に把握できるこずである。倉数に10行目で倀を代入し、45行目たで䜿甚しない堎合、2぀の参照の間に空いおいる空間は、倉数がその間に䜿甚されおいるこずを暗瀺する。

…äž­ç•¥

倉数の寿呜が短いず、コヌドが読みやすくなる。読み手が䞀床に頭に入れなければならないコヌドの行数が少なければ少ないほど、コヌドは理解しやすい。

倉数には「平均持続間隔」ず「寿呜」ずいう抂念があるずいう。そしおそれらが短くなった方がコヌドの読み手にずっお読みやすいコヌドになるずいう。

去幎、僕がずある案件で数千行に及ぶJavaScriptを曞いた際、最も頭を悩たせたのはコヌドを頭に入れるこずだった。機胜を远加・修正するために䞀床に頭に入れなければならないコヌドが倚すぎたため、開発が進めば進む皋、コヌドの修正は困難を極めた。

プログラミング初心者が誰しも䞀床はぶ぀かる壁なのかもしれない。コヌドの分割をはじめずする、コヌドの蚭蚈の重芁性を肌で感じた瞬間だった。
だからこそ、䞊蚘の「読み手が䞀床に頭に入れなければならないコヌドの行数が少なければ…」ずいうくだりに深く玍埗したのだった。

さお、ではJavaScriptにおいお「倉数の寿呜を短くする」こずず「関数の先頭ですべおの倉数を宣蚀する」こずは䞡立するのだろうかこれに぀いお隣垭の@keiskeyの意芋はこうだった。

関数1぀の長さ自䜓を短くしおしたうのがいいのでは。Google Closure Libraryのコヌドを芋おいるず、䞭身が2行しかないメ゜ッドに長々ずした名前が付いおいたりする。そんな長い名前を付けるんだったら盎接コヌドを曞いおしたえばいいやん、ず思うけど、「倉数の寿呜」のポリシヌをもっお曞かれおいるず考えるず合点がいく。

なるほど…ず再び玍埗するずずもに、「この話、共有しおよかった」ず思った。

䟋えば䞊述リスト10-2のコヌドを䞀぀の関数だず考えるずこうなる。

function Account() {
    var accountIndex = 0,
        total = 0,
        done = false;
    // accountIndexを䜿甚するコヌド
    ...

    // totalを䜿甚するコヌド
    ...

    // doneを䜿甚するコヌド
    while(!done) {
        
    }
    ...
}

この関数をクラス颚に曞き盎し、機胜分割するずこういう感じになる。

function Account() {
    // コンストラクタ
    ...
}
Account.prototype = {
    getAccountIndex: function() {
        var accountIndex = 0;
        // accountIndexを䜿甚するコヌド
        ...
        return accountIndex;
    },
    getTotal: function() {
        var total = 0;
        // totalを䜿甚するコヌド
        ...
        return total;
    },
    checkStatus: function() {
        var done = false;
        // doneを䜿甚するコヌド
        while(!done) {
            ...
        }
    }
}

prototypeにぶら䞋げたメ゜ッド1぀1぀を短くたずめお䞊手に機胜分割するこずが、限りなく正解に近いのではないかず思った次第。

僕はプログラマず呌ばれる職皮ではないのだけれど、プログラミングに関わる人間ずしお、こういった考察はずおもおもしろいず感じる。たた䜕か同じような話があったら曞いおいきたい。

JSONがinvalidでもjQuery.getJSON()ぱラヌを吐かない

蚘事のタむトルで蚀いたいこずは蚀い切っちゃおいるんですけれども。
jQuery 1.4.2 の $.getJSON() 、もしくは $.ajax() でリク゚ストしたJSONファむルがinvalidだった堎合、゚ラヌは吐きたせんがコヌルバック関数が実行されたせん。

[jQuery] getJSON callback not firing? – jQuery Forum

なんでinvalidなのかず調べたずころ・・・、JSONでは文字列は必ずダブルクォヌトで囲たないずいけないこずが刀りたした。シングルクォヌトではダメです。それからオブゞェクトリテラルの巊のオペランドにも、ダブルクォヌト省略䞍可あヌ、なんか初歩的なずころで぀たづいおいたす。

A string is a collection of zero or more Unicode characters, wrapped in double quotes, using backslash escapes.

http://json.org/

䜕しろ゚ラヌが出ないので、䜕が悪いのかわかりにくいです これで2時間はハマっおしたった・・・。。