本文從DBUnit開始介紹一系列測試工具,無論是舊輪子,還是新輪子... Utilities-DBUnit、Spring-test-dbunit 都不放過,但最后亮出新利器......
1-DBUNIT
數據庫測試工具事實上的標准就是DBUnit。根據http://www.dbunit.org/的介紹,其1.0版本早在2002年就已經發布。
它只需要一個JDBC的連接,就能完成對數據狀態的控制。
IDatabaseConnection con = new DatabaseConnection(DbUtil.getConnection())
另外一個其核心概念是IDataSet,通過DataSet來表示數據庫,用ITable 表示來自來自數據庫或者測試用例的表和數據
IDataSet dataset = new FilteredDataSet(filter, connection.createDataSet());
FlatXmlDataSet.write(dataset, new FileOutputStream(file));
上述操作完成了將數據庫內容導出到了一個DBUnit自定義的XML文件中。
ITable actualTable = getConnection().createDataSet().getTable(_testTableName);
IDataSet expectedDataSet = new FlatXmlDataSet(new File(_testDir, _dbFile));
ITable expectedTable = expectedDataSet.getTable(_testTableName);
Assertion.assertEquals(expectedTable, actualTable);
此外,上述操作完成了來自用例的預期結果expectedTable和運行時來自數據庫的結果進行比對actualTable。
另外,DBUnit還提供了在數據庫讀取、插入數據時的操作
DatabaseOperation.UPDATE
DatabaseOperation.DELETE
DatabaseOperation.DELETE_ALL
DatabaseOperation.TRUNCATE
DatabaseOperation.REFRESH
DatabaseOperation.CLEAN_INSERT
DatabaseOperation.NONE
以及非常實用的數據排序、篩選、忽略等fancy的功能,並支持了xml、csv、excel等數據保存格式,甚至還設計了DBUnit自定義的Assertion。讓其成為一個非常成功的數據庫測試框架和數據導入導出操作工具。並且成功地吸引了Unitils這樣的測試框架將其作為數據庫測試模塊的底層工具。
DBUnit存在的問題-維護少,升級、發布慢,
從發布歷史來看,DBUnit在發布的前2年,保持了非常頻繁的更新,在發布了2.0版本之后,可能維護者認為,數據庫測試的方案已經完整了,已經沒什么新功能可做了,其更新速度就開始下降。對應的,其Google熱度也逐步下降。
但是,目前還依然頑強地維持着更新,最近三年基本上是每年一發布一個版本的節奏,解決着一些缺陷,缺少架構層面的重大更新。
2-Spring-test-dbunit
從上述介紹中可以看出,DBUnit雖然功能強大,但是為了完成測試數據的導入和預期結果的比較,還是需要寫一定量的代碼的。隨着Spring框架逐步成為MVC開發模式的事實上的標准,統治JAVA WEB類的項目,基於注解的開發方式流行了開來。於是,一個基於DBUnit的新框架spring-test-dbunit橫空出世,提供了Spring Test Framework與DBUnit之間的集成,實現注解驅動的數據庫集成測試方式。
@Test
@DatabaseSetup(value = "insert.xml")
@DatabaseSetup(connection="customerDataSource", value="insert-custs.xml")
public void testInsert() throws Exception {
// Inserts "insert.xml" into dataSource and "insert-custs.xml" into customerDataSource
// ...
}
優勢:
引入了@DatabaseSetup
@DatabaseTearDown
@ExpdectedDatabase
等注解,將dbunit引入了Spring的圈子。
劣勢
問題1-維護慢,最近一個bug修復是在17年12月
問題-2:只能在Spring技術棧下使用
想要用注解,得先把Spring帶上。不像DBUnit那樣可以獨立使用。
問題-3:只能在Spring技術棧下使用數據結構單一,只支持了xml格式,其余格式需要自行開發
@DatabaseSetup("sampleData.xml")
問題4:只能在Spring技術棧下使用使用的是較老的dbunit版本
這是16年初發布的DBUnit版本。
3-database-rider
這是筆者最近才發現的一個新的基於DBUnit的擴展框架。根據changelog, 該框架於2015年啟動開發,2016年中發布1.0版本,團隊還為此發送了一個 1.0 promo video 。
優勢1:DBUnit+Spring-test-dbunit
首先,這還是一個基於DBUnit的框架
,具備了DBUnit的基本功能,其次還吸收了Spring-test-dbunit基於注解的特性。基本上所有的數據庫操作都可以通過注解來完成,如下例:
@Test
@DataSet(transactional=true)
@ExpectedDataSet(value = "yml/expectedUsers.yml",ignoreCols = "id")
public void shouldMatchExpectedDataSet() {
User u = new User();
u.setName("non expected user1");
User u2 = new User();
u2.setName("non expected user2");
emProvider.em().persist(u);
emProvider.em().persist(u2);
}
其次,提供了新的數據格式,json/yaml
如上例所示,數據文件保存在一個yaml文件中。目前json/yaml已經替代xml成為了軟件開發時對數據文件的首選,廣泛應用於接口數據交換、配置文件等場景。因此Database-rider提供的這一便利應該能吸引到不少對於DBUnit自定義的Flat-format XML文件格式早已不滿的用戶。
DataBase-Rider中引入了較新的dbunit ,並計划在新版本中引用dbunit2.6.0
詳見feature request: update to DBUnit 2.6.0 #111
相對於其競爭對手來說,這個工具在采用新的dbunit版本上還是蠻上心的。
最吸引人的是提供了 @ExportDataset的注解
在數據庫測試過程中,一般的典型場景是:
1)測試人員根據測試點設計測試用例數據,包括a)上下文環境 b)輸入 c)預期結果。
2)setup,測試人員將基礎數據導入數據庫,從而控制程序的上下文環境
3) 通過界面、API接口或者存儲過程等形式與程序交互,並完成輸入。
4)查詢數據庫結果,並與預期結果進行比對。
而自動化的過程,往往是在上述步驟完成后
5) 將a)上下文環境 b)輸入 c)實際結果分別導出
6)編寫代碼,完成1-4的過程並保存形成自動化用例
7)如有可能,將1-6合並,實現所謂的手自一體的自動化測試
從上述過程來看,提供一個較為方便的數據導出功能,可以大大方便了自動化用例的編寫。Database-rider正是解決了DBUnit中需要編寫代碼去導出數據庫中的數據的問題。而Sping-Test-DBunit則很遺憾地忽略了這一重要功能。
劣勢- 又一個輪子,期待合體
本質上這還是基於DBUnit的一個新輪子,包含了DBUnit使用中會遇到的所有的坑(這個足夠寫比本文長3倍的文章來吐槽)。其實造一個新輪子,不如把舊輪子煥新。期待哪天這兩個團隊能合並。。。
更新會持久么?
DBUnit熱鬧了2年,Spring-Test-DBUnit 也類似。憑成員熱情,背后沒有商業公司支持的開源項目,特別是工具類項目,其持久度是永遠的疑問。