JavaScript で UI を開発する際に、TDD の原則に正しく従う最善の方法を見つけようとして、私は多くの苦労をしました。これについて最善の方法は何ですか?
ビジュアルを機能から分離するのが最善ですか? 最初にビジュアル要素を開発してから、テストを作成してから機能のコードを作成しますか?
JavaScript で UI を開発する際に、TDD の原則に正しく従う最善の方法を見つけようとして、私は多くの苦労をしました。これについて最善の方法は何ですか?
ビジュアルを機能から分離するのが最善ですか? 最初にビジュアル要素を開発してから、テストを作成してから機能のコードを作成しますか?
過去に Javascript を使用して TDD を実行したことがあり、ユニット テストと統合テストを区別する必要がありました。Selenium は、サーバーからの出力、ポストバック、ajax 呼び出しなど、すべてを使用してサイト全体をテストします。しかし、単体テストでは、そのどれも重要ではありません。
必要なのは、操作する UI とスクリプトだけです。これに使用するツールは、基本的にJsUnit です。これは HTML ドキュメントを取得し、ページ上にいくつかの Javascript 関数を配置して、ページのコンテキストでそれらを実行します。したがって、関数を含むページにスタブ化された HTML を含めることになります。そこから、モック化された HTML、スクリプト、およびテストの分離されたユニットで、スクリプトと UI コンポーネントとの相互作用をテストできます。
少し混乱するかもしれないので、ちょっとしたテストができるか見てみましょう。コンポーネントがロードされた後、要素のリストが LI の内容に基づいて色付けされると想定する TDD を考えてみましょう。
tests.html
<html>
<head>
<script src="jsunit.js"></script>
<script src="mootools.js"></script>
<script src="yourcontrol.js"></script>
</head>
<body>
<ul id="mockList">
<li>red</li>
<li>green</li>
</ul>
</body>
<script>
function testListColor() {
assertNotEqual( $$("#mockList li")[0].getStyle("background-color", "red") );
var colorInst = new ColorCtrl( "mockList" );
assertEqual( $$("#mockList li")[0].getStyle("background-color", "red") );
}
</script>
</html>
明らかに、TDD は複数ステップのプロセスであるため、制御のために複数の例が必要になります。
yourcontrol.js (ステップ 1)
function ColorCtrl( id ) {
/* Fail! */
}
yourcontrol.js (ステップ 2)
function ColorCtrl( id ) {
$$("#mockList li").forEach(function(item, index) {
item.setStyle("backgrond-color", item.getText());
});
/* Success! */
}
おそらくここで問題点がお分かりいただけると思いますが、ページ上のモック HTML をサーバー コントロールの構造と同期させておく必要があります。しかし、JavaScript で TDD を行うための優れたシステムが得られます。
UIコードを正常にTDDしたことはありません。私たちが最も近かったのは、実際、UIコードをアプリケーションロジックから可能な限り分離することでした。これが、model-view-controllerパターンが役立つ理由の1つです。モデルとコントローラーは、それほど問題なく、複雑になりすぎずにTDDを実行できます。
私の経験では、ビューは常にユーザー受け入れテストに残されていました(Webアプリケーションを作成し、UATはJavaのHttpUnitを使用しました)。ただし、このレベルでは、これは実際には統合テストであり、TDDで必要な分離テストプロパティはありません。この設定のため、最初にコントローラー/モデルテスト/コードを記述し、次にUIと対応するUATを記述しなければなりませんでした。ただし、最近作成しているSwing GUIコードでは、コントローラー/モデル/ APIに追加する前に、フロントエンドの設計を調べるために最初にスタブを使用してGUIコードを作成しています。ここでもYMMV。
繰り返しになりますが、私が提供できる唯一のアドバイスは、あなたがすでに疑っているように見えることです。UIコードをロジックから可能な限り分離し、それらをTDDします。
MVPアーキテクチャは、テスト可能なUIの作成に非常に適していることがわかりました。プレゼンタークラスとモデルクラスは、100%ユニットテストするだけです。UIテスト(Seleniumなどを使用)では、ビュー(プレゼンターにイベントを発生させるだけのダムで薄いレイヤーである必要があります)についてのみ心配する必要があります。
私が話しているのは、必ずしもサーバー側に渡ることなく、UIコンテキストで完全にMVPを使用することです。UIには、完全にクライアント側に存在する独自のプレゼンターとモデルを含めることができます。プレゼンターはUIの相互作用/検証などのロジックを駆動し、モデルは状態情報を保持し、バックエンドへのポータルを提供します(別のモデルを持つことができます)。
また、 PresenterFirstTDDテクニックも確認する必要があります。
これが、私が Google Web Toolkit に切り替えた主な理由です... 私は Java で開発とテストを行っており、コンパイルされた JavaScript がさまざまなブラウザーで適切に機能することを期待しています。TDD は主に単体テスト機能であるため、ほとんどのプロジェクトは、コンパイルとデプロイの前に開発およびテストできます。
統合および機能テスト スイートは、結果のコードがテスト サーバーにデプロイされた後、期待どおりに機能することを検証します。
私がやっていることは、Dom を突っ込んで、期待どおりの結果が得られているかどうかを確認することです。これの大きな副作用は、テストを高速化することで、アプリも高速化できることです。
私は、JavaScript tdd に非常に役立つオープンソースのツールキットをリリースしました。これは、多くのオープン ソース ツールを組み合わせたものであり、requirejs バックボーン アプリをすぐに使用できます。
実行する単一のコマンドを提供します: 開発 Web サーバー、jasmine 単一ブラウザー テスト ランナー、jasmine js-test-driver マルチ ブラウザー テスト ランナー、および JavaScript と CSS の連結/縮小。また、実稼働デバッグ用にアプリの非圧縮バージョンを出力し、ハンドルバー テンプレートをプリコンパイルし、国際化をサポートします。
セットアップは必要ありません。それだけで機能します。
私が取り組んでいる新しいプロジェクトでJavascript TDDを始めようとしています。私の現在の計画は、単体テストを行うためにqunitを使用することです。開発中は、ブラウザでテスト ページを更新するだけでテストを実行できます。
継続的インテグレーション (およびすべてのブラウザーでテストが確実に実行されるようにするため) のために、Seleniumを使用して各ブラウザーでテスト ハーネスを自動的に読み込み、結果を読み取ります。これらのテストは、ソース管理へのチェックインごとに実行されます。
また、 JSCoverageを使用して、テストのコード カバレッジ分析を取得します。これも Selenium で自動化されます。
現在、この設定の真っ最中です。セットアップが完成したら、この回答をより正確な詳細で更新します。
テスト ツール: