數據庫測試策略

心得一

       目前,最有效的方法是利用腳本來重建數據庫。測試前去drop表,然后create表,然后再進行測試。

心得二

       每一個開發人員需要搞一個數據庫實例。不能公用一個數據庫。這個是顯然的。

       使用HSQLDB內存數據庫作為測試數據庫。這樣可能會造成一些問題。比如說一些特性在HSQLDB中和在MYSQL, SQLSERVER當中是不一樣的,可能在單元測試中通過了,但是不一定會在生產數據庫中運行通過。這是一個問題。需要考慮。但,確實是夠快,也不會對系統造成什么樣的影響,這個確實。

心得三

       使用springAbstractTransactionalDataSourceSpringContextTests。在每個testcase開始之前,會自動開啟一個事務,然后在結束的時候進行事務回滾。

       這樣就可以隔絕幾個測試用例之間的相互干擾。

       有很多文章提到,維護數據庫的狀態,避免幾個測試用例之間的相互干擾,非常必要。這樣才能夠實現測試的自動化,不需要人工干涉。

· public class BaseDAOTestCase extends  AbstractTransactionalDataSourceSpringContextTests{  

·     protected static Log log = LoggerServiceImpl.getLogger();  

·   

·     protected String[] getConfigLocations() {  

·         return new String[] {"classpath*:/WEB-INF/mPlatform*ApplicationContext.xml"};  

·     }  

·   

·     protected void flushSession(){  

·         SessionFactory sessionFactory =   

·             (SessionFactory)applicationContext.getBean("sessionFactory");  

·         sessionFactory.getCurrentSession().flush();  

·     }  

· }  

·   

· public class PersonDAO extends BaseDAOTestCase {  

·     private PersonDAO personDAO;  

·     private Person person;  

·       

·     public void setPersonDAO(PersonDAO personDAO) {  

·         this.personDAO = personDAO;  

·     }     

·       

·       

·     public void onSetUpBeforeTransaction() {  

·         person = new Person();  

·         person.setFirstName("Sean");  

·         person.setLastName("Liu");  

·         person.setUserName("forever");  

·     }  

·       

·     public void testSave() {  

·         personDAO.save(person);  

·         assertNotNull(person.getId());  

·     }  

·       

·     public void testGetPerson() {  

·         personDAO.save(person);  

·         Person retrievedPerson = personDAO.getPerson(person.getId());  

·         assertNotNull(retrievedPerson.getId());  

·         assertEquals(person, retrievedPerson);  

·     }  

·       

·     public void testRemovePerson() {  

·         personDAO.save(person);  

·         person.delete(person);  

·         flushSession();  

·         assertNull(personDAO.getPerson(person.getId()));  

·     }  

· }

但是,這樣子不是需要進行Spring的相關配置,這樣才可以進行DAO的測試?

心得四

       測試DAO不如連數據庫一起測試吧。因為DAO測試的目的不是DAO接口實現對不對,而是測試是否如你預期的發送了SQL,如你預期的返回了結果集。這個時候你Mock之后,測試就沒有意義了。

      

       我認同上面的看法。我不建議測試DAO還采用MOCK實現。當然,去測試業務邏輯層的方法,采用Mock實現是非常有道理的。我只是需要保證我的業務邏輯的API是否正確就可以了。

心得五

DbUnit為數據庫驅動的項目提供的一個對JUnit 的擴展!

除了提供一些常用功能,它可以將你的數據庫置于一個測試輪回之間的狀態,而DBUnit提供了單元測試需要的數據庫的數據準備工作。這個是關鍵的,照我看來。

而這一個工作對于集成測試也是有用的。

雖然DbUnit提供了完整的TestCase基類, 然而由于大部分公司和項目都有基于項目需要的TestCase基類和派生類,我們并不能直接應用!

SpringSide抽出了其核心------數據庫數據的準備和回收工作,即org.springside.core.test.support.DataBaseUnitHelper

1. DataBaseUnitHelper提供了三種數據庫連接配置能力。
a. classpath根目錄下提供DbUnit.properties,這個是缺省的配置方法。
b. 通過給定的properties文件路徑配置
c. 通過程序指定Properties對象配置

2. DataBaseUnitHelper采用Excel作為數據庫數據的來源。
雖然DbUnit支持多種數據來源,不過根據實踐來看,Excel是最容易編輯和獲取(大部分的數據庫開發工具支持將數據導出為Excel)

3. DataBaseUnitHelper提供兩種數據庫數據的配置和回收的應用策略
a. 對于TestCase,在每次Setup時,都先清空數據庫,隨后插入準備數據
b. 對于TestCase,只在第一次Setup時先清空數據庫,隨后插入準備數據,而后不在做任何動作。

2. DataBaseHelperSpringSide的應用

 org.springside.core.test.FunctionWithDataBaseTestCase提供了一個例子描述如何應用和封裝DataBaseHelper

       SpringSide給出的這種使用的例子可以供我們參考。我覺得它提供的策略a很好。和上面的心得一是一致的,我也傾向于在做測試的時候,搞一個測試的數據庫,做測試的時候就在這個數據庫中進行操作。這和ROR中建立單元測試數據庫是同樣的思想。



------君臨天下,舍我其誰------