數據庫測試策略
心得一
目前,最有效的方法是利用腳本來重建數據庫。測試前去drop表,然后create表,然后再進行測試。
心得二
每一個開發人員需要搞一個數據庫實例。不能公用一個數據庫。這個是顯然的。
使用HSQLDB內存數據庫作為測試數據庫。這樣可能會造成一些問題。比如說一些特性在HSQLDB中和在MYSQL, SQLSERVER當中是不一樣的,可能在單元測試中通過了,但是不一定會在生產數據庫中運行通過。這是一個問題。需要考慮。但,確實是夠快,也不會對系統造成什么樣的影響,這個確實。
心得三
使用spring的AbstractTransactionalDataSourceSpringContextTests。在每個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. DataBaseHelper在SpringSide的應用
org.springside.core.test.FunctionWithDataBaseTestCase提供了一個例子描述如何應用和封裝DataBaseHelper
SpringSide給出的這種使用的例子可以供我們參考。我覺得它提供的策略a很好。和上面的心得一是一致的,我也傾向于在做測試的時候,搞一個測試的數據庫,做測試的時候就在這個數據庫中進行操作。這和ROR中建立單元測試數據庫是同樣的思想。
------君臨天下,舍我其誰
------