Chrome Remote Desktop Betaにより、ChromebookやChromeboxからWindows PCやMacにセキュアにアクセスできるようになった。この機能には動画コーデック「VP8」を採用しており、ほぼリアルタイムでリモートデスクトップを操作できるという。 — Google、Chrome OSアップデートでOfficeをサポート - ITmedia ニュース
Add-on SDKのsimple-prefsモジュールを使って簡易な設定画面を作ってみる。SDKのドキュメントは情報が少ないので、Add-ons Blogの記事も見るわかりやすい。
Just Landed: Simple Prefs API | Mozilla Add-ons Blog
http://blog.mozilla.org/addons/2011/12/08/just-landed-simple-prefs-api/simple-prefs-on SDK Documentation
https://addons.mozilla.org/en-US/developers/docs/sdk/latest/packages/addon-kit/simple-prefs.html設定画面の作り方は、package.jsonに設定項目の情報を書いておくだけ。アドオンの詳細画面に設定項目が追加される。
package.json
{ "id": "jid1-7wBt2LagLajA6Q", "name": "fx-addon-prefs-example", "fullName": "fx-addon-prefs-example", "author": "swdyh", "version": "0.0.1", "preferences": [{ "name": "somePreference", "title": "Some preference title", "description": "Some short description for the preference", "type": "string", "value": "this is the default string value" }] }
この設定画面で設定された値はユーザが変更するたびに自動でFirefoxに保存されるので、あとは設定が変更されたときの処理をイベントリスナーで書いておけば終わり。
main.js
var prefs = require('simple-prefs') exports.main = function() { prefs.on('stringPreference', function(name) { console.log('pref changed.', name, prefs.prefs[name]) }) }
integerやboolでも使い方はstringと同じ。boolはチェックボックスになる。
{ "type": "bool", "name": "boolPreference", "value": true, "title": "Boolean Pref" }, { "type": "integer", "name": "intPreference", "value": 42, "title": "Integer Pref" },
ドキュメントには今のところ、integer、bool、stringの3種類と書いてあるけれど、ソースを見るとさらにいくつかtypeが利用できそうだった。ファイルやディレクトリの選択、色の選択など。
VALID_PREF_TYPES = ['bool', 'boolint', 'integer', 'string', 'color', 'file', 'directory', 'control']https://github.com/mozilla/addon-sdk/blob/master/python-lib/cuddlefish/options_xul.py
それからcontrolというのは、ボタンが配置されるだけで、他のもののように設定値が保存されることはないけれど、そのボタンが押された時になにか処理を実行するということができる。
{ "type": "control", "name": "controlPreference", "label": "controlPref", "title": "Control Pref" }
ボタンが押されたときの処理を追加するのは、設定値の変更と同じようにイベントリスナーを追加しておけばいい。
main.js
var prefs = require('simple-prefs') exports.main = function() { prefs.on('controlPreference', function(name) { console.log('pressed controlPreference') }) }
simple-prefsという名前の通り、単純な設定であればこれを使うとすごく楽にできる。これでできない範囲のものは、自分でhtmlなりxulなりで書くことになると思う。AutoPagerizeはすでにHTMLで設定画面を作ってあったのとtextareaを使いたいので、controlを使ってそれを表示するボタンだけを設置することにした。
Null.ly: WebKit の Developer Tools の罠 -
ある日、JavaScript のデバッグをしてたらこの世のものとは思えない出力を見てしまった。
Object のプロパティが重複しているではないか。こんな事ありえない!としばらく頭を抱え込んでしまった。かなりハマったが、種明かしをしてしまうとこういうことだった。
表示上、スペースが丸められてしまったせいであたかもプロパティが重複しているように見えていたのだ。コイツには困らされた……。
久しぶりに Google Chrome Canary Build (21) で WebRTC しようと思ったら、
TypeError: Not an object.なんてのがスローされ古いコードが動かなくなってた。原因はここにそのものズバリ書かれていて、第一引数に文字列をとっていたのがオブジェクトに変わったためだった。
旧
navigator.webkitGetUserMedia('video, audio', onStream, onStreamFailed);新
navigator.webkitGetUserMedia({ video: true, audio: true }, onStream, onStreamFailed);新旧ともにサポートしたい場合は
try { navigator.webkitGetUserMedia({ video: true, audio: true }, onStream, onStreamFailed); } catch (e) { navigator.webkitGetUserMedia('video, audio', onStream, onStreamFailed); }のように例外をキャッチしたらフォールバックすればよし。
追記 (2012/05/28 1:21)
Kanasansoft の人からもっとカッコいい方法を教えて頂きました。
navigator.webkitGetUserMedia({ video: true , audio: true , toString: function() { return 'video, audio'; } }, onStream, onStreamFailed);
getUserMedia()内部で String にキャストしているんでしょうか。
もともと自分はtumblrで画像をreblogすることは少なかったのでTwitterに連携していた。画像の投稿はTwitterだと「画像」と表示されるだけなので見る人にとってノイズになりやすいからだ。それが引用も同様になってしまったので、tumblrのTwitter連携ははずした。Facebook連携は画像も引用もいい感じに表示してくれるのだが。 — ARTIFACT@ハテナ系 - [ネット]tumblrのTwitter連携の仕様が変わった
ネット環境にいると、自分がもともと正しいと思っている情報を選ぶ傾向が強まる。まるで自分の「こだま」を聞いているようなメディア環境、Echo Chamberとも言われる状況では、リアリティが偏りはじめる。同じ事実に対しても、情報をねじ曲げてしまう。ネットではリンクを辿っても異なる意見には接触できない、違う意見に接触しないリンク構造が実際に生まれているという。その結果、異なる意見に対して非寛容な態度が醸成され、民主主義が機能不全を起こしてしまう方向に向かっている。メディアは強力だとこれまで思われていたが、もともとの意見と一致するメディアだけを選ぶ傾向が強まることで、意見が変化しない方向でしか情報に接触しないようになると、結局、意見を変えるきっかけを与えていないことになる。
(via 【森山和道の「ヒトと機械の境界面」】 ネット時代の社会的リアリティ形成や、錯覚を数学で理解する試み ~国立情報学研究所オープンハウス2011)
「自分は反対陣営の主張もチェックしている!」と主張する人でも、その実やっているのは「相手の主張のうち反論可能な部分を探し、反論しやすいところに反論することによって自説に対する自信を強める」ことだったりするしな。
オーダードーナツのご紹介 「ん?これは」|フロレスタのイクミママのブログ
via Takashi Toyoshima - Google+ - 先日の特注ドーナツについて、ブログで紹介して頂きました。
0-9:
JavaScript UnitTest Patterns
ここでは以下の順番でSinonJSとJsTestDriverを使用したJavaScriptのUnitTest Patternsを紹介します。
初期化の遅延
UnitTestを行う場合、まずは初期化functionが自動的に実行されないようにしましょう。
初期化functionをこちらの任意のタイミングで実行できるようにすることにより事前に対象外のコードをstub化したり、必要なfunctionへspyを仕込んだ状態でfunctionを実行できるようになります。
UnitTestの場合のみ初期化を遅延する
一番簡単な方法はUnitTest実行時のみ条件分岐で初期化を止める方法です。
$(function () { if (window.sinon) { init(); } });この方法は簡単かつ確実にタイミングを制御できますが、元コードを変更する必要があるため後からテストを追加する場合に問題になる可能性があります。
addEventListener経由での設定
window.onloadやDOMContentLoaded経由で初期化を行なっている場合、window.onloadやdocument.addEventListenerをstub化します。
//元functionを保持 var _addEventListener = document.addEventListener; //stub化 sinon.stub(document, 'addEventListener'); //stubが呼び出されるので実行されない document.addEventListener('DOMContentLoaded', function () { }, false);window.onloadやdocument.addEventListener自体のテストが行いたい場合、clickイベントを強制的に発生させたい (fireEvent/createEventの使い方) - 主に言語とシステム開発に関して等を参考にして直接ブラウザのイベントを呼び出してください。
jQuery経由での設定
初期化にjQueryを使用する場合先にjQuery functionをstub化し、functionが引数の場合に呼び出しを行わないようにすることができます。
この方法は「sinon.js -> jQuery -> 以下の初期化コード -> テスト対象コード」の順番でコードを読み込むことで実現できます。
//元jQuery objectを保管 var _jQuery = jQuery; //jQuery, $の両方stub化する必要があるので注意 sinon.stub(window, 'jQuery', init_stub); sinon.stub(window, '$', init_stub); //jQueryのfunction propertyは自動で継承されるので、このfunctionは呼び出し時の動作のみ想定すればOK function init_stub (arg) { // functionの場合何もしない if (_jQuery.isFunction(arg)) { return; } return _jQuery.apply(this, arguments); }こうすることで$(function () {})経由で設定されたfunctionを自分の好きな段階で$.args[n][0]()から呼び出すことができます。
script要素内に書かれたコードのテスト
htmlに直接書かれたコードもhtmlを$.ajax等で文字列として取得後、正規表現で切り出してevalすることでテストできますが、この方法はあまり安全ではないためhtmlとJSを分離することを推奨します。
非同期実行の同期化
主なUnitTest Frameworkは非同期実行のテストをサポートしていますが、UnitTestを行う場合できる限り非同期コードを同期的に実行することを推奨します。
非同期実行コードがテストに含まれる場合テストが複雑になるだけでなく、テストが増えてきた際に非同期部分の実行時間がテストの実行時間を伸ばすことになります。
(同期テストのみであればテスト実行環境を高速化することでテスト時間を短縮できますが、必ず固定秒数かかるテストが複数あった場合、それが積み重なるとテスト時間が非常に長くなる上に短縮できなくなります)setTimeout、setIntervalの同期化
ShinonJSのuseFakeTimersを使うことではsetTimeout、setIntervalを同期化することができます。
//setTimeout、setIntervalのmock化 this.clock = sinon.useFakeTimers(); //mock化されたsetTimeoutの呼び出し(この段階では呼び出されない) setTimeout(function () { window.alert('ok'); }, 0); //100ms経過したものとする(100ms以内に実行されるfunctionのみ実行される) this.clock.tick(100);useFakeTimersはjsunitのjsUnitMockTimeout.jsを元にしているので興味ある方はソースを読むことをおすすめします。
(コメント込みで150行程度なので簡単に読めると思います)ただ、sinonのuseFakeTimersを使う場合、Date等も上書きされてしまうためUnitTest Frameworkが対応していない場合は注意してください。
(Mochaを使用している場合不具合が出ることがあるそうです)また、useFakeTimersを使用するとDateは常に0(1970-1-1 00:00:00)を返すようになります。
XHR
ShinonJSのuseFakeXMLHttpRequest、fakeServerを使うことでサーバアクセスをstub化することができます。
(ただ、jQuery等を使用している場合は$.ajaxをstub化してしまう方が簡単かもしれません)ちなみに、同期実行には出来ませんが、JsTestDriver等には擬似的にサーバの代わりをする機能もあるためそちらを使ってテストを行うことも可能です。
jsDeferred
もし内部でjsDeferredを使用している場合、初期化の段階で以下のコードを実行することでjsDeferredがsetTimeoutを使うようになります。
Deferred.next = Deferred.next_default;jsDeferredはブラウザによってより高速な非同期化のコードを使用しますが、上記コードを使うことによりuseFakeTimers経由で実行のタイミングを制御することができます。
html, cssのテスト
htmlの記述
テスト対象のコードがDOM上の要素を参照する場合、テスト環境でも同じようにDOM上に要素が必要な場合があります。
これに関してJsTestDriverではコード内に以下の様なコメントでhtml要素を記述することができます。
/*:DOC += <div>この要素はdocument.body直下に展開される</div> */ /*:DOC += <div> 改行も書けます </div> */ /*:DOC hoge = <div>この要素はthis.hogeで参照できる</div> */ /*:DOC fragment = <div>要素を並列に記述した場合</div><div>documentFragmentになるので注意</div> */この内容はコード上の任意の場所に記述でき、ブラウザに配信される前に記述された部分が該当要素を生成するJSに置き換えられます。
注意点として、+=で要素をdocument.body以下に展開する場合、「hoge = 」で変数に生成場合に比べてテストの実行時間が長くなる傾向にあります。
(ブラウザの処理コストがかかる)これに関して、jQuery等のライブラリを使用している場合、以下のようにセレクタを外部から書き換えられるようにすることで、テスト時には変数に生成された要素を使用することができます。
var selectors = { 'link' : 'a' }; $.fn.setLinkText = function () { $(selectors.link).html('hoge'); }; TestCase('test case', { 'test_link' : function () { /*:DOC link = <a></a>*/ selectors.link = this.link; $.fn.setLinkText(); assertEquals($(this.link).html(), 'hoge'); } });また、BusterJSにはtestbedという機能があり、テストに対してそれが実行されるhtmlを指定する機能があります。
htmlの参照
htmlのテストとは「要素が正しく生成されるか」というテストになりますが、htmlのテストはクロスブラウザでの安定した要素のシリアライズが難しいため、テスト結果の比較が難しいという問題があります。
これには以下の様な方法でテストを行うことで安定したテストを行うことができます。
- htmlを展開するmethodをstub化する
jQueryを使用している場合、jQuery.fn.htmlをstub化することでDOMに展開される前のhtmlを受け取る事ができます。
この方法により、htmlをDOMではなく文字列として扱えるため、クロスブラウザで安全にテストを行うことができます。- HTMLElementのmockを使用する
もしテスト対象のコードがstyle等の属性を設定している場合、以下のようなmockを使用することでテストを行うことができます。var elem = { 'style' : {} }; targetFunction(elem); assertEquals(elem.style.display, 'block');- selectorで数える
上記のような方法が取れない場合、最後は普通にDOM経由で参照して要素数を数えたり、属性値を比較することになります。css
cssのテストも上記「htmlの参照」と同じように「ライブラリをstub化する」、「mockを使用する」、「直接比較する」のいずれかを行うことで安定したテストを行うことができます。
また、jQuery等のライブラリはブラウザ毎に発生するCSS結果の誤差をまとめる機能もあるため、たとえテスト対象のコードでライブラリを使用していなくてもテスト環境のみクロスブラウザ用ライブラリを使用する方法もあります。
イベントのテスト
イベントのテストは大きく「ブラウザ環境のテスト(正しくイベントが呼ばれるか)」と「イベントコードのテスト(イベント内のコードが意図した動作を行うか)」に分けられます。
ブラウザ環境のテスト
ブラウザ環境のテストは「あるイベントを呼び出した時に正しくイベントが呼ばれるか」をテストするものです。
今回はアプリケーションのテストをメインに考えているので、ブラウザ環境自体のテストに関しては省略します。
イベントコードのテスト
HTMLElement等の要素にbindされたコードをテストする場合、bindを行うコードを呼び出す前にテスト用の要素を作成し、コードを呼び出した後にイベントを呼び出します。
通常のイベントに関しては呼び出しが同期でおこるので、テストの際に呼び出しのタイミングを考慮する必要はありません。
jQuery等のライブラリを使用しているのであれば要素を指定してイベントを発火する仕組みを使用するのが簡単です。
(ライブラリを使用していない場合はclickイベントを強制的に発生させたい (fireEvent/createEventの使い方) - 主に言語とシステム開発に関してを参照してください)function bindClick () { $('a').click(function () { console.log('ok'); }); } /*:DOC += <a></a>*/ sinon.stub(console, 'log'); bindClick(); $('a').click(); assertCalledOnce(console.log);もしjQuery等のライブラリを使用していない場合や、mouseover等で座標を取得している場合などは、イベントをエミュレートするよりイベントと処理を切り離してそれぞれテストするのがお勧めです。
function bindEvent () { $('a').mouseover(function (e) { setElement(e.pageX, e.pageY); }); } function setElement (X, Y) { console.log(X, Y); } /*:DOC += <a></a>*/ sinon.stub(window, 'setElement'); bindEvent(); $('a').mouseover(); assertCalledOnce(setElement); // .restoreでstubを元functionに戻すことができます setElement.restore(); sinon.stub(console, 'log'); setElement(1, 2); assertCalledOnce(console.log); //最初に呼ばれた(args[0])時のargumentsの比較 assertEquals(console.log.args[0], [1, 2]);その他問題になりうるコード
document.write
JsTestDriverを使う場合、テストはページリロード無しに実行されるためテスト対象のコードは基本的にDOMContentLoaded後に実行されます。
そのためdocument.writeを使うコードをテストする際は、事前にdocument.writeをstub化してテストを実行しましょう。
alert, confirm
コードの実行が止まってしまうためstub化しましょう。
location
location objectは上書き(stub化)できないため、これに直接依存するコードをテストする場合には問題になる可能性があります。
これに関しては安定した回避方法がないため、テスト対象のコードを書き換えることを推奨します。
(別のobject経由で操作するようにし、テスト実行時はそのobjectをstub化しましょう)
デバイスの連携をブラウザ技術として考えると、OSのが持っていたデバイス連携機能をいかにブラウザとして取り込むかが必要になる。だが、それが今日の状況で本当に最適なことかは議論の余地がある。マイクロソフトがWindowsのデバイスドライバを充実させるために、何をしたか考えると、それを再度、ブラウザで行うのが本当に良いかは考えたほうが良い。数バージョン前までは、Windowsにデバイスを接続するたびに、CDを要求されたりすることが多かったろう。運が悪いと、ブルースクリーンに泣かされることも多かったに違いない。現在では、単純なデバイスならばOSが装備する標準ドライバで事足りる*2し、クラッシュなどの最悪の自体に陥ることもほとんどない。これは、Windowsが数バージョンを経て、デバイスドライバの階層を整理したり、サードパーティと協力し、デバイスドライバの安定性に務めた結果だ。
これが実現できたのは、Windowsが共通プラットフォームとして位置づけられているからであるという側面も忘れてはいけない。
ブラウザで、さまざまな異なるデバイスの連携を図らなければいけないとしたらどうするのが良いか。1つは、マイクロソフトなり、OSベンダーが行ったのと同じことをブラウザで行うことだ。だが、それはブラウザという単体のコンポーネントを見ているに過ぎない。
もちろん、ブラウザでデバイスの直接サポートが必要なことも多くある。Gamepadがそうだし、WebCamなどもそうだ。レイテンシーが最重要視される部分では、ブラウザ自身が直接デバイスをサポートする必要がある。
だが、それ以外の場合、大きなクラウドアプリケーションの中でそのデバイスが接続されれば良い。すなわち、デバイスごとに直接ネット経由でクラウドアプリケーションに接続し、アプリケーションの構成要素になるという方法もでてくる。特に、疎結合されるような連携の場合には、このほうが柔軟性も高い。
— Webの未来とブラウザのこれからをデバイス連携から考えた - Nothing ventured, nothing gained.
Almunia副委員長はこれまでの調査で、市場支配の乱用と考えられる4つの懸念を確認したと説明している。1つはGoogleの一般検索からレストランやニュース、商品情報など自社独自の垂直型検索サービスへのリンクを設けていること。2つめは競合の垂直型検索サービス企業のWebサイトからコンテンツをコピーして自社サービスで使っていること。これらは競合企業のコンテンツ投資意欲を阻害しているとECは指摘している。
3つめの懸念事項として、検索サービスと検索連動広告を提供しているWebサイトとの契約条項を挙げている。これによりGoogleは、ほぼすべての検索広告をGoogleから取得するよう義務づけ、他社を締め出したとECは見ている。4つめは、Googleが「AdWords」の検索広告キャンペーンの他社プラットフォームへの持ち出しに制限を加えていることを問題視している。
— Google、罰金と制裁措置を回避できる可能性、欧州委員会が改善策の提示求める - ニュース:ITpro
Google Chrome で native code を実行するための仕組みである Native Client 上で Ruby を実行するためのパッチがコミットされました。
簡単に言えば、JavaScript の代わりに Ruby を使えるようになるようです。HotRuby や JRuby Applets に似ていますが、ネイティブで CRuby そのものがクライアント上で動くところが違います。
— Ruby 2.0 リリース週記 (2012/05/14 - 20) - まめめも
jxck:
Node.js v0.7 系から、 EventEmitter の変更が原因で、 Socket.IO が落ちるバグが発生しています。
具体的には Socket.IO@0.9.6(およびそれ以前) を node@0.7.8(及び 0.7.x 全般) で起動した後、ブラウザからアクセスしたら、下記のようなトレースを吐いて落ちます。
Jxck$ node server.js info - socket.io started /../gist-2292777/node_modules/socket.io/lib/manager.js:0 (function (exports, require, module, __filename, __dirname) { /*! ^ RangeError: Maximum call stack size exceeded上記を再現できるソースはこちら。なんでもないサーバ実装です。
https://gist.github.com/2292777
このバグの原因は、Node.js 本体の EventEmitter にあったこの修正です。
https://github.com/joyent/node/commit/78dc13fbf97e2e3003e6f3baacdd5ff60e8de3f7
これにより、Socket.IO サーバ内で無限ループな感じになって、スタックが食いちぎられます。
そして、対応する Socket.IO への修正はこちら。
https://github.com/LearnBoost/socket.io/commit/e1884859bcbb57daeb843421cc5b4b95bd914bd8
しかし、socket.io@0.9.6 リリースの直後にコミットされて、まだ socket.io@0.9.7 がリリースされていないため、
自分でリポジトリから直接 clone して使うか、 node@0.6 系で動かすしか方法が無いです。
おそらく、 socket.io@0.9.8 がリリースされれば治るとは思いますが、
node@0.7 系は unstable だということで、 node@0.6 系の stable の方を重視するような
意味合いのコメントがどっかにありました。そういわれればまあ仕方ないのですが、
とりあえずハマった方々バージョンを見なおしてみてください。
Pot.js の実装のうち Pot.Deferred.forEach などの
非同期/同期イテレータだけにした軽量タイプを PotPico.js として作ってみました。
サイズは約 50KB で、PotLite.js より軽くなりました。
単に CPU 負荷を抑えて JavaScript を実行したい時とか、
Pot.Deferred や Pot.js のイテレータがどんなものか触ってみるきっかけになれたらと思ってます。
サイズと実装は、Pot.js >>>>>> PotLite.js >>> PotPico.js (full) (非同期処理のみ) (イテレータとDeferredのみ)こんな感じです。
PotPico.js はイテレータに必要なものだけにして、 Minify 用に少し最適化した感じです。
なので Pot.js / PotLite.js とまったく同じに使えて、リファレンス も同じく参照できます。Download
Download zipzip package
potpico.min.js - Production (Minified)PotPico.js
Document and Reference
PotPico.js で利用できる関数/オブジェクトのリファレンス:
JSDoc
Closure Compiler でソースコードから自動生成したドキュメント。
Compatibility
PotPico.js は Pot.js と同じく以下の環境で動きます。
- Mozilla Firefox *
- Internet Explorer 6+
- Safari *
- Opera *
- Google Chrome *
以下の環境でも利用可能です。
- Greasemonkey (userscript)
- Mozilla Firefox Add-On (on XUL)
- Node.js
- Other non-browser environment
TestRun
以下のページで動作テストして確認できます。
License
Dual licensed under the MIT and GPL v2 licenses.
PotPico.js のページ
PotPico.js - JavaScript Async Library
PotPico.js は今のところレポジトリ (GitHub /master) に含まれてません。
PotLite.js もあるのに、これ以上そういうの増やすのもどうかと思って API サーバのほうに置いてます。
Pot.js より手軽でイイ! ていうことになったら master に含めようと思ってます (もし使ってくれる方がいたら…)。
もしくは、PotLite.js を PotPico.js として置き換えてもいいかも (WebWorker とかたぶん使われてない)。
Pot.js のほうの情報についてはリファレンス等から参照ください。レポジトリ
その他、なにか問題・バグ・感想・指摘などあれば、
コメントやメールまたは @polygon_planetまで送っていただけるとうれしいです。
Chromium と WebKit は二つの独立したプロジェクトだ。 ソースツリーはそれぞれ別で、そこにはインテグレーションの苦労がある。 WebKit 以外にも V8 や Skia など Chromium が依存している外部のプロジェクトは山ほどあるけれど, WebKit とは特にぴったりくっついている。 そのぶん二つの足並みをあわせる手間も際立つ。
以前、書籍 ”アジャイル開発の本質とスケールアップ” で リリーストレイン という大規模プロジェクトのインテグレーション手法を読んだ。 プロジェクトの内部で一段細かい時限リリースを設け、そのタイミングでインテグレーションする方法。 内部リリースにあわせてプロジェクト同士が依存している相手のバージョンを上げ、 壊れたところをなおすわけ。
Chromium と WebKit もこまめに相手のバージョンを新しくする。 主たる依存の向きは Chromium -> WebKit だから、 Chromium の依存する WebKit のバージョンアップは特に気を使う。 足並みをあわせる間隔はとても短い。 Chromium は一日に何度も WebKit のバージョンを上げている。 このこまめな同期によってビッグバンインテグレーションの不確定性から逃れている。 (なおリリーストレインと違い, Chromium の依存プロジェクトはそれぞれ勝手にバージョンをあげる。 依存関係のグラフが Chromium に集中しているので、 全体の足並みを揃えなくてもなんとかなるのだろう。)
— 炭坑の庭師 - steps to phantasien
0-9:
ざっくり以下のようなツールが関連する
CIサーバ系(Jenkins等)
何かのタイミングで自動的にテストを実行する場合に使用
「Swarm系」、「結合テスト系」を操作し、その結果を蓄積、報告する
結合テスト系
利点
- IDEを使えばテストの定義が簡単
- 実ブラウザでテストを実行するので検証が確実
- 標準で画面遷移も含めた結合テストをサポート
- htmlの切り出しが不要で実サービスを使ったテストが可能
- CIサーバとの連携が可能
欠点
- IDEを使ったテストは柔軟性に欠ける
- 実ブラウザを使うので起動が遅い
- 実ブラウザを使うので安定性に欠ける
- テストがUI(html, css)に依存する
- HeadLess系が使えない(多分)
- ブラウザのみでテストが完結しない
ある程度UIが安定しているサービスに対してのサーバも含めたブラックボックステストに向く
Swarm系
利点
- 実ブラウザでテストを実行するので検証が確実
- UnitTest系のものが使えるのでライブラリ単位のテストが可能
- CIサーバとの連携が可能
- htmlの埋め込みを使ったUIの検証が可能
- JSのキャッシュを使用した高速なテストが可能
- コマンドラインからテストの実行が可能
- スマートフォンでのテストが可能
- HeadLess系が使える
- (一部のものは)結合テスト的な動作も可能
- (一部のものは)コードカバレッジ取得可能
欠点
- 実ブラウザを使うので安定性にかける
- イベント関連のテストが弱い
- ブラウザのみでテストが完結しない
- 実行速度がブラウザ環境に依存する
TDD、UnitTestがメインだが、結合テストも可能
HeadLess Browser系
利点
- ブラウザの起動が無いので高速に実行できる
- 結合テスト的な動作も可能
- 実ブラウザでテストを実行するので検証が確実
- UnitTest系のものが使えるのでライブラリ単位のテストが可能
- CIサーバとの連携が可能
- コマンドラインからテストの実行が可能
- ブラウザのみでテストが完結する
- (一部のものは)サーバサイド環境と相性がいい
欠点
- テストできないブラウザがある
- イベント関連のテストが弱い
- (一部のものは)環境構築が大変
主にWebkit系でのTDD、UnitTestがメイン。スマートフォン環境、IE環境のテストはできない
JSエンジン系
利点
- ブラウザの起動が無いので高速に実行できる
- UnitTest系のものが使えるのでライブラリ単位のテストが可能
- CIサーバとの連携が可能
- コマンドラインからテストの実行が可能
- クライアントのみでテストが完結する
- サーバサイド環境と相性がいい
欠点
- 環境構築が大変
- テストできないブラウザがある
- DOM、イベント、ブラウザ関連のテストが弱い
- 結合テスト的な動作は別サポート
HeadLess系に近いが、純粋なJS環境なのでブラウザ関係のテストが難しい
UnitTest系
他言語環境でいうxUnit系にあたる。利点、欠点は一般的なxUnitに同じ
- 安定のQUnit
- 新進のJasmine
- 革新のMocha
mock系
基本的にSinonJSでカバーできる。UnitTest系よりむしろこちらの使い方のほうが重要