コンテナでテストをまわせ! Java EE への自動テストの導入 1 小西高之 JBoss Technical Support Engineer Red Hat K.K.
コンテナでテストをまわせ! Twitter ハッシュタグ : #jt12_b202 小西高之 @leather_sole 2
とあるプロジェクトで... これからアプリケーションのテストを始める はい! まずはこのテストだ! 3
4
5 そんなの意味がないですよ!
6 そうさ 意味なんかない
7 俺たちは
8 俺たちは こんなテストを...
9 強いられているんだ!
10 とお考えの皆さんのためのセッションです
今日話すこと 自動テストの考え方 テストフレームワークのご紹介 デモ 実際のプロジェクトへの適用 まとめ 11
Java EE 6 Architecture Applet Container Client Web Container JSP Servlet EJB Container EJB Application Client Container Client CDI, JPA, JMS,... JSF, CDI, JPA, JMS, JAX-RS, JACC, JTA,... CDI, JPA, JMS, JAX-RS, JACC, JTA,... Database 12
自動テスト メリット リグレッションテスト 再現可能 実行時に人手が不要 デメリット テスト作成 メンテナンス 13
各テスト自動化の 難易度と効果 容易 / 簡単 テストの作成 メンテナンス 実行前処理 実行 結果確認 事後処理の難易度 小 効果 大 テストの明確さ テスト対象の変更可能性などによる自動化の効果 14 困難 / 複雑
容易 / 簡単 優先的に テストを作成 小 効果 大 自動化以外の 方法を考える 15 困難 / 複雑
テストの分類 Unit Test Integration Test System Test 16
Unit Test 個々のクラスのテスト JVM 内で閉じている 実行速度が速い Java EE 5 以降 容易にテストできるようになった コンテナの機能を補うためのオブジェクトが必要 17
Integration Test コンポーネントのテスト 例 ) 秘密鍵ファイルを使って XML に署名する コンテナ ネットワーク DB ファイルなどを使用 18
System Test フィーチャーのテスト 例 ) ユーザーとしてシステムにユーザー情報を登録する コンテナ ネットワーク DB ファイルなどを使用 19
Unit Test 容易 / 簡単 小 効果 大 20 困難 / 複雑
Integration Test 容易 / 簡単 小 効果 大 21 困難 / 複雑
System Test 容易 / 簡単 小 効果 大 22 困難 / 複雑
Integration Test の問題点 テスト作成が大変 実行に時間がかかる テストコードが脆い 効果は期待できるが テスト作成 維持にコストがかかる 23
Integration Test 容易 / 簡単 小 効果 大 24 困難 / 複雑
Integration Test 容易 / 簡単 小 効果 大 25 困難 / 複雑
26
27 Integration Test を自動化する力が欲しいか...?
28 Integration Test を自動化する力が欲しいか...?
29
Integration Test Framework のご紹介 http://arquillian.org/ 30
https://github.com/arquillian 31
Arquillian の特徴 複数のコンテナに対応 Java EE Containers Web Containers EJB Containers CDI Containers Web Container JSP Servlet JSF, CDI, JPA, JMS, JAX-RS, JACC, JTA,... EJB Container EJB CDI, JPA, JMS, JAX-RS, JACC, JTA,... https://docs.jboss.org/author/display/arq/supported+containers 32
Arquillian の特徴 JUnit/TestNGのテストケースとしてテストを作成 ビルドツール非依存 IDEの自動ビルド機能と連携 拡張可能 ( 開発中 ) Selenium, DBUnit, Andloid... 33
Arquillian 利用プロジェクトの例 Seam 3 http://seamframework.org/seam3 Apache DeltaSpike https://cwiki.apache.org/deltaspike/ JBoss AS 7 http://www.jboss.org/as7 JBoss RHQ http://www.jboss.org/rhq 34
例 CDI Bean のテスト 35
Greeter.java /** * A component for creating personal greetings. */ public class Greeter { public void greet(printstream to, String name) { to.println(creategreeting(name)); } } public String creategreeting(string name) { return "Hello, " + name + "!"; } 36
GreeterTest.java @RunWith(Arquillian.class) public class GreeterTest { } @Deployment public static JavaArchive createdeployment() { return ShrinkWrap.create(JavaArchive.class).addClass(Greeter.class).addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); } @Inject Greeter greeter; @Test public void should_create_greeting() { Assert.assertEquals("Hello, Earthling!", greeter.creategreeting("earthling")); greeter.greet(system.out, "Earthling"); } 37
GreeterTest.java @RunWith(Arquillian.class) public class GreeterTest { } @Deployment public static JavaArchive createdeployment() { return ShrinkWrap.create(JavaArchive.class).addClass(Greeter.class).addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); } @Inject Greeter greeter; @Test public void should_create_greeting() { Assert.assertEquals("Hello, Earthling!", greeter.creategreeting("earthling")); greeter.greet(system.out, "Earthling"); } Arquillian を指定 38
GreeterTest.java @RunWith(Arquillian.class) public class GreeterTest { } @Deployment public static JavaArchive createdeployment() { return ShrinkWrap.create(JavaArchive.class).addClass(Greeter.class).addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); } @Inject Greeter greeter; @Test public void should_create_greeting() { Assert.assertEquals("Hello, Earthling!", greeter.creategreeting("earthling")); greeter.greet(system.out, "Earthling"); } greeter をインジェクト 39
GreeterTest.java @RunWith(Arquillian.class) public class GreeterTest { } @Deployment public static JavaArchive createdeployment() { return ShrinkWrap.create(JavaArchive.class).addClass(Greeter.class).addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); } @Inject Greeter greeter; @Test public void should_create_greeting() { Assert.assertEquals("Hello, Earthling!", greeter.creategreeting("earthling")); greeter.greet(system.out, "Earthling"); } テストアーカイブを指定 40
GreeterTest.java @RunWith(Arquillian.class) public class GreeterTest { } @Deployment public static JavaArchive createdeployment() { return ShrinkWrap.create(JavaArchive.class).addClass(Greeter.class).addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); } @Inject Greeter greeter; @Test public void should_create_greeting() { Assert.assertEquals("Hello, Earthling!", greeter.creategreeting("earthling")); greeter.greet(system.out, "Earthling"); } 41
42 ファイル構成
デモの実行環境 Weld 1.1.1.Final embedded GlassFish 3.1 embedded JBoss AS 7.1.0.Final managed 43
Container management Embedded Remote Managed 44
Managed mode J Unit 45
Managed mode J U Arquillian class (extends BlockJUnit4ClassRunner) 46
Managed mode boot arquillian service JAR file 47
Managed mode run tests 48
Managed mode correct result undeploy shutdown 49
Managed mode J U result 50
51 DEMO
ふりかえり テスト実行速度について IDE の自動ビルドを利用 最新コンテナ : 起動が高速 52
実プロジェクトへの適用 既存のコードへの適用 DB ネットワーク 画面遷移 53
実プロジェクトへの適用 既存のコードへの適用 DB ネットワーク 画面遷移 arquillian-showcase を参照してください 54 CDI, EJB, EJB(TestNG), JAX-RS, JAX-WS, JMS, JPA, JPA-Lite, JSF, OSGi, Servlet, UI(Selenium) https://github.com/arquillian/arquillian-showcase
実プロジェクトへの適用 既存のコードへの適用 DB ネットワーク 画面遷移 55
56 新規プロジェクトの例なんて 意味がない
57 俺たちは 既存コードのメンテナンスを...
58 強いられているんだ!
59 とお考えの皆さんのためのデモです
既存コードへの 自動テストの適用 容易 / 簡単 優先的に テストを作成 小 効果 徐々に テストを追加 大 60 困難 / 複雑
DEMO 既存コードの例 :OpenAM WARファイルを読み込んで テストアーカイブを作成 テストを実行 コンテナ :JBoss Enterprise Application Platform 5.1.2 OpenAM http://forgerock.com/openam.html 61
DEMO J U 62
63 まとめ
これまでの Integration Test テスト作成が大変 実行に時間がかかる テストコードが脆い 効果は期待できるが テスト作成 維持にコストがかかる 64
Arquillian を利用した Integration Test 作成 管理 実行が容易 実行が高速 テストコードが脆くない 65
Integration Test 容易 / 簡単 小 効果 大 66 困難 / 複雑
コンテナでテストをまわせ! Java EE への自動テストの導入 ご清聴ありがとうございました 67
References Arquillian - JBoss Community http://www.jboss.org/arquillian Shrinkwrap - JBoss Community http://www.jboss.org/shrinkwrap/ Real Java Enterprise Testing http://slidesha.re/q06oxs Throwing complexity over the wall: Rapid development for enterprise Java http://slidesha.re/vl8hkw JUnit http://junit.org/ Git http://git-scm.com/ レガシーコード改善ガイド (Michael C. Feathers 著 / ウルシステムズ株式会社監訳 / 平澤章 越智典子 稲葉信之 田村友彦 小堀真義訳 / 翔泳社刊 ) Growing Object-Oriented Software Guided by Tests (Steve Freeman Nat Pryce 著 / Addison-Wesley 刊 ) Jenkins (John Ferguson Smart 著 / Sky 株式会社玉川竜司訳 / オライリージャパン刊 ) Jenkins 実践入門 ( 佐藤聖規 ( 監修 ) 和田貴久 河村雅人 米沢弘樹 山岸啓著 / 川口耕介監修 / 技術評論社刊 ) xunit Test Patterns (Gerard Meszaros 著 / Addison-Wesley 刊 ) 68 Jenkins CI http://jenkins-ci.org/http://slidesha.re/vl8hkw CloudBees http://www.cloudbees.com/ JBoss Tools http://www.jboss.org/tools