Show page source of FrontPage #27331

= !DbUnitNG プロジェクト Wiki =

== 概要 ==
こんなのができます。
{{{ code java
	@SetUpOperation(value = DatabaseOperationType.CLEAN_INSERT, pathname = "org/dbunitng/dept-emp.xml")
	@Test
	public void verifySelectAllFromDept() {
		// call target method and assert...
	}
}}}

!DbUnitのアノテーション対応。

@!SetUpOperationでテスト実行前にテストデータを投入する。
アノテーションの属性で!DbUnitの!DatabaseOperationを指定したり、テストデータのファイルを指定したりできる。

さすがに単体ではできないので、TestNGと連携させます。


----


== !DbUnitアノテーション化ライブラリ「!DbUnitNG」 ==

!DbUnitNG(http://sourceforge.jp/projects/dbunitng/)は!DbUnit(http://www.dbunit.org/)の機能をアノテーションとして利用するためのオープンソースライブラリです。

テスト実行前の初期データの投入や実行後のクリーンアップ処理をコードで書く必要はなく、アノテーションで設定できます。

!DbUnitNGはテスティングフレームワークTestNG(http://testng.org/doc/)のリスナーとして実装しているため、設定ファイルに数行記述するだけで簡単に利用できます。

'''!DbUnitNGには大きく3つの機能があります。'''
 * !DbUnitを利用した初期データ投入やクリーンアップ処理をアノテーションで設定できる
 * Java BeansのListを!DbUnitのデータセットに変換し、期待値ファイルの内容と比較検証できる
 * データベースのテーブルの内容と期待値ファイルの内容を自動的に比較検証するアノテーションを利用できる

初期データの投入や期待値とプログラムの実行結果の比較検証といった、データベースに実際に接続してテストを実施する際に必要となる処理をアノテーションで設定できることでテスト作成の工数を削減します。

またテストプログラムの作成自体はTestNGをそのまま利用できるため、学習のコストは非常に低く、TestNGと!DbUnitを連携する作業もまったく必要ありません。


----


== 依存ライブラリ ==

依存ライブラリは以下。

 * TestNG
 * !DbUnit
 * Commons Lang
 * JUnit 4.x(!DbUnitが依存)
 * SLF4J(!DbUnitが依存。slf4j-api.jarとslf4j-nop.jarが必要。)
 * Commons Collections(!DbUnitが依存)
 * Apache POI(!DbUnitが依存。テストデータをExcelに記述する場合必要。)
 * Commons DBCP(利用する場合必要)
 * Commons Pool(DBCPを利用する場合必要)

== !DbUnitアノテーションの使い方 ==

=== TestNGとの連携 ===
TestNGのリスナーとして!DbUnitとの連携を実現します。
testng.xmlにリスナーを記述します。

{{{
	<listeners>
		<listener class-name="org.dbunitng.listeners.DbUnitNGTestListener"></listener>
	</listeners>
}}}

TestNGのテストスイートファイルであるtestng.xmlにデータベース接続情報を記述します。
{{{
<parameter name="driver" value="com.mysql.jdbc.Driver"></parameter>
<parameter name="url" value="jdbc:mysql://127.0.0.1/データベース名"></parameter>
<parameter name="username" value="ユーザー名"></parameter>
<parameter name="password" value="パスワード"></parameter>
}}}

データベースに接続する際のConnectionは、特に指定がなければ!DriverManagerで生成します。
もしテストメソッド間で!DataSourceを利用したい場合、testng-xmlに「DBCP」と指定します。
{{{
<parameter name="datasource" value="DBCP"></parameter>
}}}
この場合、もちろんDBCPとPoolのJARが必要です。

また、[DatabaseConnectivity DbUnitNGアノテーション]に接続情報を記述することもできます。

==== デフォルトの!DatabaseOperation ====
@!SetupOperationで!DbUnitの!DatabaseOperationを指定できるわけですが、
テストメソッドごとに毎回指定するのは手間なので、
テストスイート全体でデフォルトを設定できるようにしました。

testng.xmlか@!DbUnitNGアノテーションで指定することができます。
もちろんデフォルトを指定しないこともできます。

こんな感じです。
{{{ code java
@BeforeSuite
@!DbUnitNG(driver = "com.mysql.jdbc.Driver", password = "root", url = "jdbc:mysql://127.0.0.1/testframework", username = "root", defaultOperation = DatabaseOperationType.CLEAN_INSERT)
public void beforeSuite() {}
}}}
アノテーションであればdefaultOperation属性にEnumの!DatabaseOperationTypeを指定します。

XMLであれば<parameter>要素にname「defaultOperation」で指定します。
{{{ code xml
<suite name="!DbUnitNG">
	<parameter name="defaultOperation" value="CLEAN_INSERT"></parameter>
	<parameter name="driver" value="com.mysql.jdbc.Driver"></parameter>
	<parameter name="url" value="jdbc:mysql://127.0.0.1/testframework"></parameter>
	<parameter name="username" value="root"></parameter>
	<parameter name="password" value="root"></parameter>
}}}
defaultOperationの値は次の文字列を指定します。
 * NONE
 * UPDATE
 * INSERT
 * REFRESH
 * DELETE
 * DELETE_ALL
 * TRUNCATE_TABLE
 * CLEAN_INSERT 

もちろん、デフォルトを指定していても@!SetUpOperationや@!TearDownOpearionで指定すれば、後者を優先します。

=== アノテーション ===

テストメソッド(@Testを付与したメソッド)に対して、初期データの投入を@!SetUpOperationで指定します。
@!SetUpOperationに属性を指定します。

 * value(データベース操作方法の指定。要は!DbUnitの!DatabaseOperationの定数。デフォルトはNONE。)
 * pathname(テストデータを記述したファイルパス。クラスパスでの位置。)

valueにはEnumである!DatabaseOperationTypeを指定します。


こんな感じで指定します。
{{{
@SetUpOperation(value = DatabaseOperationType.CLEAN_INSERT, pathname = "org/dbunitng/dept-emp.xml")
}}}
!DbUnitと同様で、XML形式とExcel形式に対応してます。
!DatabaseOperationTypeは8つの値があります。

 * NONE
 * UPDATE
 * INSERT
 * REFRESH
 * DELETE
 * DELETE_ALL
 * TRUNCATE_TABLE
 * CLEAN_INSERT

意味は!DbUnitそのままです。

これでテストメソッド実行前にテストデータを投入します。

==== CSV対応 ====

初期値や期待値のファイルとしてCSVにも対応しました。

!DbUnitではCSVファイルの場合「table-ordering.txt」というファイルが必須なので、このファイルをアノテーションに指定した場合、CSVとして処理します。

「table-ordering.txt」は定数として!DbUnitNGConstrantsにあります。
こんな感じです。
{{{ code java
@SetUpOperation(pathname = DbUnitNGConstrants.CSV_ORDER_FILE, value = DatabaseOperationType.CLEAN_INSERT)
public void testCsvFile() {
}
}}}
pathname属性にファイル名「table * ordering.txt」だけ指定しているので、テストクラスと同じパッケージに配置します。

「table-ordering.txt」はこんな感じ。
{{{ code 
dept
emp
}}}
テーブル名を記述します。
そして、この名前に対応するCSVファイルをテキストファイルと同じパッケージに配置します。dept.csvとemp.csvです。
{{{ code 
DEPTNO,DNAME,LOC
10,ACCOUNTING,NEW YORK
}}}
{{{ code 
EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO
7782,CLARK,MANAGER,7839,1981 * 01 * 09,2450.0,null,10
}}}
1行目は列名、2行目以降にデータを記述します。nullの場合はそのままnullと書きます。


== BeanのListを!DbUnitの!DataSetに変換

[BeanList BeanのリストをDbUnitのDataSetに変換してアサートできます。]

== パフォーマンス ==

[PerformanceTest 簡単なパフォーマンステストを実行しました。]

== DBからテストデータのファイルを作成 ==

[TestData DbUnitライブラリでDBデータをXML,Excel,CSVに出力するクラスを作りました。]

== DBテーブルと期待値ファイルをアノテーションでアサートする

[TableAssert @TableAssertでDBとアサートできます]