數(shù)據(jù)庫(kù)測(cè)試策略
心得一
目前,最有效的方法是利用腳本來(lái)重建數(shù)據(jù)庫(kù)。測(cè)試前去drop表,然后create表,然后再進(jìn)行測(cè)試。
心得二
每一個(gè)開發(fā)人員需要搞一個(gè)數(shù)據(jù)庫(kù)實(shí)例。不能公用一個(gè)數(shù)據(jù)庫(kù)。這個(gè)是顯然的。
使用HSQLDB內(nèi)存數(shù)據(jù)庫(kù)作為測(cè)試數(shù)據(jù)庫(kù)。這樣可能會(huì)造成一些問(wèn)題。比如說(shuō)一些特性在HSQLDB中和在MYSQL, SQLSERVER當(dāng)中是不一樣的,可能在單元測(cè)試中通過(guò)了,但是不一定會(huì)在生產(chǎn)數(shù)據(jù)庫(kù)中運(yùn)行通過(guò)。這是一個(gè)問(wèn)題。需要考慮。但,確實(shí)是夠快,也不會(huì)對(duì)系統(tǒng)造成什么樣的影響,這個(gè)確實(shí)。
心得三
使用spring的AbstractTransactionalDataSourceSpringContextTests。在每個(gè)testcase開始之前,會(huì)自動(dòng)開啟一個(gè)事務(wù),然后在結(jié)束的時(shí)候進(jìn)行事務(wù)回滾。
這樣就可以隔絕幾個(gè)測(cè)試用例之間的相互干擾。
有很多文章提到,維護(hù)數(shù)據(jù)庫(kù)的狀態(tài),避免幾個(gè)測(cè)試用例之間的相互干擾,非常必要。這樣才能夠?qū)崿F(xiàn)測(cè)試的自動(dòng)化,不需要人工干涉。
· 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()));
· }
· }
但是,這樣子不是需要進(jìn)行Spring的相關(guān)配置,這樣才可以進(jìn)行DAO的測(cè)試?
心得四
測(cè)試DAO不如連數(shù)據(jù)庫(kù)一起測(cè)試吧。因?yàn)?/span>DAO測(cè)試的目的不是DAO接口實(shí)現(xiàn)對(duì)不對(duì),而是測(cè)試是否如你預(yù)期的發(fā)送了SQL,如你預(yù)期的返回了結(jié)果集。這個(gè)時(shí)候你Mock之后,測(cè)試就沒(méi)有意義了。
我認(rèn)同上面的看法。我不建議測(cè)試DAO還采用MOCK實(shí)現(xiàn)。當(dāng)然,去測(cè)試業(yè)務(wù)邏輯層的方法,采用Mock實(shí)現(xiàn)是非常有道理的。我只是需要保證我的業(yè)務(wù)邏輯的API是否正確就可以了。
心得五
DbUnit為數(shù)據(jù)庫(kù)驅(qū)動(dòng)的項(xiàng)目提供的一個(gè)對(duì)JUnit 的擴(kuò)展!
除了提供一些常用功能,它可以將你的數(shù)據(jù)庫(kù)置于一個(gè)測(cè)試輪回之間的狀態(tài),而DBUnit提供了單元測(cè)試需要的數(shù)據(jù)庫(kù)的數(shù)據(jù)準(zhǔn)備工作。這個(gè)是關(guān)鍵的,照我看來(lái)。
而這一個(gè)工作對(duì)于集成測(cè)試也是有用的。
雖然DbUnit提供了完整的TestCase基類, 然而由于大部分公司和項(xiàng)目都有基于項(xiàng)目需要的TestCase基類和派生類,我們并不能直接應(yīng)用!
SpringSide抽出了其核心------數(shù)據(jù)庫(kù)數(shù)據(jù)的準(zhǔn)備和回收工作,即org.springside.core.test.support.DataBaseUnitHelper。
1. DataBaseUnitHelper提供了三種數(shù)據(jù)庫(kù)連接配置能力。
a. 在classpath根目錄下提供DbUnit.properties,這個(gè)是缺省的配置方法。
b. 通過(guò)給定的properties文件路徑配置
c. 通過(guò)程序指定Properties對(duì)象配置
2. DataBaseUnitHelper采用Excel作為數(shù)據(jù)庫(kù)數(shù)據(jù)的來(lái)源。
雖然DbUnit支持多種數(shù)據(jù)來(lái)源,不過(guò)根據(jù)實(shí)踐來(lái)看,Excel是最容易編輯和獲取(大部分的數(shù)據(jù)庫(kù)開發(fā)工具支持將數(shù)據(jù)導(dǎo)出為Excel)。
3. DataBaseUnitHelper提供兩種數(shù)據(jù)庫(kù)數(shù)據(jù)的配置和回收的應(yīng)用策略
a. 對(duì)于TestCase,在每次Setup時(shí),都先清空數(shù)據(jù)庫(kù),隨后插入準(zhǔn)備數(shù)據(jù)
b. 對(duì)于TestCase,只在第一次Setup時(shí)先清空數(shù)據(jù)庫(kù),隨后插入準(zhǔn)備數(shù)據(jù),而后不在做任何動(dòng)作。
2. DataBaseHelper在SpringSide的應(yīng)用
org.springside.core.test.FunctionWithDataBaseTestCase提供了一個(gè)例子描述如何應(yīng)用和封裝DataBaseHelper
SpringSide給出的這種使用的例子可以供我們參考。我覺(jué)得它提供的策略a很好。和上面的心得一是一致的,我也傾向于在做測(cè)試的時(shí)候,搞一個(gè)測(cè)試的數(shù)據(jù)庫(kù),做測(cè)試的時(shí)候就在這個(gè)數(shù)據(jù)庫(kù)中進(jìn)行操作。這和ROR中建立單元測(cè)試數(shù)據(jù)庫(kù)是同樣的思想。
------君臨天下,舍我其誰(shuí)
------