Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo...

37
Javaアプリケーション 開発における テストとTDDの実践 Shuji Watanabe (@shuji_w6e) 1

description

 

Transcript of Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo...

Page 1: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

Javaアプリケーション 開発における

テストとTDDの実践

Shuji Watanabe (@shuji_w6e)

1

Page 2: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

自己紹介

Page 3: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

渡辺 修司 / @shuji_w6eJUnit実践入門(技術評論社)

クラスメソッド株式会社

札幌にて在宅勤務

AWS関連

ポータルサイト構築

Spring, Ember.js, d3-data

4刷!累計1万部

Page 4: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

クラスメソッド札幌オフィス開設!AWSエンジニア / iOSエンジニア

U/Iターン歓迎!

7月初旬 開設予定!

アプリ屋から 移籍可能

Page 5: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

Javaアプリケーション 開発における

テストとTDDの実践

Shuji Watanabe (@shuji_w6e)

5

Page 6: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

Javaアプリケーション 開発における

テストとTDDの実践

Shuji Watanabe (@shuji_w6e)

6

Page 7: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

Long live testing ?

Page 8: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

http://www.flickr.com/photos/peakman2/1017866785/

_人人人人人人人人人_  > レガシーコード <   ̄Y^Y^Y^Y^Y^Y^Y^Y ̄

Page 9: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

http://www.flickr.com/photos/bsom/4625185702/

貴様のプロジェクトでは、効果的なテストをしてるか?

Page 10: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

自動化テストの成熟度0 自動化されたテストを行っていない、標準出力

1 効果的とは言えないが、一部のテストを自動化している

2主要な部分のテストは自動化され、継続的インテグレーションなどの「自動化」をはじめている

3プロジェクト計画やアーキテクチャが自動化されたテス トを前提としている

4テストをはじめとした「自動化」が開発プロセスに組み込まれている

5自動化が開発プロセスに組み込まれ、プロジェクトやチームに合わせて改善を続けている

Page 11: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

ユニットテストは基本スキル最初から出来る人はいません

たくさん書けばそれだけ覚えます

TDDBC, JJUG CCCなど勉強会にでましょう

社内でテスト勉強会をやりましょう

JUnit実践入門がオススメです!

Page 12: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

http://www.flickr.com/photos/palermobootcamp/5464512672/

TDD!TDD!

テスト!テスト!

Page 13: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

継続的インテグレーションと

ユニットテスト

Page 14: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

手作業したら負け

Page 15: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

継続的インテグレーションバージョン管理システムと連動

コミット毎にテストなどを自動実行

テスト失敗時に通知(メールなど)

簡単に導入可能

Jenkinsがスタンダード

Page 16: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

自動化された開発環境の例

Page 17: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

自動化のメリット手作業によるコストの削減

手作業によるミスの削減

コンピューティングリソースを有効活用

文句を言わずに繰り返し何度でも実行

楽しいw

Page 18: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

http://www.flickr.com/photos/jas_132/5403388208

ユニットテストは 最高のパートナー

Page 19: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

ユニットテストの特徴自動的に実行可能なプログラム

実行コスト < 実装コスト / 手動テスト

変更の影響がなければ常に成功を維持

早い段階から繰り返し実行することで 効果が最大となる

Page 20: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

テストの実装時期とテスト回数

コード量/開発の進捗

テスト数

テスト 回数

A

B

C

テスト 回数

テスト 回数

Page 21: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

変更毎にテストを実行ソースコードの修正の影響

可能な限り早く影響を検知

リグレッション(デグレーション)対策

× 防止する ○ 即座に修正できるようにする

Page 22: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

Amazon EC2の活用Elasticなコンピューティングリソース

調達が容易

必要に応じて起動すればコストも削減

VPN接続も可能

簡単構築、簡単インストール

Page 23: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

データベースを操作するメソッドのテスト

Page 24: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

DAO, Repository, EntityManagerモデルの永続化を行うレイヤー

RDBとの通信部分を分離する

Hibernate, S2Dao などのフレームワーク

Page 25: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

永続化層のユニットテスト戦略外部システムに依存する部分はモック派

外部システムに依存すべきでない

実行に時間がかかるのはよくない

RDBは実質的にシステム内部とみなす派

SQLやクエリ実行まで含めて実装

時間がかかってもテストしたい

Page 26: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

4 Phase Test初期化 ー Setup テスト実行時の状態を一定にする 実行 ー Exercise テスト実行後の影響を観測する 検証 ー Verify 期待する結果となるかを検証する 後処理 ー Teardown 次のテストへの影響させない

Page 27: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

初期化 ー SetupDBデータの初期化

関連テーブルの削除

シーケンス

システム時間

初期化にかかる処理時間

テスト用データの準備

すべて自前で行うのは かなり大変....

Page 28: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

実行 ー Exerciseテスト対象オブジェクト(Daoなど)の準備

フレームワークのは単体で実行できるか?

コネクションプールやデータソース

トランザクション境界

1つのメソッド(SQL)毎にテストを実行

DBの状態によって結果も変わる

Page 29: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

検証 ー Verifyモデルの検証

Assertion / Hamcrest Matcher API

シーケンス番号、システム時間などの除外

順番に注意(order by)

DBデータへの反映の検証

Create, Update, Deleteでは必須

Page 30: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

後処理 ー Teardown1つのテストで複数のことを検証しない

次のテストの初期化に任せて何もしない

テスト失敗時、DBの状態が残る

Page 31: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

テスト方針リアルDBを利用

フィクスチャはYAMLフォーマットで定義

初期化処理でDBをセットアップ

後処理ではDBを操作しない

JUnit, DbUnit, cmtest-db を利用

Page 32: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

DbUnit JUnitの拡張フレームワーク

JUnit 3系

データベースの初期化と後処理

フィクスチャ(データ)

検証

http://dbunit.sourceforge.net/

Page 33: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

public class SampleTest extends DBTestCase { protected void setUp() throws Exception { super.setUp(); DatabaseOperation.CLEAN_INSERT .execute(connection, dataSet); } public void testMe() throws Exception { IDataSet databaseDataSet = getConnection().createDataSet(); ITable actualTable = databaseDataSet.getTable("TABLE_NAME"); IDataSet expectedDataSet = new FlatXmlDataSetBuilder() .build(new File("expectedDataSet.xml")); ITable expectedTable = expectedDataSet.getTable("TABLE_NAME"); Assertion.assertEquals(expectedTable, actualTable); } }

Page 34: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

cmtest-dbDbUnitのラッパーライブラリ

JUnit4対応

YAMLによるフィクスチャ

アノテーションによるテストの定義

JUnit4系のモダンなテストコードを実現

https://github.com/classmethod/cmtest/tree/master/cmtest-db

Page 35: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

public class UserRepositoryTest { @Rule public DbUnitTester tester = DbUnitTester .forJdbc("com.mysql.jdbc.Driver", "jdbc:mysql://localhost:3306/cmtest") .username("root").password("").create(); @Fixture(resources = "2-users.yaml") @Test public void updateによる更新() throws Exception { IDataSet expected = YamlDataSet .load(getClass().getResourceAsStream("yaml")); sut.update(user); tester.verifyTable("users", expected); } }

Page 36: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014

その他のポイントフィクスチャ重要

0件の場合、1件の場合、2件の場合

Enclosedテストランナーを活用

ローカル実行

スローテスト

システム時間など難しい部分は無視も一手

Page 37: Javaアプリケーション開発におけるユニットテストとTDDの実践 Java Day Tokyo 2014