35.3. Seam アプリケーションのユーザーインタラクション統合テスト
さらに難しいことはユーザーインタラクションを模倣し、 適切にアサーションを配置することです。 テストフレームワークの中には Web ブラウザでユーザーのインタラクションを再生することでアプリケーション全体をテストできるものがあります。このようなフレームワークは便利ですが、 開発段階での使用には適していません。
SeamTest を使用して擬似 JSF 環境で スクリプト化した テストを記述することができます。 スクリプト化したテストは、 ビューと Seam コンポーネント間のやりとりを再現するため、 テスト中は JSF 実装の役割を演じることになります。 この方法ならビュー以外のあらゆるものすべてがテスト可能です。
上記でユニットテストしたコンポーネントの JSP ビューを考えてみましょう。
<html>
<head>
<title>Register New User</title>
</head>
<body>
<f:view>
<h:form>
<table border="0">
<tr>
<td>Username</td>
<td><h:inputText value="#{user.username}"/></td>
</tr>
<tr>
<td>Real Name</td>
<td><h:inputText value="#{user.name}"/></td>
</tr>
<tr>
<td>Password</td>
<td><h:inputSecret value="#{user.password}"/></td>
</tr>
</table>
<h:messages/>
<h:commandButton type="submit" value="Register"
action="#{register.register}"/>
</h:form>
</f:view>
</body>
</html>
このアプリケーションの登録機能 (ユーザーが Register ボタンをクリックしたときの動作) をテストしたいとします。 TestNG 自動テストで JSF 要求のライフサイクルを再現してみます。
public class RegisterTest extends SeamTesFt {
@Test
public void testRegister() throws Exception {
new FacesRequest() {
@Override
protected void processValidations() throws Exception {
validateValue("#{user.username}", "1ovthafew");
validateValue("#{user.name}", "Gavin King");
validateValue("#{user.password}", "secret");
assert !isValidationFailure();
}
@Override
protected void updateModelValues() throws Exception {
setValue("#{user.username}", "1ovthafew");
setValue("#{user.name}", "Gavin King");
setValue("#{user.password}", "secret");
}
@Override
protected void invokeApplication() {
assert invokeMethod("#{register.register}").equals("success");
}
@Override
protected void renderResponse() {
assert getValue("#{user.username}").equals("1ovthafew");
assert getValue("#{user.name}").equals("Gavin King");
assert getValue("#{user.password}").equals("secret");
}
}.run();
}
...
}
ここで
SeamTest を拡張し、コンポーネントに Seam 環境を提供し、テストスクリプトは SeamTest.FacesRequest を拡張する匿名クラスとして記述されています。 これにより模倣された JSF 要求ライフサイクルを提供しています (GET 要求をテストする SeamTest.NonFacesRequest もあります)。コードには各種の JSF フェーズ用に名前が付けられたメソッドが含まれ、 コンポーネントに対して JSF が行うであろう呼び出しを模倣します。 さらに、さまざまなアサーションもあります。
Seam のサンプルアプリケーションにはさらに複雑なケースのデモを行うことができる統合テストが用意されています。 これらのテストは Ant または Eclipse 用の TestNG プラグインを使用して実行します。
35.3.1. 設定 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
seam-gen でプロジェクトを作成した場合は、 すぐにテストを書き始めることができます。そうでない場合は、Ant、Maven、 Eclipse などのビルドツールでまずテスト環境を設定する必要があります。
少なくとも 次の依存が必要となります。
| グループ ID | アーティファクト ID | Seam での場所 |
|---|---|---|
org.jboss.seam.embedded | hibernate-all | lib/test/hibernate-all.jar |
org.jboss.seam.embedded | jboss-embedded-all | lib/test/jboss-embedded-all.jar |
org.jboss.seam.embedded | thirdparty-all | lib/test/thirdparty-all.jar |
org.jboss.seam.embedded | jboss-embedded-api | lib/jboss-embedded-api.jar |
org.jboss.seam | jboss-seam | lib/jboss-seam.jar |
org.jboss.el | jboss-el | lib/jboss-el.jar |
javax.faces | jsf-api | lib/jsf-api.jar |
javax.el | el-api | lib/el-api.jar |
javax.activation | javax.activation | lib/activation.jar |
Embedded JBoss が起動しなくなるため、
lib/ にあるコンパイル時の JBoss AS 依存 (jboss-system.jar など) をクラスパスに置かないでください。必要に応じて Drools や jBPM などの依存を追加してください。
bootstrap/ ディレクトリには Embedded JBoss の設定が含まれているため、それをクラスパスに含める必要があります。
テストフレームワーク用の
jar ファイル、 プロジェクト、 テストの他、 JPA および Seam の設定ファイル郡もクラスパスに含めてください。 Seam は Embedded JBoss に指示して seam.properties を持つリソース (JAR やディレクトリ) はすべてそのルートにデプロイさせます。 ビルドしたプロジェクトを含むディレクトリ構造がデプロイ可能なアーカイブのそれに似ていない場合は、各リソースに seam.properties を含ませる必要があります。
デフォルトでは、生成されたプロジェクトは
java:/DefaultDS (Embedded JBoss で HSQL データソースにビルドされたもの) をテストに使用します。 別のデータソースを使用する場合は、 foo-ds.xml を bootstrap/deploy ディレクトリに置いてください。