關(guān)于單元測(cè)試及項(xiàng)目質(zhì)量管理的總結(jié)-創(chuàng)新互聯(lián)

摘要:如果沒(méi)寫(xiě)單元測(cè)試,如若在branch中對(duì)之前代碼重構(gòu)的話(huà),則沒(méi)有移回trunck上的勇氣,有了單元測(cè)試,全部運(yùn)行通過(guò)后則有信心合并?;ヂ?lián)網(wǎng)公司更是需要重視單元測(cè)試,因?yàn)榘姹镜容^迅速。因此一個(gè)好的單元測(cè)試框架及一個(gè)好的項(xiàng)目質(zhì)量管理非常重要。本文即是我對(duì)這些的心得體會(huì)。關(guān)鍵詞:java, 單元測(cè)試, TestNG, DbUnit, Spring, 項(xiàng)目管理, 質(zhì)量管理, PMP解決問(wèn)題:?jiǎn)卧獪y(cè)試該如何實(shí)施?項(xiàng)目質(zhì)量管理該如何執(zhí)行?
   在開(kāi)發(fā)數(shù)據(jù)訪(fǎng)問(wèn)對(duì)象DAO層時(shí),我們需要直接對(duì)數(shù)據(jù)層進(jìn)行增刪改查CRUD操作。單元測(cè)試非常重要,因?yàn)樵陂_(kāi)發(fā)期間經(jīng)常需要進(jìn)行代碼重構(gòu),怎樣才能保證代碼重構(gòu)的正確性呢,怎樣給代碼重構(gòu)者以信心讓他放手去做呢,需要執(zhí)行單元測(cè)試,只要能保證接口功能不發(fā)生任何變化,與代碼重構(gòu)前完全相同,并且能直觀(guān)的感受到這一一致性,開(kāi)發(fā)者便能大膽地去干了。功能開(kāi)發(fā)容易,單元測(cè)試難做。第一,單元測(cè)試間相互影響:?jiǎn)卧獪y(cè)試1對(duì)數(shù)據(jù)A新增的一條數(shù)據(jù)可能會(huì)影響到單元測(cè)試2驗(yàn)證的正確性,你可能會(huì)想到在每個(gè)單元測(cè)試的起始時(shí)手動(dòng)做一遍初始化,比如清理一遍表中數(shù)據(jù),以清除其他單元測(cè)試的影響,這樣笨且增加工作量。第二,開(kāi)發(fā)者間相互影響:如果有多人同時(shí)需要執(zhí)行測(cè)試用例,使用以上的辦法后還是會(huì)發(fā)生問(wèn)題,這時(shí)我們可能會(huì)選擇每個(gè)開(kāi)發(fā)者自己搭建一套數(shù)據(jù)庫(kù)(內(nèi)存或大型),以避免多人間的干擾,這樣還是過(guò)于麻煩,且消耗資源。   下面是基于TestNG和DbUnit的單元測(cè)試框架,它的基本思想是管理事務(wù),在單元測(cè)試起始時(shí)使用事務(wù),在單元測(cè)試邏輯的最后將事務(wù)回滾,因此每個(gè)單元測(cè)試內(nèi)對(duì)數(shù)據(jù)庫(kù)的操作將不會(huì)實(shí)際對(duì)數(shù)據(jù)庫(kù)有實(shí)質(zhì)性影響,這樣在單元測(cè)試中既可以測(cè)試邏輯的正確性,又避免影響到了其他單元測(cè)試和其他開(kāi)發(fā)者,并且只需要依賴(lài)于統(tǒng)一的開(kāi)發(fā)數(shù)據(jù)庫(kù)即可,使用還很方便。以下還使用MyBatis的功能抽象出了一個(gè)統(tǒng)一平臺(tái),該統(tǒng)一平臺(tái)提供了大多數(shù)的公共接口,如增刪改查及批量操作等,大部分的基礎(chǔ)操作可以通過(guò)調(diào)用這些接口就能完成,不通用的操作傳入SQL語(yǔ)句也可執(zhí)行。 一、MyBatis統(tǒng)一平臺(tái):MyBatisAngelWang.class
  1. @Repository
    publicclassMyBatisAngelWangimplementsIRepository{
    @Autowired
    privateGeneralDAO generalDAO;
    public<T extendsBase> T get(Class<T> clz,Long id){
    HashMap hashMap= generalDAO.getLogically(clz, id);
    T ret=this.convert(hashMap, clz);
    return ret;
    }
    }
     關(guān)于單元測(cè)試及項(xiàng)目質(zhì)量管理的總結(jié)
  上面的代碼即對(duì)數(shù)據(jù)庫(kù)直接進(jìn)行了操作,我們需要對(duì)此接口編寫(xiě)單元測(cè)試。具體的MyBatis使用方法,及MyBatisAngelWang統(tǒng)一平臺(tái)的實(shí)現(xiàn)辦法,需要另抽專(zhuān)門(mén)章節(jié)進(jìn)行詳細(xì)討論。在這里就不做更深入研究了。 二、統(tǒng)一平臺(tái)的單元測(cè)試:MyBatisAngelWangTest
  1. import org.testng.annotations.Test;
    //@DatabaseSetup(value= "/dbunitData/TestAngelEntity.xml")publicclassMyBatisAngelWangTestextendsAbstractRollbackTest{
    @Autowired
    privateMyBatisAngelWang myBatisAngelWang;
    @Test(enabled=false)
    publicvoid testGet(){
    }
    }

    10年積累的成都網(wǎng)站建設(shè)、做網(wǎng)站經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶(hù)對(duì)網(wǎng)站的新想法和需求。提供各種問(wèn)題對(duì)應(yīng)的解決方案。讓選擇我們的客戶(hù)得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站設(shè)計(jì)后付款的網(wǎng)站建設(shè)流程,更有尉犁免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
  可以看到此單元測(cè)試MyBatisAngelWangTest.class繼承自一個(gè)抽象類(lèi):AbstractRollbackTest。
  1. import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.TestExecutionListeners;
    @ContextConfiguration(locations={"classpath:spring-datasource-dbunit.xml",
    "classpath*:spring-services.xml"})
    @TestExecutionListeners({DependencyInjectionTestExecutionListener.class,
    TransactionDbUnitTestExecutionListener.class,TransactionalTestExecutionListener.class})
    @Transactional
    publicclassAbstractRollbackTestextendsAbstractTestNGSpringContextTests{
    }

  此抽象類(lèi)是由我們自己定義的,其繼承自抽象類(lèi):AbstractTestNGSpringContextTests,它由Springframework提供。我們可以通過(guò)ContextConfiguration注解來(lái)注入spring配置文件。   或者這樣也可以。單元測(cè)試MyBatisAngelWangTest.class直接繼承自AbstractTestNGSpringContextTests。減少了一層。
  1. @ContextConfiguration("/config/Spring-db.xml")
    @Transactional
    @ActiveProfiles("test")
    publicclassMyBatisAngelWangTestextends
    AbstractTransactionalTestNGSpringContextTests{}

三、供給單元測(cè)試的專(zhuān)用spring配置文件:spring-datasource-dbunit.xml
  1. <?xml version="1.0" encoding="UTF-8"?>
    <beansxmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.2.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-3.2.xsd"default-autowire="byName">
    <description>spring-datasource-configuration</description>
    <beanclass="com.angel.context.ApplicationContextAwareHelper"/>
    <!-- 定義事務(wù)管理器(聲明式的事務(wù)) -->
    <beanid="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <propertyname="dataSource"ref="dataSource"/>
    </bean>
    <tx:annotation-driventransaction-manager="transactionManager"/>
    <beanid="propertyConfigurer"class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer">
    <propertyname="locations">
    <list>
    <value>classpath*:props/datasource_dev.properties</value>
    </list>
    </property>
    </bean>
    <beanid="dataSource"class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <propertyname="driverClassName"value="${jdbc.driver}"/>
    <propertyname="url"
    value="${jdbc.dbunit.url}"/>
    <propertyname="username"value="${jdbc.user}"/>
    <propertyname="password"value="${jdbc.password}"/>
    </bean>
    <!-- MyBatis 配置 -->
    <beanclass="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <propertyname="basePackage"value="com.angel.*.dao"/>
    <propertyname="sqlSessionFactoryBeanName"value="xSqlSessionFactory"/>
    </bean>
    <beanid="xSqlSessionFactory"class="org.mybatis.spring.SqlSessionFactoryBean">
    <propertyname="dataSource"ref="dataSource"/>
    <propertyname="typeAliasesPackage"value="com.angel.*.entities"/>
    <propertyname="configLocation"value="classpath:mybatis/mybatis-config.xml"/>
    <propertyname="mapperLocations"value="classpath:/com/angel/dao/*.xml"/>
    <propertyname="plugins">
    <array>
    <!--page interceptor-->
    <beanclass="com.angel.orm.db.QueryInterceptor"/>
    </array>
    </property>
    </bean>
    <tx:annotation-driventransaction-manager="transactionManager"/>
    </beans>

       這樣大家測(cè)試的數(shù)據(jù)庫(kù)都是同一個(gè)了,也不會(huì)有任何的相互影響了。因?yàn)槭聞?wù)回滾了,不信的話(huà)可以提交一條Insert測(cè)試哦,執(zhí)行完后查看數(shù)據(jù)庫(kù)中并沒(méi)有插入任何數(shù)據(jù)。然而,在一個(gè)單元測(cè)試中,先Insert再get是可以取到數(shù)據(jù)的,神奇吧?!

四、其它:ApplicationContextAwareHelper.class
  1. publicclassApplicationContextAwareHelperimplementsApplicationContextAware{
    privatestaticApplicationContext context;
    @Override
    publicvoid setApplicationContext(ApplicationContext applicationContext){
    context= applicationContext;
    }
    publicstaticApplicationContext getContext(){
    return context;
    }
    }

當(dāng)我們需要比較動(dòng)態(tài)的獲取某些bean時(shí),需要ApplicationContextAwareHelper類(lèi)。比如說(shuō),我要自己拼接一個(gè)bean的名稱(chēng),還要獲得該bean,則可以使用下面的代碼來(lái)獲?。?ol>
  • DruidDataSource dataSource =ApplicationContextAwareHelper.getBean("dataSource_"+ dataSources[i]);

       當(dāng)然,這不屬于單元測(cè)試的范疇了,有點(diǎn)跑題,但是蠻有用的,在這里記一下。

  •  五、項(xiàng)目質(zhì)量管理    通過(guò)上面數(shù)步就能夠很好的實(shí)施單元測(cè)試了。然而單元測(cè)試說(shuō)來(lái)容易,執(zhí)行難,有方法了,但推進(jìn)它又是另外一件事了。在互聯(lián)網(wǎng)公司中,很多個(gè)小項(xiàng)目并發(fā)進(jìn)行,同時(shí)存在,項(xiàng)目成員亦流動(dòng)性較大,相近的項(xiàng)目會(huì)分布在各項(xiàng)目組中。這樣,每個(gè)小項(xiàng)目組可能有其自己的規(guī)范或是沒(méi)有。規(guī)范就像法律一樣,是個(gè)人素質(zhì)的最底線(xiàn)、最低層約束。項(xiàng)目開(kāi)發(fā)成員素質(zhì)較高還好,可能不會(huì)引起混亂,當(dāng)項(xiàng)目組成員多了,素質(zhì)參差不齊就麻煩了。這時(shí)就需要執(zhí)行項(xiàng)目經(jīng)理職能的角色出現(xiàn)了。這時(shí)項(xiàng)目經(jīng)理可以且應(yīng)該具體要求各小組的開(kāi)發(fā)流程、規(guī)范。在互聯(lián)網(wǎng)項(xiàng)目中沒(méi)有項(xiàng)目經(jīng)理存在的情況下,可以由行政層面或配置項(xiàng)目管理專(zhuān)員來(lái)實(shí)現(xiàn)。  當(dāng)然項(xiàng)目質(zhì)量管理除了要規(guī)范單元測(cè)試以外,還有很多其他方法,具體可以查看我的這篇文章:http://www.cnblogs.com/wgp13x/p/4101314.html。其中的B圖-質(zhì)量管理即體現(xiàn)了項(xiàng)目質(zhì)量管理的實(shí)施辦法,可能不夠細(xì)致,有空再詳細(xì)敘述一下。   多謝大家的鼓勵(lì)! 

    來(lái)自王安琪

    作者:Angel 出處:http://www.cnblogs.com/wgp13x/ 歡迎轉(zhuǎn)載或分享,但請(qǐng)務(wù)必聲明文章出處。如果文章對(duì)您有幫助,希望你能推薦或關(guān)注。

    王安琪,英文名Angel,南京郵電大學(xué)計(jì)算機(jī)應(yīng)用技術(shù)碩士學(xué)位。 熟悉Java、C#編程語(yǔ)言。專(zhuān)注于WebService、海量數(shù)據(jù)處理、搜索引擎技術(shù)、消息中間件技術(shù)、分布式文件存儲(chǔ)、.NET應(yīng)用程序開(kāi)發(fā)、系統(tǒng)架構(gòu)設(shè)計(jì)。主要從事大數(shù)據(jù)管理系統(tǒng)的研發(fā),項(xiàng)目經(jīng)理,系統(tǒng)架構(gòu)師,就職于江蘇金陵科技集團(tuán)有限公司。

    Email:aitanjupt@hotmail.com

    QQ:289770363

    當(dāng)前題目:關(guān)于單元測(cè)試及項(xiàng)目質(zhì)量管理的總結(jié)-創(chuàng)新互聯(lián)
    標(biāo)題來(lái)源:http://bm7419.com/article20/dgojjo.html

    成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站建設(shè)、用戶(hù)體驗(yàn)、標(biāo)簽優(yōu)化、網(wǎng)站收錄、外貿(mào)建站全網(wǎng)營(yíng)銷(xiāo)推廣

    廣告

    聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

    成都seo排名網(wǎng)站優(yōu)化