はじめに
Javaのテストフレームワークの中にKarateというものがあります。
E2Eのテスト自動化ツールで、レポートなども生成してくれて、非常に便利なのですが、テストデータの作成が中々にめんどくさい。
Javaのコードをテスト内で実行できるので、それでORMみたいなものを作ってデータの作成もできるんですが、クラスを作ったらいちいちそっちも作ったり、修正したらメンテしたりとめんどくさいです。
そこで便利なのが、DBUnitです。
XML形式でデータを定義し、あとは流すだけでデータを作ってくれます。
また、XMLの内部で識別用の文字列をセットしておいて、後で任意の値に置換することで変数の入れ込みも行えます。
コード
以下が該当のテストコードです。
Feature: テスト
Background:
* def dbunit = Java.type('integration.util.DBUnitController')
* def uuid = Java.type('java.util.UUID')
* text originalData =
"""
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<TEST ID="<id>" NAME="テスト" />
</dataset>
"""
Scenario: テスト1
* copy data = originalData
* def id = uuid.randomUUID().toString()
* replace data
| token | value |
| id | id |
* print data
* dbunit.refresh(data)
Given url 'http://localhost:9080/api/test?id=' + id
And header Accept = 'application/json'
When method get
Then status 200
And match response.test.id = id
また、dbunitのコードはDBUnitController.java
に書かれています。
以下が該当のコードです。
public class DBUnitController {
private static final String schema = "xxx";
private static final String username = "xxx";
private static final String password = "xxx";
private static final String url = "xxx";
private static final String driverClassName = "xxx";
private static IDatabaseConnection conn;
static {
try {
conn =
new JdbcDatabaseTester(driverClassName, url, username, password, schema).getConnection();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void refresh(String content) throws Exception {
try {
String filename = saveFile(content);
DatabaseOperation.REFRESH.execute(conn, getDataSet(filename));
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
private static IDataSet getDataSet(String filename) throws Exception {
FlatXmlDataSet dataSet = new FlatXmlDataSetBuilder().build(new File(filename));
ReplacementDataSet replacementDataSet = new ReplacementDataSet(dataSet);
replacementDataSet.addReplacementObject("[null]", null);
replacementDataSet.addReplacementObject("[uuid]", UUID.randomUUID().toString());
replacementDataSet.addReplacementObject(
"[current_timestamp]",
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.000")));
return replacementDataSet;
}
private static String saveFile(String content) throws Exception {
Path path = Files.createTempFile("dbunit-", ".xml");
File file = path.toFile();
Files.write(path, content.getBytes(StandardCharsets.UTF_8));
file.deleteOnExit();
return file.getAbsolutePath();
}
}
コード自体はかなり単純で、テーブルのスキーマにデータを定義して、それをDBUnitに渡して保存してもらっているだけです。
karateでは、xmlに <id>
のような形でデータの部分に定義しておけば、replaceという宣言で、token
に合致するものを value
の値に置換してくれます。
上で示したテストコードのように、変数を入れ込むことができるので非常に便利です。
また、私のプロジェクトでは、DBUnitController.java
の getDataSet
メソッドの中で、文字列を予約しています。
このように予約しておけば、わざわざxmlで書かなくても、[uuid]
などと書くだけで、uuidに変換してくれます。
こういった拡張は好きなだけできると思います。
是非試してみてください。