作成 2004/9/10
今度使うらしいのでちょっとさわってみた。ちょっとだけ。
DBUnitとは、データベースを含むプログラムの単体テストツールです。アプリケーション開発では、多くの場合、データベースを利用します。DBを更新したり、DBから値を取得する単体テストを書くとき、「テスト用のデータのセットアップ」や「更新されたデータの確認」などを行うのは、非常に骨の折れる作業です。DBUnitは、そのような骨の折れる作業を低減させてくれる方法とツールを提供しています。
DBUnitは以下のWebページからダウンロードします。
DBUnitのWebページ
http://dbunit.sourceforge.net/
ここでは現在の最新バージョンの2.1をダウンロードしました。
ここではMySQLを利用して、簡単なデータベースとテーブルを作成し、それを利用したテストを記述します。テーブルは以下です。
CREATE TABLE CD( TITLE VARCHAR(100), PRICE INTEGER, DATE DATE, PRIMARY KEY(TITLE) );
ついでに以下のようなデータを入れておきます。
insert into cd values('レレレ',1000,'2004-10-10'); insert into cd values('いかだに乗ってどこまでも',2000,'2005-12-10');
DBUnitでは、まずテスト用のデータを準備します。データは基本的にXMLで記述します。データは、データベースからエクスポートするか、あるいは手で記述します。テストデータのエクスポートにはDBUnitのAntタスクが利用します。
DBUnitのAntタスクを使って、DBからデータをエクスポートすることができます。
エクスポートを行うAntビルドファイルの例
<project name="hoge" default="hoge"> <taskdef name="dbunit" classname="org.dbunit.ant.DbUnitTask"> <classpath id="class.path"> <fileset dir="lib"/> </classpath> </taskdef> <target name="hoge"> <dbunit driver="com.mysql.jdbc.Driver" url="jdbc:mysql:///blog?useUnicode=true&characterEncoding=SJIS" userid="root" password=""> <export dest="data/export.xml"/> </dbunit> </target> </project>
このタスクを実行すると、以下のファイルが出力されます。DBのデータがXML形式で出力されているのがわかります。
<?xml version='1.0' encoding='UTF-8'?> <dataset> <cd TITLE="いかだに乗ってどこまでも" PRICE="2000" DATE="2005-12-10"/> <cd TITLE="レレレ" PRICE="1000" DATE="2004-10-10"/> </dataset>
なお、XMLの出力形式には、xmlとflatの2種類があり、形式により、DBUnitからの利用法も若干異なるので注意してください。上記の例はflat(デフォルト)の出力です。
DBUnitのAntタスクは、エクスポートの他に、DTDエクスポートや、インポート、データの比較など、いろいろと操作が出来ます。DTDを出力すると、補完機能のついたXMLエディタでデータの編集がやりやすかったりします。どんなタスクが利用できるかは、以下をご覧ください。
http://dbunit.sourceforge.net/anttask.html
次にJavaで単体テストを記述します。やることは、以下のことです。
ここでは、以下のようなファイル構成でプロジェクトを作成しました。
DBUnitを利用したテストを行うには、以下のJARをクラスパスに含めます。
テストを行うには、何かの処理を行うクラスが必要です。ここでは、簡単ですが、以下のクラスを用意しました。ConnectionManagerはDBに接続してConnectionを取得するクラスと考えてください。
Sample.java(何かDB処理を行うクラス)
package hoge; import java.sql.Connection; import java.sql.Statement; public class Sample { public void tatakiuri() throws Exception{ Connection con = ConnectionManager.getConnection(); Statement smt = con.createStatement(); smt.execute("update cd set price=10"); //con.commit();//autocommit con.close(); } }
このクラスに対する単体テストを記述します。次のようになります。
SampleTest.java(テストケースの例)
package hoge; import junit.framework.TestCase; import org.dbunit.Assertion; import org.dbunit.database.DatabaseConnection; import org.dbunit.database.IDatabaseConnection; import org.dbunit.dataset.IDataSet; import org.dbunit.dataset.ITable; import org.dbunit.dataset.xml.FlatXmlDataSet; import org.dbunit.operation.DatabaseOperation; public class SampleTest extends TestCase { public void testTatakiuri() throws Exception { //準備データをDBに入れる DatabaseOperation.CLEAN_INSERT.execute(getConnection(), new FlatXmlDataSet(SampleTest.class .getResourceAsStream("prepare.xml"))); //ロジックの実行 Sample sample = new Sample(); sample.tatakiuri(); //DBから実際のデータの取得 IDataSet databaseDataSet = getConnection().createDataSet(); ITable actualTable = databaseDataSet.getTable("cd"); //期待値データの取得 IDataSet expectedDataSet = new FlatXmlDataSet(SampleTest.class .getResourceAsStream("expected.xml")); ITable expectedTable = expectedDataSet.getTable("cd"); //期待値と実際のデータの比較 Assertion.assertEquals(expectedTable, actualTable); } protected IDatabaseConnection getConnection() throws Exception { return new DatabaseConnection(ConnectionManager.getConnection()); } }
次に準備データと期待値データを用意します。準備データは先ほどAntタスクでエクスポートしたXMLをそのまま利用します。期待値データは、準備データをコピーして値を書き換えます。
expected.xml(期待結果のデータ)
<?xml version='1.0' encoding='UTF-8'?> <dataset> <cd TITLE="いかだに乗ってどこまでも" PRICE="10" DATE="2005-12-10"/> <cd TITLE="レレレ" PRICE="10" DATE="2004-10-10"/> </dataset>
これでJUnitテストを実行すると、テストが実行できます。ここではテストメソッド内でデータ準備を行っていますが、setUp()で行ってもいいでしょう。また、DBUnitのWebページのチュートリアル(Qucik Start)では、TestCaseでなく、DatabaseTestCaseを継承した例が示されています。ここでは更新系のテストなので、期待値データを準備しましたが、照会系であれば、いらないでしょう。また、テストデータをクラスパス(ソースパス)に含めていますが、別のフォルダに置いてもいいでしょう。テストのやり方はいろいろ考えられます。
DBUnitのテスト用データは基本はXMLですが、元々2次元のテーブルデータであるわけで、やっぱりEXCELなどでデータは編集した方がやりやすいです。DBUnitでは、EXCELデータも読み込めるようになっています。
まず、DBからのエクスポートですが、Antタスクはない(マニュアル上は)ようなので、とりあえずコードを書いてエクスポートします。といっても2、3行のコードです。
XLSExporter.java(DBデータをEXCELにエクスポート)
package hoge; import java.io.FileOutputStream; import org.dbunit.database.DatabaseConnection; import org.dbunit.dataset.IDataSet; import org.dbunit.dataset.excel.XlsDataSet; public class XLSExporter { public static void main(String[] args) throws Exception { DatabaseConnection con = new DatabaseConnection(ConnectionManager .getConnection()); IDataSet dataset = con.createDataSet(); XlsDataSet.write(dataset, new FileOutputStream("export.xls")); } }
出力されたファイルは次のようになっています。これを元に、準備データや期待値データを作成します。
で、テストケース上では、FlatXmlDataSetを利用していたところを、XlsDataSetに変えればEXCELデータを読み込んでのテストが行えます。
なお、XlsDataSetは内部でJakarta POI(http://jakarta.apache.org/poi/)を利用しているので、上記を実行するには、POIをダウンロードしてきて、JARをクラスパスに含める必要があります。一応最新リリースの2.5.1では動きました。
と、まあ、DBUnitを非常に簡単に利用してみました。私自身が全然使いこなしてないので、なんちゃってですが、以下感想です。
今回作ったサンプル
dbunit1.zip
JavaPress vol.34 Eclipseによるデータベースプログラミング DbEdit+XMLBuddyプラグインでDbUnitを利用する
http://www.gihyo.co.jp/magazines/javapress/contents/Vol34
[それはBooks]DBUnitでデータベーステスト
http://xlegend.dip.jp/~hamasyou/archives/Engineer-Soul/dbunitcuedbeditxmlbuddy.php