アプリケーションのテスト
自動実行できるテストスイートを作成するのは、アプリケーションを堅牢にする良い方法です。自動テストスイートを作成することで、アジャイルなやり方で作業することができます。
Play のテストは、何をテストするかによって Junit 4 または Selenium を使って作成されます。
テストの記述
テストは test/
ディレクトリに作成されなければなりません。アプリケーションが test
モードで実行するときにだけ、このフォルダはソースパスに加えられます。テストは、異なる 3 種類の方法で書くことができます。
単体テスト
単体テストは JUnit を使用して書かれます。このテストでは、(いくつかのユーティリティを含む) アプリケーションのモデルをテストすることができます。
単体テストの例を以下に示します:
import play.test.*;
import org.junit.*;
public class MyTest extends UnitTest {
@Test
public void aTest() {
assertEquals(2, 1 + 1); // A really important thing to test
}
@Test
public void testUsers() {
assertEquals(3, Users.count());
}
}
機能テスト
機能テストは JUnit を使用して書かれます。このテストでは、直接コントローラオブジェクトにアクセスすることでアプリケーションをテストします。
機能テストの例を以下に示します:
import play.test.*;
import play.mvc.*;
import play.mvc.Http.*;
import org.junit.*;
public class ApplicationTest extends FunctionalTest {
@Test
public void testTheHomePage() {
Response response = GET("/");
assertStatus(200, response);
}
}
レスポンスそのものに関するアサーションを作成する代わりに、 renderArgs()
メソッドを使うことでビューに渡された引数に直接アクセスすることができます。例えば:
@Test
public void testUserIsFoundAndPassedToView() {
Response response = POST("/user/find?name=mark&dob=18011977");
assertThat(renderArgs("user"), is(notNullValue()));
User user = (User) renderArgs("user");
assertThat(user.name, is("mark"));
}
Selenium テスト
受入テストは Selenium を使用して書かれます。このテストでは、自動化されたブラウザでこれを実行することでアプリケーションをテストします。
Selenium テストは HTML テーブルを使用して書かれます。従来のこの構文を使用するか、または #{selenium /}
タグを使用することができます。
Selenium テストの例を以下に示します:
#{selenium 'Test security'}
// Try to log in the administration area
clearSession()
open('/admin')
assertTextPresent('Login')
type('login', 'admin')
type('password', 'secret')
clickAndWait('signin')
// Verify that the user in correctly logged in
assertText('success', 'Welcom admin!')
#{/selenium}
Slenium テストはブラウザを通して実行されるので、モックで送信された e メールや、Play Cache に格納された文字列にアクセスするためには、Selenium エクステンションを使用しなければなりません。
あるアカウントに送信された最近の e メールにアクセスする例を以下に示します:
#{selenium 'Test email sending'}
// Open email form and send an email to boron@localhost
open('/sendEmail')
assertTextPresent('Email form')
type('To', 'boron@localhost')
type('Subject', 'Berillium Subject')
clickAndWait('send')
// Extract the last email sent to boron@localhost into a JavaScript
// variable called email
storeLastReceivedEmailBy('boron@localhost', 'email')
// Extract the subject line from the email variable into a variable
// called subject
store('javascript{/Subject:\s+(.*)/.exec(storedVars["email"])[1]}', 'subject')
// Test the contents of the subject variable
assertEquals('Berillium Subject', '$[subject]')
#{/selenium}
Play Cache に格納された文字列 (例えば、キャプチャに対する正しい答え) にアクセスする例を以下に示します:
#{selenium 'Get string from cache'}
open('/register')
assertTextPresent('Registration form')
type('Email', '[email protected]')
type('Password', 'secretpass')
type('Password2', 'secretpass')
// .. Fill in the registration form ..
// Get the value of the magicKey variable from the cache
// (set to the CAPTCHA answer in the application)
storeCacheEntry('magicKey', 'captchaAnswer')
// Type it into the form
type('Answer', '$[captchaAnswer]')
clickAndWait('register')
#{/selenium}
フィクスチャ
テストを実行するとき、アプリケーションのための安定したデータを必要とします。最も簡単な方法は、各テストの前にデータベースをリセットすることです。
play.test.Fixtures
クラスは、データベースを操作して、テストデータを注入する手助けをします。通常、これは JUnit テストの @Before
メソッドで使用します。
@Before
public void setUp() {
Fixtures.deleteDatabase();
}
データをインポートするには、Fixtures が自動的にインポートすることができる YAML ファイルに定義するのが簡単です。
# Test data
Company(google):
name: Google
Company(zen):
name: Zenexity
User(guillaume):
name: guillaume
company: zen
その後、以下のようにします:
@Before
public void setUp() {
Fixtures.deleteDatabase();
Fixtures.loadModels("data.yml");
}
YAML マニュアルページ で Play と YAML について詳しく読むことができます。
Selenium テストのために #{fixture /}
タグを使用することができます:
#{fixture delete:'all', load:'data.yml' /}
#{selenium}
// Write your test here
#{/selenium}
データをいくつかの YAML ファイルに分割すると便利な場合があります。複数のファイルかた一度にフィクスチャをロードすることができます:
Fixtures.loadModels("users.yml", "roles.yml", "permissions.yml");
Selenium テストは以下のようになります:
#{fixture delete:'all', load:['users.yml', 'roles.yml', 'permissions.yml'] /}
テストの実行
テストを実行するには、 play test
コマンドを使ってアプリケーションを test
モードで実行しなければなりません。
# play test myApp
このモードでは、Play は自動的に test-runner
モジュールをロードします。このモジュールは http://localhost:9000/@tests という URL で利用可能な Web ベースのテストランナーを提供します。
テストを実行すると、その結果はアプリケーションの /test-result
ディレクトリに保存されます。
テストランナーページでは、各テストはリンクになっています。‘右クリック’ して ‘新しいタブで開き’ 、テストランナーの外で直接実行することができます。
この方法でテストを実行する場合、Play は特別なフレームワーク ID test
で始動します。このため、 application.conf
ファイルで特別な設定を定義することができます。
いくつかの異なるテスト設定が必要な場合、パターン test-?.*
にマッチするフレームワーク ID (例: ‘test-special’) を使用することができます。
デフォルトの test
とは違うフレームワーク ID を使用する場合は、@application.conf@ にあるすべてのテスト用設定が、そのフレームワーク ID で利用可能であることをしっかりと確認しなければなりません。特別なテストフレームワーク ID でテストを起動するときは、このようにします: 'play test --%test-your-special-id'
例えば
%test.db=mem
%test.jpa.ddl=create-drop
継続的統合と自動的なテストの実行
auto-test
コマンドは test
コマンドと同じことをしますが、こちらは自動的にブラウザを起動し、すべてのテストを実行し、そして停止します。
継続的統合システムを構築する場合、これは便利なコマンドです;
実行後、すべての結果は /test-result
ディレクトリに保存されます。さらに、このディレクトリにはテストスイートの最終的な結果を示すマーカーファイル ( result.failed
または result.passed
のどちらか) を含んでいます。最終的に、このディレクトリは application.log
ファイルにすべてのログを含みます。
このためアプリケーションをテストするための継続的統合システムシステムの構築手順は、以下のようになるかもしれません:
- 最新版のアプリケーションをチェックアウトする
play auto-test
を実行する- プロセスの完了を待つ
/test-result
ディレクトリ内のマーカファイルresult.passed
またはresult.failed
を確認する
これらの手順が CRON タブで実行されれば完了です!
headlessBrowser を設定することで、ヘッドレスブラウザによって利用される web ブラウザ互換性を変更することができます。
考察を続けます
Next: セキュリティガイド.