目次


MEAN をマスターする

MEAN スタックのテスト

Comments

コンテンツシリーズ

このコンテンツは全#シリーズのパート#です: MEAN をマスターする

このシリーズの続きに乞うご期待。

このコンテンツはシリーズの一部分です:MEAN をマスターする

このシリーズの続きに乞うご期待。

UGLI (User Group List and Information) アプリケーションは、作成を開始して以来、大きな進歩を遂げました。現在、UGLI アプリケーションにはローカル・データを保管すると同時に、RESTful Web サービスを通じてリモート・ソースからデータを取り込めるようになっています。また、このアプリケーションにはモバイル対応のレスポンシブ Web デザインが適用されていて、SEO (Search Engine Optimization: 検索エンジン最適化) を最大限に利用するために、セマンティックなマークアップが追加されています。認証に関しては、ユーザーはローカルの専用アカウントを作成することも、他の場所に保管されている既存のアカウントを (OAuth を介して) 再利用することもできます。

しかし、UGLI アプリケーションに問題がないことを保証する手段として、信頼できるテスト・スイートを使用することなく、本番へ移行するとなると、皆さんは不安を感じるのではないでしょうか?皆さんが不安を感じるのは当然のことです。しっかりしたテストをしないのは、プロとして無責任なことだからです。テスティングのことを「ソフトウェア開発におけるエンジニアリングの厳格さ」と称した (著作者でもあり、国際的な講演者でもある) Neal Ford 氏に、私も同意します。私が新しいクライアントを使い始めるときは、何よりもまずテスト・スイートを調べます。テストの設計書まで調べることもあります。テストの質、量、包括性は、ソフトウェア開発プロセスの成熟度にそのまま結び付きます。活発に保守が行われている健全なテスト・スイートがあることは、プロジェクト全体の健全さを示す目安となります。それと同じく、テストのしやすさを重視しているフレームワークは、私が優先的に使用するフレームワークのリストのトップに位置します。AngularJS は、テスターたちによって作成されたフレームワークです。最近の Web フレームワークの中でこれよりもテストしやすいものは、私には思い付きません。MEAN.JS スタックは、AngularJS のテストのしやすさを拡張し、サーバー・サイドのロジックをテストできるようにしています。

AngularJS は、テスターたちによって作成されたフレームワークです。最近の Web フレームワークの中でこれよりもテストしやすいものは、私には思い付きません。

この連載の始めでは、MEAN スタックの基本的な構成要素について説明しました。MEAN スタックでは、疎結合の小さなピースが、アプリケーションの本番コンポーネントを構成します。今度は、アプリケーションをテストして本番に移行できるようにするために使用する、各種のフレームワークやライブラリーについて、詳しく見て行きます。今回の記事では、Karma というプラガブル・テスト・ランナーを紹介します。Karma を使用すれば、実際の Web ブラウザー (スマートフォン、タブレット、スマート TV を含む) をいくつでも使って、任意のテスト・フレームワークで作成されたテストを簡単に実行し、多種多様なフォーマットでテスト結果を返すことができます。Karma を紹介する中で、クライアント・サイドのテストには Jasmine を、サーバー・サイドのテストには Mocha を、そしてコード・カバレッジには istanbul を使用します。

テストを実行する

連載ではこれまで、MEAN.JS フレームワークに標準装備されている Yeoman ジェネレーターを使用してきたので、すでにいくつかのテストが所定の場所に生成されています。「grunt test」と入力して、それらのテストを実行すると、リスト 1 のような結果が表示されるはずです。

リスト 1. 生成済みのテストを実行する
$ grunt test
Running "env:test" (env) task

Running "mochaTest:src" (mochaTest) task

 Application loaded using the "test" environment configuration

Running "karma:unit" (karma) task
INFO [karma]: Karma v0.12.31 server started at http://localhost:9876/
INFO [launcher]: Starting browser PhantomJS
INFO [PhantomJS 1.9.8 (Mac OS X)]: Connected on socket 6zkU-H6qx_m2J6lY4zJ8 with id 51669923
PhantomJS 1.9.8 (Mac OS X): Executed 18 of 18 SUCCESS (0.016 secs / 0.093 secs)

Done, without errors.

エラーや警告が出ても気にしないでください。テストは最初に実装された時点で、モデルとコントローラーに合わせて scaffold として生成されています。テスト対象コード (CUT: Code Under Test) に変更を加えた場合、対応するテストを更新していなければ、エラーが出るのは当然です。

私はユニット・テストで失敗するたびにゾクゾクします。ユニット・テストは、コード・ベースのブレーカーのようなものです。自宅では、送電網と高価な家電製品の間にブレーカーを配備します。そうすることで、家電製品にダメージを与えかねない電力サージが電線を伝って来たとしても、3,500 ドルのノート PC は犠牲にならずに 35 セントのブレーカーを犠牲にするだけで済みます。それと同様に、ユニット・テストでの失敗は、開発者が目にするエラーですが、このエラーをユーザーが目にすることはありません。

可能であれば、少し時間を取って、失敗したテストを修正してください。一般的なエラーの原因は、テストで使用しているフィールド名が変更されていたり、フィールド自体が削除されていたりすることにあります。サーバー・サイドのテストは、app/tests に格納されています。クライアント・サイドのテストは、各 public/module の test ディレクトリーに格納されています。テストでのエラーの原因がすぐに見つからないとしても、テストを削除せずに、そのテストを一時的にディレクトリー・ツリーの外に移動するだけにしてください。

エラーなしでテストを実行できるようになったら、次はテスト・プロセスを分析します。

Grunt の test タスクについて理解する

皆さんが「grunt test」と入力したときに、Grunt がこれらのテストをどのように実行するのか、考えたことを願います。ご存知のように、Grunt はビルド・スクリプトを実行します。gruntfile.js をテキスト・エディターで開いて、ファイルの一番下までスクロールダウンすると、以下のように test タスクが登録されていることがわかります。

// Test task.
grunt.registerTask('test', ['env:test', 'mochaTest', 'karma:unit']);

grunt.registerTask の 1 番目の引数は、タスクの名前です (この場合は、test という名前です)。次の引数は、従属タスクの配列となっています。test タスクは、最初にテスト環境に固有の値をセットアップします。次に、Mocha で作成されたサーバー・サイドのテストをすべて実行し、最後に Karma を介してクライアント・サイドのテストを起動します。

env タスクが見つかるまで、gruntfile.js を少しスクロールアップしてください。

env: {
    test: {
        NODE_ENV: 'test'
    }
},

このタスクは、NODE_ENV 変数を test に設定するだけに過ぎません。以前に説明したように、Grunt はこの変数を頼りに、config/env/all.js の共通設定とマージしなければならない、環境に固有の設定を判別します。この例の場合、それに該当するのは config/env/test.js です。

テキスト・エディターで config/env/test.js を調べると (リスト 2 を参照)、カスタム MongoDB 接続ストリングの他に、各種 OAuth プロバイダーに応じたすべての Passport 設定のフックがあることがわかります。

リスト 2. config/env/test.js
'use strict';

module.exports = {
    db: 'mongodb://localhost/test-test',
    port: 3001,
    app: {
        title: 'Test - Test Environment'
    },
    facebook: {
        clientID: process.env.FACEBOOK_ID || 'APP_ID',
        clientSecret: process.env.FACEBOOK_SECRET || 'APP_SECRET',
        callbackURL: 'http://localhost:3000/auth/facebook/callback'
    },
    google: {
        clientID: process.env.GOOGLE_ID || 'APP_ID',
        clientSecret: process.env.GOOGLE_SECRET || 'APP_SECRET',
        callbackURL: 'http://localhost:3000/auth/google/callback'
        },
    // snip
};

このコード・セクションは、Passport に Meetup 認証ストラテジーのモック実装を参照させるのに理想的な場所です。このようにしておけば、テストの実行時に、実際のユーザーに頼って、Meetup.com に対する OAuth リクエストをセットアップして実際に送信してもらう必要がなくなります。

テスト環境が構成されると、Grunt は、Mocha で作成されたサーバー・サイトのテストをすべて実行します。以下に、mochaTest タスクを記載します。

mochaTest: {
    src: watchFiles.mochaTests,
    options: {
        reporter: 'spec',
        require: 'server.js'
    }
},

サーバー・サイドのテストを、なぜ Jasmine ではなく Mocha で作成したのかというと、それは、成熟度、拡張性、プラグインの点で、Mocha は私のお気に入りのテスト・フレームワークの 1 つだからです。Express ルート、コントローラー、MongoDB インタラクションなどをテストするには、Mocha が強力な選択肢となります。Mocha は Node.js においてもブラウザー内でも簡単にテストを実行することができますが、AngularJS チームではブラウザー内テストには Jasmine を使用しています。Jasmine は、クライアント・サイドのテストに最適化されているからです。つまり、MEAN.JS 開発チームは最善の組み合わせとして、サーバー・サイドのテストには強力なサーバー・サイドのテスト・フレームワークを選択し、クライアント・サイドのテストには強力なクライアント・サイドのテスト・フレームワークを選択したというわけです。皆さんは、これらのフレームワークのいずれか、または両方を、自分の使いやすいテスト・ツールに換えてください。

サーバー・サイドのテストは (当然のことながら) ブラウザー内では実行されないため、Mocha で作成されたテストは、Karma では起動されません。Jasmine で作成されたテスト (Grunt test 依存関係の最後の部分) は、以下のように karma タスクによってトリガーされます。

karma: {
    unit: {
        configFile: 'karma.conf.js'
    }
}

karma.conf.js ファイルの分析に移る前に、package.json をテキスト・エディターで開いてください。dependencies ブロックに記載されているランタイム・モジュールに加え、devDependencies (developer dependencies の略) ブロックに、ビルド時の依存関係がいくつか記載されています。このブロックは、Mocha および Karma に関連する Grunt プラグインが明確に宣言されている場所であり、「npm install」と入力して実行すると、これらのプラグインがインストールされます。

  "devDependencies": {
    "grunt-env": "~0.4.1",
    "grunt-mocha-test": "~0.10.0",
    "grunt-karma": "~0.8.2",
    "load-grunt-tasks": "~0.4.0",

    // snip
  }

Karma の紹介

Karma は、修士論文で裏付けられた、私が知っている唯一のテスト・ランナーです。このプロジェクトのミッション・ステートメントには、Karma の背後にある考え方がもっと簡潔に表現されています。

物事はシンプルであるべきです。私たちはテストの重要性を信じているので、テストをできる限り単純にすることを目指しています。

その言葉通り、Karma は単純です。Karma では、任意のフレームワークでテストを作成することができます。QUnit のテスト駆動開発 (TDD) スタイルを選ぶのか、Jasmine のビヘイビア駆動開発 (BDD) スタイルを選ぶのかに関わらず、Karma はどのスタイルで作成されたテストでも適切に実行します (サーバー・サイドのテストとクライアント・サイドのテストを 1 つのテスト・フレームワークを使って両方とも作成したい場合、Karma には、Mocha に対する第 1 級のサポートも用意されています)。

ベテランの Web 開発者は、アプリケーションのテストは多種多様なブラウザーで実行することが、いかに重要であるかを知っています。コアとなる JavaScript 言語は、あらゆるブラウザーで驚くほどの一貫性を持っていますが、DOM (Document Object Model: ドキュメント・オブジェクト・モデル) の操作と Ajax リクエストの実行方法となると、標準化されているとはとても言い難い状況です。jQuery や AngularJS などの主流のライブラリーは、ブラウザーの非互換性をポリフィルで解消するという偉業を達成しているとはいえ、それに甘んじることはできません。1 つのテストは千件の意見に匹敵します。アプリケーションが特定のブラウザーで意図した通りに動作することを単に前提とすることよりも、それを証明することのほうが、遥かに価値があります。

Karma には、実際のブラウザーをオンデマンドで起動して、完全なテスト・スイートを実行した後、完了時にブラウザーをシャットダウンするために使用できるプラグインがいくつか用意されています。この機能は、任意のブラウザーを使ってローカルでテストを実行するのに重宝しますが、Jenkins、Hudson、Strider などのヘッドレスの継続的インテグレーション・サーバーによってテストが起動される場合は、その機能が制限されてしまいます。

ありがたいことに、Karma では、長時間稼働する Karma サーバーを立ち上げて、リモート端末上のブラウザーをキャプチャーできるようになっています。ブラウザーで Karma サーバーの URL にアクセスするだけで、ブラウザーをキャプチャーすることができるのです。ブラウザーが WebSocket をサポートしている場合 (caniuse.com に、最近主流となっているすべてのブラウザーでのサポート状況が記載されています)、Karma サーバーは端末との接続を長時間維持することができます。Karma サーバーは、テスト・スイートに新しいテストが追加されると、そのテストをオンラインでリモート・ブラウザーにシリアライズして実行し、結果を返します。

しかし、結果を数値化できなければ、テスト・スイートを実行する効果はどれほどのものになるのでしょう? Karma には、何種類かのレポート機能用のプラグインが用意されています。これらのレポート機能には、合格した各テストに対してコマンド・ラインにドットを出力するだけのものもあれば、完全にフォーマット設定された HTML を出力するものや、任意の出力に変換可能な、未加工の JUnit 対応 XML を出力するものもあります。

テスティング・フレームワーク、ブラウザー・ランチャー、そして結果のレポート機能はすべて、karma.conf.js ファイルに定義されています。

karma.conf.js を理解する

karma.conf.js をテキスト・エディターで開いてください (リスト 3 を参照)。このファイルには、frameworksfilesreportersbrowsers という明確なラベル設定が見つかるはずです。

リスト 3. karma.conf.js
'use strict';

/**
 * Module dependencies.
 */
var applicationConfiguration = require('./config/config');

// Karma configuration
module.exports = function(config) {
    config.set({
        // Frameworks to use
        frameworks: ['jasmine'],

        // List of files / patterns to load in the browser
        files: applicationConfiguration.assets.lib.js.concat(applicationConfiguration.assets.js,
        applicationConfiguration.assets.tests),

        // Test results reporter to use
        // Possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'
        //reporters: ['progress'],
        reporters: ['progress'],

        // Web server port
        port: 9876,

        // Enable / disable colors in the output (reporters and logs)
        colors: true,

        // Level of logging
        // Possible values: config.LOG_DISABLE || config.LOG_ERROR ||
           config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
        logLevel: config.LOG_INFO,

        // Enable / disable watching file and executing tests whenever any file changes
        autoWatch: true,

        // Start these browsers, currently available:
        // - Chrome
        // - ChromeCanary
        // - Firefox
        // - Opera
        // - Safari (only Mac)
        // - PhantomJS
        // - IE (only Windows)
        browsers: ['PhantomJS'],

        // If browser does not capture in given timeout [ms], kill it
        captureTimeout: 60000,

        // Continuous Integration mode
        // If true, it capture browsers, run tests and exit
        singleRun: true
    });
};

package.json を再び参照すると、このファイルの devDependencies ブロックに、各種の Karma プラグインに対応するエントリーがあります。

  "devDependencies": {
    // snip

    "karma": "~0.12.0",
    "karma-jasmine": "~0.2.1",
    "karma-coverage": "~0.2.0",
    "karma-chrome-launcher": "~0.1.2",
    "karma-firefox-launcher": "~0.1.3",
    "karma-phantomjs-launcher": "~0.1.2"
  }

scaffold として生成されたクライアント・サイドのテストはすべて Jasmine で作成されているので、frameworks 配列は現状のままにしておくことをお奨めします。ただし、このセクションの後のほうでわかるように、上記ブロックにはブラウザーの種類を自由に追加または削除して構いません。

PhantomJS の紹介

このセクションでは、PhantomJS ブラウザーに馴染みがない Web 開発者を温かくおもてなしします。PhantomJS は、Web テスターの最高のお供の 1 つです。

Firefox、Chrome、Safari、Opera、Internet Explorer といったお馴染みのブランド名によって、Web ブラウザーはモノリシックなアプリケーションであると思い込まれがちですが、これらのブランド名は、レンダリング・エンジン (HTML、CSS 用)、スクリプト・エンジン (JavaScript 用)、プラグイン・サブシステムなどの特定のテクノロジーの集合を説明する便宜的な手段に過ぎません。

皆さんはすでに、経験を積んだ MEAN 開発者として、ブラウザーからコンポーネントを取り出してヘッドレスで実行する方法を十分理解しているはずです。ヘッドレスのレンダリング・キットをテストの目的で実行するのはお手の物でしょう。

ブラウザーが、レンダリング・キットとスクリプト・エンジンが疎結合された集合であることを理解するようになると、まったく新しいレベルでブラウザーを理解できるようになります。例えば、Netscape Navigator ブラウザーは、1990年代半ばにバージョン 2.0 がリリースされた時点で、市場のシェアの 90 パーセント以上を占めていました。そのわずか数年後には、IE が市場のトップを引き継ぎましたが、最近ではブラウザーではなくレンダリング・キット (WebKit) が市場のシェアの大半を占めるようになっています。それは、WebKit は最近まで、Safari、Mobile Safari、Chrome、Android ブラウザー、BlackBerry ブラウザー、Kindle 端末、PlayStation、Samsung スマート TV、LG スマート TV、Panasonic スマート TV、等々を駆動する、縁の下の力持ちであったためです (囲み記事「WebKit と Blink との融合」を参照)。これらのアプリケーションと端末は、いずれも異なる企業やプロジェクトによってアセンブルされているとはいえ、HTML を表示してそれを CSS でスタイル設定するためのレンダリング・キットとして、共通のものを使用していました。

このことが PhantomJS にどう関係するのかというと、PhantomJS Web サイトでは、次のように説明しています。

「PhantomJS は、JavaScript API を使用するスクリプトを作成できる、ヘッドレス WebKit です」。

ヘッドレス・サービスには、モニターも GUI も必要ありません。モニターレスの継続的インテグレーション・サーバーでブラウザー・ベースのユニット・テストを実行するには、そのようなヘッドレス・サービスが最適なはずです (SlimerJS プロジェクトでも同じような機能を提供しています。具体的には、ヘッドレス Gecko レンダリング・キットを実行して、Firefox ブラウザーでページのレンダリングをテストすることができます)。

皆さんはすでに、経験を積んだ MEAN 開発者として、ブラウザーからコンポーネントを取り出してヘッドレスで実行する方法を十分理解しているはずです (Node.js は、ヘッドレスで実行される Google Chrome のスクリプト・エンジン (V8) です)。ヘッドレスのレンダリング・キットをテストの目的で実行するのはお手の物でしょう。

karma.conf.js をもう一度調べると、browsers 配列に PhantomJS が含まれていることがわかります。これで、Jasmine のクライアント・サイドのテストのすべてがどのように実行されて、GUI が起動されることなくブラウザーに渡されるかを理解できたはずです。

他のブラウザーも起動されるように Karma を構成する

Karma には、主要なすべてのブラウザーのランチャーが用意されています。package.json の devDependencies ブロックをもう一度見てみると、Firefox と Chrome のランチャーがすでにインストールされるようになっていることがわかります。これらのブラウザーをコンピューターにインストールしてある場合は、karma.conf.js の browsers 配列にこの 2 つを追加してください。その上で「grunt test」と入力して実行すると、新しく追加されたブラウザーでテスト・スイートが実行されます。

npm の Web サイトにアクセスして「karma launcher」と入力して検索し、サポートされているすべてのブラウザーのリストを確認することをお勧めします。各ランチャーをインストールして、それを package.json に追加するには、「npm install karma-xxx-launcher --save-dev」と入力して実行します。ランチャーがインストールされたら、karma.conf.js の browsers 配列にそのランチャーを追加して、テストを再実行します。

起動できないブラウザーをキャプチャーする

Karma ランチャーは、一般に、同じコンピューター上にインストールされているブラウザーを起動するために使用します。Karma は、リモート・ブラウザーでテストを実行するためにも使用できることを思い出してください。つまり、スマートフォン、タブレット、スマート TV などのブラウザーでテストを実行できるということです。WebSocket をサポートしているブラウザーであれば、いずれも Karma でキャプチャーして、テスト・ターゲットとして使用できます。

リモート・ブラウザーをキャプチャーするには、何よりも Karma サーバーがテストとテストの間でも稼働し続けるようにする必要があります。Karma サーバーを永続的に稼働させたままにするには、karma.conf.js で、singleRun の値を false に変更します。

// Continuous Integration mode
// If true, it capture browsers, run tests and exit
singleRun: true

Karma サーバーまたはキャプチャーしたブラウザーのいずれかをリブートすると、サーバーまたはブラウザーが再接続してすべてのテストを再実行しようとします。

Karma サーバーが稼働中になったら、リモート・ブラウザーで http://<サーバーの IP アドレス>:9876 にある Karma サーバーにアクセスしてください。これだけで、起動できないブラウザーでも Karma を使用してキャプチャーできるようになります。

他の Karma レポート機能を追加する

他のテストとブラウザーを追加する方法がわかったところで、テスト結果を取り込んで表示するレポート機能をさらに追加する方法を検討します。

まず始めに、dots レポート機能を karma.conf.js の reporters 配列に追加します。すると、次に「grunt test」と入力して実行したときには、一連のドットが画面全体を流れることになります。それぞれのドットが、合格したテストを表します。

ドットは可愛らしいものの、一時的にしか表示されないので、いくつのテストに合格したかを知るには、テストを実行している間、画面を注視していなければなりません。それよりは、多少永続的なレポート機能をインストールしたほうが妥当でしょう。

求めているものに最も近そうなのが karma-html-reporter です。図 1 の例に示されているように、それぞれのテストごとに、言葉による詳細な結果が HTML で綺麗に整形されて表示されます。

図 1. karma-html-reporter によって生成されたレポート
karma-html-reporter によって生成されたレポートのスクリーンショット
karma-html-reporter によって生成されたレポートのスクリーンショット

karma-html-reporter をインストールするには、「npm install karma-html-reporter --save-dev」と入力して実行します。インストールが完了した後、このレポート機能を構成するために、karma.conf.js を以下のように編集します。

reporters: ['progress', 'html'],

htmlReporter: {
  outputDir: 'karma_html'
},

すべての構成オプションについては、karma-html-reporterパッケージの詳細を参照してください。

洗練された HTML 出力ではなく未加工の XML 出力が必要な場合は、karma-junit-reporter をインストールすることを検討してください。これをインストールするには、「npm install karma-junit-reporter --save-dev」と入力して実行します。その後、プロジェクト・サイトに記載されているように、karma.conf.js 内でこのレポート機能を構成します。

npm Web サイトでは、他のランチャーを検索するために「karma launcher」と入力しました。同じように、「karma reporter」と入力すれば、他の Karma レポート機能を検索することができます。

Karma および istanbul でコード・カバレッジを表示する

どのテスティング・インフラストラクチャーでも、テスト・コード・カバレッジを表示できなければ完全なものとは言えません。これまで取り上げたレポートに表示されたのは、合格したテストと失敗テストだけで、作成し忘れたテストは表示されませんでした。優れたコード・カバレッジ・ツールは、表示されている行ごとに、コード・ベースのどの部分にユニット・テストがアクセスしたのかを示します。さらに重要なことに、ユニット・テストでまだアクセスしていないコードが含まれている行も示します。

npm install karma-coverage --save-dev」と入力して実行して karma-coverage プラグイン (このプラグインは istanbul ライブラリーを使用します) をインストールし、説明に従って構成すると、アプリケーションのすべてのコードを示す一連の見事なレポートが手に入ります (図 2 を参照)。

図 2. カバレッジ・レポート
karma-coverage によって生成されたレポートのスクリーンショット
karma-coverage によって生成されたレポートのスクリーンショット

緑色の行は、ユニット・テストでアクセスされたファイルであることを示しており、赤色の行は、ユニット・テストでこれからアクセスされるのを待っているファイルであることを示しています。

依存関係のモックを作成する

適切に作成されたユニット・テストの特徴は、テストの非依存性にあります。これらのユニット・テストでは、実際のデータベースを利用することも、稼働中の Web サービスに対して実際の HTTP 呼び出しを行うこともありません。ありがたいことに、このような依存性をモックとして作成することが、テストを実行する昔ながらの方法となっています。

クライアント・サイドの Jasmine テストで実際の Alax 呼び出しを行わずに、その代わりとして AngularJS に含まれているモック・サービス $httpBackend を使用することを検討してください。

実際の MongoDB データベースをテストで使用せずに、その代わりとして Mockgoose (テストを明確な目的として、Mongoose (および MongoDB) に代わるものとして作成された純粋なインメモリー・ドロップイン) を使用することを検討してください。

Protractor.js を使用してエンド・ツー・エンドのテストを実行する

これまでは、ユニット・テストを実行してきました。ユニット・テストは、本質的に、GUI を利用しないテストであり、コード・ベースの UI 以外の部分をテストするためのものです。

では、ユーザーがアプリケーションの使用中に通常行う、入力操作やボタンのクリック操作のすべてをテストするには、どうすればよいのでしょう? Protractor.js をインストールすれば、そのような動作をテストすることができます。

完全な手順と例は Protractor のホーム・ページに揃っているので、ここでは簡単に説明します。まず、「npm install protractor --save-dev」と入力して実行し、このライブラリーをインストールします。次に、特定の URL にアクセスして、ページ上の特定のコンポーネントを操作する Jasmine テストを作成します。リスト 4 に、プロジェクトのホーム・ページから引用した Protractor テストの一例を記載します。

リスト 4. Protractor テスト
describe('angularjs homepage todo list', function() {
  it('should add a todo', function() {
    browser.get('http://www.angularjs.org');

    element(by.model('todoText')).sendKeys('write a protractor test');
    element(by.css('[value="add"]')).click();

    var todoList = element.all(by.repeater('todo in todos'));
    expect(todoList.count()).toEqual(3);
    expect(todoList.get(2).getText()).toEqual('write a protractor test');
  });
});

おそらく見ておわかりのとおり、このテストは AngularJS ホーム・ページにアクセスし、todoText 要素を見つけてテスト・ストリングを入力し、追加ボタンをクリックします。その後、一連のアサーションを実行して、期待される値が表示されることを確認します。

まとめ

前にも言ったように (そしていつも言っているように)、1 つのテストは千件の意見に匹敵します。そうは言っても、信頼できるソフトウェア・プラクティスで裏付けできなければ、生意気な発言は意味をなしません。この記事で学んだ教訓を実践すれば、この急速に変化し続けるソフトウェア・エコシステムの一部となるには欠かせない「エンジニアリングの厳格さ」へ向けて順調に進むことになります。


ダウンロード可能なリソース


関連トピック

  • AngularJS 「Unit Testing」: AngularJS 「Developer Guide」の「Unit Testing」セクションを調べてください。
  • MEAN.JS によるテスティングのためのドキュメント: MEAN.JS のドキュメントで、テスティングに関するセクションを調べてください。
  • Karma: Karma に関するあらゆることを調べ、このプロジェクト・サイトで Karma で使用可能なプラグインを参照してください。
  • PhantomJS: スクリプトを実行できる、このヘッドレス・ブラウザーについて学んでください。
  • Mocha: Mocha のホーム・ページにアクセスしてドキュメントやサンプルを参照してください。
  • Jasmine: Jasmine のドキュメントを調べてください。

コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Web development, Open source
ArticleID=1015421
ArticleTitle=MEAN をマスターする: MEAN スタックのテスト
publish-date=10012015