ホームページ >ウェブフロントエンド >jsチュートリアル >バックボーンのユニットテスト。JSアプリケーション
何時間も過ごした後、タッチしなかった部分は、恐ろしく不幸になりました。これで、既存のコードをどのように壊したかを把握しようとするために、作業の日々をバックトラックするという課題に直面しています。幸せな日は間違いなく再びここにありません。 そのまさにシナリオが私が認めたい以上に私を噛んだ。そして、あなたがしばらくコーディングしているなら、おそらくあなたもそれを見たことがあるでしょう。ただし、このシナリオを非常に苦痛にしている理由を考えてみましょう。新しいコードが既存のコードを破ったためではありません。それは開発では避けられません。本当の痛みは、破損に気付くのに時間がかかったことです。アプリケーションが機能していることを知って以来、非常に多くの開発があるため、バグが隠れている可能性のあるコードが大量にあります。そして、それは干し草の山で針を狩るようなように思えるかもしれませんが、私たちはそれを潜るしかありません。 この記事では、JavaScript開発からこのシナリオを本当に追放するつもりです。針を探しているコードの数時間、数日、または数週間を掘ることはもうありません。私たちが採用する原則は簡単なものです。
を作成するとすぐにバグを見つけます。それは正しい;バグを導入するコードを作成するときにすぐにわかります。さらに、私たちがプロセスに費やした余分な努力は、初期開発が完了すると無駄になりません。開発バグをキャッチするのと同じテストコードは、統合環境で完全に再利用可能になります。テストをソースコード管理システムに簡単に組み込むことができ、コードベースに入る前にバグをブロックできます。次の4つのセクションでは、まずJavaScriptテスト環境に必要なツールを調べます。次に、理解するのに十分なシンプルなアプリケーションを検討しますが、実際の制作Webアプリケーションに存在する可能性のあるすべての機能と機能を備えています。最後の2つのセクションでは、開発中に環境を使用してサンプルアプリをテストする方法を示しています。
テストツールは、Webブラウザーとnode.js環境の両方をサポートする必要があることを確認したため、コアテストフレームワークを選択するのに十分な選択肢を絞り込むことができます。多くのJavaScriptテストフレームワークが存在しますが、ほとんどはブラウザーテストに大きく偏っています。通常、node.jsで動作させることは通常可能ですが、多くの場合、無力なハックまたは調整が必要です。この問題に苦しんでいないフレームワークの1つはモカです。
node.js用に開発されたMochaは、Webブラウザーも容易にサポートするために拡張されました。 Mochaをテストフレームワークとして使用することにより、変更なしで開発と統合の両方をサポートするテストを作成できます。
いくつかのJavaScriptテストフレームワークとは異なり、Mochaは柔軟性を最大限に活用できるように設計されています。結果として、それを完成させるには、いくつかの追加作品を選択する必要があります。特に、JavaScriptアサーションライブラリが必要です。そのために、Chai Assertion Libraryに依存します。 Chaiは、すべての一般的なアサーションスタイルをサポートするという点でややユニークです。コード。カバーの下では、それらはすべて同等です。テストを1つのアサーションスタイルからもう1つのテストに翻訳するのは簡単です。アサーションスタイルの主な違いは、読みやすさです。アサーションスタイルの選択は、主にあなた(またはあなたのチーム)が最も読みやすいスタイルと、どのスタイルが最も理解できるテストを生成するかに依存します。違いを確認するには、次のコードの些細なテストの開発を検討してください。 従来のアサートスタイルのテストは、次のように記述できます そのテストは仕事を終了しますが、古い学校の単体テストに慣れていない限り、読んで解釈するのは少し難しいでしょう。代替のアサーションスタイルでは、を使用します ほとんどの開発者は、アサートスタイルのテストよりも読みや理解が容易になると予想されるスタイルのアサーションを見つけます。 3番目の選択肢は、テストアサーションを自然言語のようにさらに行う必要があります:
<span>var sum = 2 + 2;</span>
Chaiライブラリは、3つのアサーションスタイルすべてをサポートしています。この記事では、
に固執します スパイ、スタブ、および模擬assert<span>.equal(sum, 4, "sum should equal 4");</span>この記事で考慮する些細な例を含む
ほとんどのWebアプリは、サードパーティの図書館とサービスに依存しています。多くの場合、コードをテストするには、それらのライブラリやサービスを観察する、または制御する必要があります。 Sinon.JSライブラリは、これらの相互作用をテストするための多くのツールを提供しています。このようなツールは、3つの一般的なクラスに分類されます
<span>expect(sum).to.equal(4);</span>
spy
。テスト中のコードの外側の機能への呼び出しを観察するテストコード。スパイは、これらの外部機能の動作を妨害しません。彼らは単に呼び出しと返品値を記録するだけですsum<span>.should.equal(4);</span>
stub
。テスト中のコードの外側の機能を呼び出すためのテストコード。スタブコードは、外部関数を再現しようとはしません。テスト下のコードが外部関数にアクセスすると、未解決のエラーを防ぎます。 mock。テスト中のコード外で機能またはサービスを模倣するテストコード。モックを使用すると、テストコードはそれらの関数またはサービスからの返品値を指定して、コードの応答を確認できるようにします。
テストワークベンチの最終ツールは、ユニットテストの開発環境です。この例では、test’emを使用します。 Test’emは、連続テスト環境を設定および実行するための便利なスクリプトのコレクションです。選択した場合、スクリプトを自分で書いて、環境を手動で管理することができます。しかし、Toby Ho(Test’emの作成者)は、私たちにトラブルを救うことができる素晴らしいパッケージをまとめました。
サンプルアプリケーション
TODOSデータベース
そして、テーブルがテストデータを入れた後のテーブルがどのように見えるかを次に示します。
<span>var sum = 2 + 2;</span>
id
title当社のWebアプリケーションにはこのデータベースへのアクセスが必要なため、標準のRESTインターフェイスを提供します。 APIはRubyコンベンションに従いますが、サーバーテクノロジーによって簡単に実装できます。特に:
get api/todos/nnnは、nnnに等しいIDを持つtodoのJSON表現を返します。
POST API/TODOSは、リクエストのJSONエンコードされた情報を使用してデータベースに新しいTODOを追加します。開発中のテスト
<span>var sum = 2 + 2;</span>
ブラウザで開発する場合でも、テスト環境はnode.jsに依存しています。したがって、最初のステップは、node.jsとノードパッケージマネージャー(NPM)のインストールです。 Node.js Webサイトには、OS X、Windows、Linux、Sunos用の実行可能バイナリ、および他のオペレーティングシステムのソースコードがあります。インストーラーを実行した後、コマンドラインからnode.jsとnpmの両方を確認できます。
プロジェクト構造の作成
assert<span>.equal(sum, 4, "sum should equal 4");</span>この例のソースコードには、次の15のファイルを備えた完全なプロジェクト構造が含まれています。
各フォルダーとファイルに含まれるものは次のとおりです
の開発を開始します
最後に、コーディングの準備が整いました。コマンドシェルで、プロジェクトのルートフォルダーに移動し、コマンドテストムを実行します。 Test’emスクリプトが実行され、端子ウィンドウがクリアされ、右上にURLが与えられます。そのURLを選択したブラウザにコピーして貼り付けてください。Test’emを起動した端子窓もステータスを与えます。
真のテスト駆動型開発の精神では、テスト/App-todos-test.jsファイルに最初のテストケースを記述することから始めます。他の優れたWebアプリと同様に、グローバルネームスペース汚染を最小限に抑えたいと考えています。そのためには、すべてのコードを含むために、単一のグローバル変数TODOAPPに依存します。最初のテストケースでは、グローバル名スペース変数が存在することを確認します。
<span>var sum = 2 + 2;</span>ご覧のとおり、MochaにChaiの主張を使用していることを伝えるために、1つの予備声明が必要です。その後、テストの作成を開始できます。コンベンションにより、JavaScriptテストはブロックに編成されます(サブブロックなどにネストできます)。各ブロックは、describe()関数呼び出しから始まり、テストしているコードのどの部分を識別します。この場合、アプリケーション全体をテストしているため、これが最初のパラメーターです()。
テストブロック内で、各テストケースをテストするもので文書化します。それがIT()関数の目的です。テストケースを読む方法は、describe()とit()文字列を単一のステートメントに結合することです。したがって、最初のテストケースは
ですアプリケーションは、名前空間のグローバル変数を作成します
ですテストコード自体はIT()ブロック内にあります。私たちのテストケースは
これで、完全なテストケースがあります。ファイルを保存するとすぐに、Test`EMが自動的に引き継ぎます。ファイルの1つが変更されたことに気付くため、すぐにテストを再実行します。当然のことながら(まだアプリケーションのコードを書いていないため)、最初のテストは失敗します。
assert<span>.equal(sum, 4, "sum should equal 4");</span>
端子ウィンドウも自動的に更新されます
ファイルを保存するとすぐに、テストは再び行動に陥ります。テストケースの最新の結果がすぐに表示されます
しばらく後退して、何が起こっているのかを考えてください!テストコードまたはアプリケーションのいずれかに変更を加えるたびに、Test`EMはすぐにテストスイート全体を再実行します。私たちがしなければならないのは、画面の隅にTest’emのブラウザまたは端子ウィンドウを表示できるようにすることです。リアルタイムでコードの健康状態を見ることができます。バグが作業している場所とは異なるコードの一部に現れても、バグを導入するとすぐにわかります。バグを導入した時期を把握するために、時間、数日、または数週間の新しいコードを掘り下げることはもうありません。
開発環境が完全に確立されたため、アプリケーションの開発を開始できます。私たちのアプリはTODOのリストを表示しているので、それらのTODOのモデルを作成することは良いかもしれません。モデルは、TODOのタイトルとそのステータスの両方を追跡する必要があります。合理的なデフォルトでTODOを作成できる検証を検証するユニットテストを追加しましょう。
<span>var sum = 2 + 2;</span>これらのテストには注目に値するいくつかの側面があります
互いにテストブロックをネストすることができます。 1つのテストブロックには、TODOモデルのすべてのユニットテストが含まれ、これらのテストのサブブロックは初期化に焦点を当てています。
assert<span>.equal(sum, 4, "sum should equal 4");</span>各テストの前にいくつかの追加コードを含め、各テストの後に実行するコードのセクションを追加しました。その余分なコードは、コード内の別の関数を効果的に無効にする関数であるSinonスタブを管理します。この場合、スタブはthis.todoのsave()メソッドを無効にします。スタブを配置すると、メソッドへの呼び出しは実際にはBacknoneライブラリに移動しません。代わりに、シノンはそれらの呼び出しを傍受し、すぐに戻るだけです。この動作は重要です。ユニットテスト環境で実際のバックボーンSave()メソッドを実行しようとした場合、データベースまたはサーバーAPIが利用可能でないため、通話が失敗します。
スタブを所定の位置に配置すると、テストケースを使用してモデルの動作を検証できます。最初のテストケースでは、すぐにTODOのタイトルを新しい価値に設定しました。タイトルプロパティが変更されているため、モデルにバッキングストアを更新してもらいたいと考えています。スタブが呼び出されたことを単純に確認するために確認します。モデルをこれらのテストに合格させるために、変更イベントを探して適切に対応できます。
<span>var sum = 2 + 2;</span>ビューのテスト
2つのテストケースでビューのテストを開始します。まず、ビューのrender()メソッドがビュー自体を返すようにします。これは、メソッドチェーンを可能にするため、バックボーンで一般的で非常に便利な慣習です。 2番目のテストケースは、レンダリングが作成するHTML要素がリスト項目(
assert<span>.equal(sum, 4, "sum should equal 4");</span>
次に、そのリスト項目ビューの詳細なコンテンツを開発できます。例として、完全なリスト項目が次のように見えるようにしたい。
<span>expect(sum).to.equal(4);</span>テストケースでは、jqueryを利用して、ビューの主な要素から個々の要素を抽出できます。
最後のテストケースでは、モデルのsave()メソッドをスタブしたことに注意してください。プロパティをデフォルト値から変更しているため、モデルはその変更をバッキングストアに維持しようとします。ただし、ユニットテスト環境では、データベースやサーバーAPIはありません。スタブは、欠落しているコンポーネントの代わりになり、エラーなしでテストを続行できます。これらのテストを渡すには、ビューに追加のコードを追加する必要があります。
sum<span>.should.equal(4);</span>
テストモデル/表示相互作用を表示
CREATE TABLE `todos` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Primary key for the table.', `title` varchar(256) NOT NULL DEFAULT '' COMMENT 'The text for the todo item.', `complete` bit(1) NOT NULL DEFAULT b'0' COMMENT 'Boolean indicating whether or not the item is complete.', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='To Do items.'ビューの実装が適切なHTMLマークアップを作成することを確認したため、モデルとの相互作用をテストできます。特に、チェックボックスをクリックして、ユーザーがTODOのステータスを切り替えることができるようにします。私たちのテスト環境は実際の人間のユーザーを必要としないため、jQueryを使用してクリックイベントを生成します。ただし、そのためには、実際のライブDOMにコンテンツを追加する必要があります。そのコンテンツは、テスト
フィクスチャ
として知られています。これがユニットテストコードです。<span><span><!DOCTYPE html></span> </span><span><span><span><html</span> lang<span>="en"</span>></span> </span> <span><span><span><head</span>></span> </span> <span><span><span><meta</span> charset<span>="utf-8"</span>></span> </span> <span><span><span><title</span>></span><span><span></title</span>></span> </span> <span><span><span></head</span>></span> </span> <span><span><span><body</span>></span> </span> <span><span><span><h1</span>></span>List of Todos<span><span></h1</span>></span> </span> <span><span><span><script</span> src<span>="lib/jquery-1.9.0.min.js"</span>></span><span><span></script</span>></span> </span> <span><span><span><script</span> src<span>="lib/underscore-min.js"</span>></span><span><span></script</span>></span> </span> <span><span><span><script</span> src<span>="lib/backbone-min.js"</span>></span><span><span></script</span>></span> </span> <span><span><span><script</span> src<span>="src/app-todos.js"</span>></span><span><span></script</span>></span> </span> <span><span><span><script</span>></span><span> </span></span><span><span> <span>$(function () { </span></span></span><span><span> <span>var todos = new todoApp<span>.Todos</span>(); </span></span></span><span><span> todos<span>.fetch(); </span></span></span><span><span> <span>var list = new todoApp<span>.TodosList</span>({collection: todos}); </span></span></span><span><span> <span>$("body").append(list.el); </span></span></span><span><span> <span>}) </span></span></span><span><span> </span><span><span></script</span>></span> </span> <span><span><span></body</span>></span> </span><span><span><span></html</span>></span></span>
テストケース自体については、フィクスチャのIDを使用して
<span>var sum = 2 + 2;</span>ビューでは、
コレクションのテスト
assert<span>.equal(sum, 4, "sum should equal 4");</span>
ビューの実装も簡単です。コレクションへの追加を追跡し、ビューを更新します。最初のrender()の場合、コレクション内のすべてのモデルを一度に1つずつ追加するだけです。
<span>expect(sum).to.equal(4);</span>
ボーナステスト:APIの検証
sum<span>.should.equal(4);</span>REST APIは、Backboneが期待するAPIと完全に一致するため、APIインタラクションを管理するためにカスタムコードは必要ありませんでした。その結果、ユニットテストのケースは必要ありません。現実の世界では、あなたはそれほど幸運ではないかもしれません。 APIがバックボーンコンベンションに準拠していない場合は、非標準のAPIに対処するためにバックボーンコードの一部をオーバーライドまたは拡張する必要がある場合があります。その余分なコードには、単体テストも必要です。幸いなことに、ユニットテスト環境であっても、APIの相互作用をテストするのは比較的簡単です。
API相互作用をテストする最も簡単な方法は、sinon.jsの偽のサーバー機能に依存しています。残念ながら、その機能は、Sinonのブラウザの実装でのみ(現在)利用可能です。 node.jsの実装から明示的に除外されています。 node.jsで実行するためのハックがいくつかありますが、これらのハッキングは非常に脆く、内部実装の詳細に依存しています。可能であれば避けるのが最善です。幸いなことに、Sinonの偽サーバーなしではうまくいくことができます
秘密は、バックボーンがjqueryの$ .ajax()関数に依存して、rest apisを実装することを知っていることです。その関数をスタブすることにより、API相互作用を傍受できます。関数をスタブするときは、独自の応答を置き換えたいと思うでしょう。 スタブのevelowsto()メソッドは、その機会をまったく与えてくれます。それは、スタブが呼び出されたときにどのような追加のアクションをとるべきかをシノンに伝えます。これは、REST APIを使用してコレクションが正しく初期化されていることを確認するための完全なテストケースです。
<span>var sum = 2 + 2;</span>終了!
統合中のテスト
ビルドプロセス中に、Webブラウザーではなくコマンドラインからテストを実行することをお勧めします。個々のテストケースの詳細は必要ありません。すべてが合格するという保証だけです。 node.jsは、この要件に対応するのに十分簡単になります。ソースコードおよびユニットテストコードファイルにいくつかの小さな追加を行う必要があります。 Node.jsは、Webブラウザーとは異なる方法でグローバル変数を処理するため、
コードがこれらの変更が必要です。 Webブラウザでは、JavaScript変数はデフォルトでグローバルな範囲です。一方、node.jsは、デフォルトで変数をローカルモジュールに限定します。その環境では、私たちのコードは必要なサードパーティのライブラリを見つけることができません(jquery、underscore、およびbackbone。最初に次の記述を追加すると、node.jsはこれらのライブラリへの参照を適切に解決します。また、テストコードを調整する必要があります。テストスクリプトでは、独自のライブラリ(jquery、chai、sinon.js、およびsinon-chai)にアクセスする必要があります。さらに、Webブラウザーのドキュメントオブジェクトモデル(DOM)をシミュレートするために、少し追加を追加する必要があります。クリック処理のためのテストでは、Webページに「フィクスチャ」
<span>var sum = 2 + 2;</span>これらのステートメントテストをラップして、Webブラウザーの代わりにnode.js環境で実行されているかどうかを確認する条件付き。ブラウザでは、追加のステートメントは必要ありませんので、安全にスキップできます。
これらの変更を使用すると、コマンドラインから完全なテストスイートを実行できます。プロジェクトのルートフォルダーに移動し、コマンドMochaを実行するだけです。結果は非常によく知られているように見えます。
もちろん、モカは出口レベルを返して、すべてのテストが合格したかどうかを示します。これにより、継続的な統合プロセスの一部として、または単に独自の正気を維持するためのローカルプリコミットスクリプトとしてテストを自動化できます。
結論この時点で、私たちは目標を達成しました。開発中にバックグラウンドで実行されるユニットテスト環境があり、テストが失敗したときにすぐに通知します。テストはWebブラウザで実行され、コーディング中にブラウザの開発ツールに完全にアクセスできます。同じテストもコマンドラインスクリプトから等しく実行されるため、ビルドまたは統合プロセス中に実行を自動化できます。
リソース
javaScript単体テストフレームワーク:mocha
backbone.jsは、他のJavaScriptフレームワークと同様に、アプリケーションの品質を確保するための単体テストをサポートします。ただし、Backbone.jsは、柔軟性とシンプルさのために際立っています。アプリケーションをどのように構成すべきかを決定することはなく、開発者は適切と思われるアプリケーションを自由に設計することができます。この柔軟性は単体テストにまで及び、開発者が好みのテストツールと方法論を選択できるようになります。さらに、Backbone.jsは他のフレームワークと比較してフットプリントが小さく、単体テストのために高速かつ効率的になります。 Backbone.jsでの単体テストに利用できるいくつかのツールです。人気のあるものには、Mocha、Jasmine、Jestが含まれます。 Mochaは、開発者にアプリケーションをテストする簡単な方法を開発者に提供する機能が豊富なJavaScriptテストフレームワークです。 Jasmineは、JavaScriptコードをテストするための行動主導の開発フレームワークです。ブラウザ、DOM、またはJavaScriptフレームワークに依存していないため、BackBone.jsアプリケーションのテストに最適です。一方、Jestは、大規模なWebアプリケーションのシンプルさとサポートに焦点を当てた包括的なテストソリューションです。 Backbone.jsアプリケーションのテストには、アプリケーションの各コンポーネントのテストケースの作成が含まれます。これには、モデル、ビュー、コレクションが含まれます。各テストケースは、コンポーネントの特定の機能をカバーし、他のテストケースとは無関係である必要があります。 MochaやJasmineなどのテストフレームワークを使用して、テストを作成できます。これらのフレームワークは、テストケースを定義し、テスト環境をセットアップおよび解体し、アサーションを作成する機能を提供します。 JSは、使用しているテストフレームワークに依存します。たとえば、Mochaを使用している場合は、Mochaコマンドラインツールを使用してテストを実行できます。ジャスミンを使用している場合は、ジャスミンコマンドラインツールを使用してテストを実行できます。これらのツールは、個々のテストケース、テストスイート全体、またはアプリケーション内のすべてのテストを実行するオプションを提供します。また、渡され、失敗し、スキップされたテストの数など、テストの結果に関する詳細なレポートを提供します。 Backbone.jsでユニットテストを自動化します。自動化には、コードが変更されるたびにテストを自動的に実行する継続的な統合(CI)システムのセットアップが含まれます。これにより、変更によって導入されたバグがすぐにキャッチされます。 JavaScriptをサポートし、Backbone.jsの単体テストを自動化するために使用できるJenkins、Travis CI、Circleciなど、いくつかのCIツールが利用可能です。
以上がバックボーンのユニットテスト。JSアプリケーションの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。