作成 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