web-dev-qa-db-ja.com

ユーザーインターフェイスの単体テストはどのように行いますか?

RailsアプリケーションのJavaScriptをJQueryで使用します。これには動的な動作があります。Ruby開発者として、私はTDD/BDDが好きで、 RSpec。今のところ、JavaScriptを手動でテストしています。どこかで変更すると、どこかでコードが壊れる可能性があるため、最善の方法ではありません。TDDを使用することには多くの利点があります。

多くのユーザーインタラクションをテストする必要があるため、JavaScriptでのテストは複雑に思われます。カピバラなどを使用して完全に統合して動作をテストできますが、テストが非常に遅くなります。

たとえば、動的な振る舞いを持つフォームがあります。このフォームには、オプションを選択したり、ラジオボタンを選択したり、チェックボックスをオンにしたりすると変化する5つまたは6つの動的フィールドがあります。場合によっては、ajax呼び出しがあります。このフォームの場合、フォームだけで約20のテストを実行できると思います。このテストは本当に便利ですか?

では、標準のWebアプリケーションのルールは何ですか?

7
Dougui

価値があるかどうかのみテスト

私は通常はテストしませんが、もしそうしたとしても、私が書いたすべてのものの前にカバー率やローディングテストのパーセンテージを目指すことはせず、制御できないものやコーディングが不十分なものの処理に焦点を当てます書き直す時間がない。

私が制御し、実際に書き込んだことの動作が予測できない場合、私の問題は、テストがないことではなく、方法に関係なく、保守が難しい小便の少ないコードを書いたことです。すぐに動作していることがわかります(無意味な複雑さに圧倒されることを許可していなければ、通常クライアント側ですぐに発生します)。時間がかかるだけで、UIにはテストファーストTDDアプローチのようなものでそれをうまく書くプロセスを細かく管理しようとする多くの要因が含まれる傾向があります。私は、コードをクリーンでわかりやすく、最小限で堅牢な状態に保つことに重点を置くことを好みます。

Bury the DOM

IMOは、テストする理由の範囲内にあるものを発見するための鍵です。アーキテクチャーのアプリレベルでより操作できるオブジェクトにすべてのクライアント側のものを埋め込むことです。目標は、最高レベル(つまり、実装と再利用可能なコードの通常)で、単純なバニラオブジェクトを作成することです。あなたは大量のオプションと_$_と_document.getViaRidiculouslyExplicitlyNamedMethod_が供給されているajaxメソッドを見ていない、comboFactory.build('combo_class_name')のようなものを見ていてクライアント側についての無知は、使用方法を理解することができました。

これがあなたにもたらすことは、DOM関連の細部を分割したものであり、実際に考えることができるより多くのアプリレベルのデータフローの懸念から、物事を堅牢に保つことは、あなたが書くあらゆる小さなものの前にテストをロードすることほど簡単ではありません。フローチャートの観点から。テストが必要な場合は、ここでテストに集中します。

クレイジーダイナミックフォームの場合:

Ajaxがすべてサービスオブジェクトにバンドルされている場合、または非同期通信要素を完全に隠すいくつかのばかげたシームレスなデータレイヤーの一部である場合、フォームのコンテキストでテストする必要はありません。サービスコールは機能するか機能しません。それらは独立してテストすることができます。

動的に入力されるフォーム入力の場合、これらの入力の大部分は、他の1つの設定から読み込まれます。サービスがすでにチェックアウトしている場合、CSSまたはHTMLに関連付けられたDOMの悪意のために壊れる可能性が高いため、テストする価値があるものは考慮しません。だから、せいぜいセレンだろう。しかし、単体テストは実際には私には意味がありません。 Test-first-TDDは私には意味がありませんが、特にそのようなものには意味がありません。

思慮深いアーキテクチャが最初

入力が入力され、そのフォーム内の他の20の入力状態すべてに基づいて変化する、非常に複雑なフォームがある場合、再設計を要求する権限がないと仮定すると(通常、その場合は本当の問題です)、各入力操作が1つのデータセットを変更し、データモデルの他の部分が変化する可能性があるが、入力自体がデータの断片を設定する可能性のあるイベントをトリガーする、データバインドイベント駆動型アプローチを採用する彼らはそのデータセットの変更を気にし、リッスンして、せいぜい少数の異なるタイプの動作を引き起こします。

それぞれの入力について、それは機能するか機能しない最小限の分岐を持つ2つの単純な手段であり、潜在的な障害点が明白ではない方法で変更することはほとんどなく、コミットする前に徹底的にテストするのは簡単です。これにより、関係のクモの巣がデータの抽象化に限定され、他のデータ要素が変更されたときに残っているものだけを気にするものまで、さらに不確かなものが絞り込まれます。

問題は、あなたが最も評価するもの、私が今説明したもの、またはもう少し複雑で紛らわしいものですが、すべてをテストしています。私の意見は前者にかなり強く重み付けされていますが、両方を管理できれば、あなたに力があります。

UIでは、DRYの原則が最重要です、IMO。最初にコードベースを慎重に作成することに費やした時間よりも多くの時間をかけて値を追加するという正当な理由がない限り、テストを追加しないでください。読みやすく、変更しやすく、他の部分の再利用も簡単です。これらの3つすべては、私の経験に代わるものがない、コーディングクラフトで広く認められている他の多くの重要なヒューリスティックを必要とします。私のアーキテクチャを推進するものであり、結果として、たいていの場合、テストを追加することは難しくありませんが、テスト戦略が実際にアーキテクチャを推進することは決してありません。ただジェネラリストになろうとしているだけですが、私はこの時点で、これらの優先順位はWeb UI以外にも有効であるとかなり確信しています。

12
Erik Reppen

仕事で jasmine を使用してJavaScriptをテストし始めました。学習曲線が少しあります(ただし、RSpecに精通している場合はそれほど悪くはありません)。コードの構成方法を少し変更する必要があるかもしれませんが、全体としては非常に良い経験でした。

これはコードの動作テストです。これは、受け入れおよび統合テストの代わりにはなりません。

0
binarycleric

私が知っている多くの個人は、テストの考え方から来ており、コード化されたテストからではなく、人から発生しています。もちろん、これは QUnit (私のお気に入りの1つ)などのツールを使用したTDDの適切な理解の欠如です。 JavaScriptゲームフレームワークにQUnitを使用して、コンポーネントが確実に機能するようにしました。

それはあなたのJSが実際にどれほど複雑であるか、JSがどのように設計されているかに依存します(ユニットテストはそれがモジュラー方式で開発されることを要求します)。直接DOMに関連付けられている場合、テストはより困難ですが、不可能ではありません。いくつかの割り当てをテストするだけであれば、それ自体は心配しません。ただし、UIの多くがJavaScriptベースの場合は、フレームワークを使用し、可能な場合はコードをモジュール化することを検討します。

0
Brian Mains