成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Mock框架的三次迭代,讓你的單元測(cè)試更高效

開發(fā) 開發(fā)工具 測(cè)試
對(duì)于單元測(cè)試中的單元,不同的人有不同的看法:可以理解為一個(gè)方法,可以理解為一個(gè)完整的接口實(shí)現(xiàn),也可以理解為一個(gè)完整的功能模塊或者是多個(gè)功能模塊的一個(gè)耦合。

如何定義單元

對(duì)于單元測(cè)試中的單元,不同的人有不同的看法:可以理解為一個(gè)方法,可以理解為一個(gè)完整的接口實(shí)現(xiàn),也可以理解為一個(gè)完整的功能模塊或者是多個(gè)功能模塊的一個(gè)耦合。

根據(jù)以往的單元測(cè)試經(jīng)驗(yàn),在設(shè)計(jì)單元測(cè)試用例時(shí),當(dāng)針對(duì)方法級(jí)別展開單元測(cè)試時(shí),重點(diǎn)關(guān)注的是方法的底層邏輯;當(dāng)針對(duì)的是模塊時(shí),針對(duì)的是實(shí)際的業(yè)務(wù)邏輯實(shí)現(xiàn);當(dāng)針對(duì)整合后的模塊進(jìn)行測(cè)試時(shí),一般稱之為集成測(cè)試。

[[243805]]

不管是單元測(cè)試還是集成測(cè)試,都可以統(tǒng)一的理解為單元測(cè)試。因?yàn)樗麄兊谋举|(zhì)都是對(duì)方法或接口的一種測(cè)試形式,只是所處的階段不一樣罷了。

1. 集成測(cè)試應(yīng)該由誰(shuí)編寫

在我們的實(shí)際工作中,研發(fā)人員在提交代碼之前,會(huì)設(shè)計(jì)一些“冒煙測(cè)試”級(jí)別集成測(cè)試用例。等到整個(gè)功能開發(fā)完成后,測(cè)試人員會(huì)根據(jù)業(yè)務(wù)需求和設(shè)計(jì)的測(cè)試用例,來(lái)進(jìn)行整體的集成測(cè)試用例的編寫、執(zhí)行、失敗用例分析,以及代碼的調(diào)式和問(wèn)題代碼的定位等工作。

2. 集成測(cè)試用例

業(yè)務(wù)相關(guān)的測(cè)試主要是通過(guò)spring-test來(lái)進(jìn)行集成測(cè)試,基本的測(cè)試結(jié)構(gòu)為先定義一個(gè)基類用來(lái)初始化被測(cè)試類。

測(cè)試基類定義結(jié)構(gòu)如下:

  1. @RunWith(SpringJUnit4ClassRunner.class)   
  2. ContextConfiguration(locations = {"classpath:./spring/applicationContext.xml"})   
  3. @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)   
  4. public class BaseSpringJunitTest {   
  5.     @Autowired   
  6.     protected BusinessRelatedServiceImpl businessRelatedService;   

業(yè)務(wù)相關(guān)的測(cè)試類定義如下格式:

  1.   public class BusinessRelatedServiceImplDomainTest  extends BaseSpringJunitTest {  
  2.   @Test   
  3.   public void testScenario1 (){  
  4.   new Thread(new DOSAutoTest("testScenario1")).start();   
  5.   Thread.sleep(1000*60*1);   
  6.   String requestJson=""//測(cè)試入?yún)?   
  7.   RequestPojo request=( RequestPojo )JSONUtils.jsonToBean(requestJson,RequestPojo .class);   
  8.   ResponsePojo responsebusinessRelatedService.businessRelatedMethod(ResponsePojo );   
  9.   //業(yè)務(wù)相關(guān)的assert區(qū)域   
  10. }   

3. 如何解決下游系統(tǒng)依賴

businessRelatedMethod方法在處理業(yè)務(wù)邏輯的過(guò)程中需要調(diào)用下游JSF(Jingdong Service Framework,完全自主研發(fā)的高性能RPC服務(wù)框架)提供的訂單接口(OrderverExportService),并根據(jù)入?yún)⒅械挠唵尉幪?hào)獲取訂單的詳細(xì)信息(ResultPojo getOrderInfoById (long orderId))。

那么如何獲取下游JSF接口的返回正確數(shù)據(jù)就變成了一個(gè)比較重要的問(wèn)題。如果是在功能測(cè)試或者聯(lián)調(diào)測(cè)試階段,可以由下游測(cè)試人員來(lái)提供數(shù)據(jù)。不過(guò)這樣溝通和測(cè)試成本較高,無(wú)法滿足業(yè)務(wù)快速上線和變化的要求,尤其在集成測(cè)試階段這個(gè)問(wèn)題就變得尤為明顯,因?yàn)橄掠螖?shù)據(jù)對(duì)于上游來(lái)說(shuō)是不可控的。這樣mock下游數(shù)據(jù)就變得尤為緊急和重要。

4. Mock框架的選擇

在整個(gè)java生態(tài)圈中,支持mock的開源框架還是比較多的,比如常用的mockito、powermock、easymock和jmockit等開源框架。這些框架在mock方面都具有比較強(qiáng)大的功能與比較廣泛的使用量。但是這些框架都具有一個(gè)相同的缺點(diǎn),那就是需要或多或少的編碼工作來(lái)mock所需要的接口返回?cái)?shù)據(jù)。

在設(shè)計(jì)mock框架的時(shí)候,我們考慮到盡量讓寫單元測(cè)試的人員或研發(fā)人員少編碼或不編碼,來(lái)獲取不同的業(yè)務(wù)場(chǎng)景所需要的測(cè)試數(shù)據(jù)。

Mock框架 ***版

該版本的mock框架的整體思想為:結(jié)合JSF的特性,Override所有下游接口的方法,然后將實(shí)現(xiàn)下游接口的應(yīng)用部署到測(cè)試環(huán)境,發(fā)布一個(gè)有別與真實(shí)下游接口的服務(wù),在接口調(diào)用的時(shí)候,通過(guò)不同的JSF接口別名來(lái)進(jìn)行區(qū)分。Mock的數(shù)據(jù)存儲(chǔ)在數(shù)據(jù)庫(kù)中。

該框架類調(diào)用關(guān)系:

Mock框架

Mock接口的具體實(shí)現(xiàn):

  1.   public class OrderverExportServiceImp extends OrderverExportServiceAdapter {   
  2.       @Resource   
  3.       private OrderverMapper orderverMapper;   
  4.      
  5.       @Override   
  6.       public ResultPojo getOrderInfoById (long orderId) {   
  7.   OrderverPojo orderverMock=orderverMapper.getOrderId(new Long(orderId).toString());   
  8.           ResultPojo result=new ResultPojo ();   
  9.           result.setFiled1(null);   
  10.         result.setFiled1(0);   
  11.         result.setFiled2(null);   
  12.         result.setFiled3(null);   
  13.         result.setResult(true);   
  14.         …//mock需要的數(shù)據(jù) 
  15.         result.setReturnObject(orderver);   
  16.         return result;   
  17.     }   

Mock服務(wù)發(fā)布完后的效果:

Mock服務(wù)發(fā)布完后的效果

在集成測(cè)試階段,只需要修改該接口的JSF別名,就可以實(shí)現(xiàn)該接口的mock調(diào)用。

  1. <jsf:consumer id="orderverExportServiceJsf" interface="xxx.xxx.xxx.xxx.xxx.OrderverExportService"   
  2.                protocol="jsf" timeout="${timeout}"  
  3.                alias="${alias}" retries="2" serialization="hessian">   
  4.  </jsf:consumer>  
  5.   alias=orderver_mock 

該框架的優(yōu)缺點(diǎn)

優(yōu)點(diǎn):

  • 做集成測(cè)試用例設(shè)計(jì)時(shí),不用編寫代碼,只需要維護(hù)測(cè)試場(chǎng)景所需要的返回?cái)?shù)據(jù);
  • 該框架不僅可以用在集成測(cè)試中,在下游接口無(wú)變更的前提下,同時(shí)還可以用在后續(xù)系統(tǒng)測(cè)試與聯(lián)調(diào)測(cè)試階段。

缺點(diǎn):

  • mock服務(wù)的發(fā)布依賴于服務(wù)器與數(shù)據(jù)庫(kù),當(dāng)依賴的服務(wù)器或數(shù)據(jù)庫(kù)出現(xiàn)跌機(jī)情況時(shí),該mock服務(wù)不用;
  • 該框架的維護(hù)成本比較大,當(dāng)下游依賴的接口較多時(shí),所有的服務(wù)包含的方法均需要進(jìn)行override;
  • 當(dāng)下游的接口定義發(fā)生變化時(shí)比如新增接口方法,該mock服務(wù)需要重新override該新增的方法并且需要重新打包部署;
  • 下游接口方法的數(shù)據(jù)結(jié)構(gòu)發(fā)生變化時(shí),存儲(chǔ)數(shù)據(jù)的數(shù)據(jù)表結(jié)構(gòu)需要做相應(yīng)的調(diào)整,對(duì)于業(yè)務(wù)變化較快的系統(tǒng),這種類型的改動(dòng)頻率還是較高。

Mock框架 第二版

為了解決上述mock框架依賴服務(wù)器與數(shù)據(jù)庫(kù)的問(wèn)題,我們又做了第二次嘗試。將mock框架設(shè)計(jì)為jar包的形式,提供給程序來(lái)調(diào)用。在下游接口的實(shí)現(xiàn)方式上第二版與***版保持不變,同時(shí)業(yè)務(wù)數(shù)據(jù)不放數(shù)據(jù)庫(kù),而是將業(yè)務(wù)數(shù)據(jù)放到文件中。變化的點(diǎn)為接口調(diào)用上需要將對(duì)應(yīng)的jsf:comsumer節(jié)點(diǎn)替換為對(duì)應(yīng)的實(shí)際mock的實(shí)現(xiàn)類。

Mock接口的實(shí)現(xiàn):

  1.   @Service("orderverExportService")   
  2.  public class OrderverExportServiceMock extends OrderverExportServiceAdapter { 
  3.       @Override   
  4.       public ResultPojo getOrderInfoById(long orderId) {   
  5.           ResultPojo result=new ResultPojo ();   
  6.           result.setFiled1(null);   
  7.           result.setFiled1(0);   
  8.           result.setFiled2(null);   
  9.           result.setFiled3(null);   
  10.         result.setResult(true);   
  11.         …//mock需要的數(shù)據(jù) 
  12.         result.setReturnObject(orderver);   
  13.         return result;   
  14.     }   
  15. }  

Mock接口調(diào)用配置:

  1. <!--<jsf:consumer id="orderverExportServiceJsf" interface="xxx.xxx.xxx.xxx.xxx.OrderverExportService" protocol="jsf" timeout="${timeout}"alias="${alias}" retries="2" serialization="hessian"> 
  2. </jsf:consumer>--> 
  3. <bean id="orderverExportServiceJsf" class="xxx.xxx.xxx.xxx.xxx.OrderverExportServiceMock"></bean>   

該框架的優(yōu)缺點(diǎn)

優(yōu)點(diǎn):

  • 做集成測(cè)試用例設(shè)計(jì)時(shí),不用編寫代碼,只需要維護(hù)測(cè)試場(chǎng)景所需要的返回?cái)?shù)據(jù);
  • 相比較***個(gè)版本,該版本在執(zhí)行效率上有了較大的提升,因?yàn)閙ock類的加載是走的本地Spring配置文件,同時(shí)數(shù)據(jù)加載也是走的本地文件;
  • 無(wú)需再依賴于服務(wù)器部署和數(shù)據(jù)庫(kù)依賴。

缺點(diǎn):

  • 該框架的維護(hù)成本比較大,當(dāng)下游依賴的接口較多時(shí),所有的服務(wù)包含的方法均需要進(jìn)行override;
  • 當(dāng)下游的接口定義發(fā)生變化時(shí)比如新增接口方法,該mock服務(wù)需要重新override該新增的方法并且需要重新打包,然后上傳到maven倉(cāng)庫(kù);
  • 下游接口方法的數(shù)據(jù)結(jié)構(gòu)發(fā)生變化時(shí),對(duì)于業(yè)務(wù)變化較快的系統(tǒng),這種類型的改動(dòng)頻率還是較高。

Mock框架 第三版

隨著需要mock的接口變的越來(lái)越龐大,以上兩種mock框架的實(shí)現(xiàn)的缺點(diǎn)就變的越來(lái)越突出。該框架可以說(shuō)從根本上解決了上述框架實(shí)現(xiàn)的問(wèn)題。因?yàn)樵摽蚣艹浞掷昧薐DK的動(dòng)態(tài)代理,反射機(jī)制以及JSF提供的高級(jí)特性來(lái)實(shí)現(xiàn)我們的mock框架。框架維護(hù)任務(wù)可以做到無(wú)需做更多的針對(duì)接口的編碼任務(wù)。測(cè)試人員只需要將重點(diǎn)放在測(cè)試數(shù)據(jù)的準(zhǔn)備上。

框架整體調(diào)用時(shí)序圖:

框架的核心類圖:

框架的核心類圖

其中DOSAutoTest類用來(lái)啟動(dòng)和發(fā)布JSF的mock接口,JSFMock通過(guò)動(dòng)態(tài)代理的方式,實(shí)現(xiàn)下游接口的mock功能并根據(jù)測(cè)試場(chǎng)景獲取對(duì)應(yīng)的mock數(shù)據(jù)。

其中,mock的數(shù)據(jù)以json格式存儲(chǔ)在mock框架項(xiàng)目工程的指定目錄下。

該框架解決的問(wèn)題:

  • 省去了利用第三方mock框架如jmockit,mockito,powermock時(shí),需要在單元測(cè)試或集成測(cè)試類中寫mock代碼的麻煩;
  • 該框架模擬數(shù)據(jù)返回時(shí),完全的模擬了接口之間的調(diào)用關(guān)系;
  • 測(cè)試人員或研發(fā)人員在利用該框架mock數(shù)據(jù)時(shí),無(wú)需額外的代碼,就可以實(shí)現(xiàn)mock數(shù)據(jù)的返回;
  • 在模擬下游數(shù)據(jù)返回時(shí),發(fā)布的mock接口調(diào)用完成后就自行銷毀,無(wú)需額外服務(wù)器進(jìn)行部署與維護(hù)。
  • 在進(jìn)行接口mock時(shí),無(wú)需在mock框架中添加相關(guān)的接口maven依賴。

單元測(cè)試展開方式

1. 單元測(cè)試應(yīng)該由誰(shuí)編寫

單元測(cè)試由誰(shuí)編寫?針對(duì)這個(gè)問(wèn)題,大家在網(wǎng)上會(huì)找到不同的觀點(diǎn):

  • 一個(gè)觀點(diǎn)是,誰(shuí)寫代碼,誰(shuí)自己寫單元測(cè)試。當(dāng)然,有的結(jié)對(duì)編程里面,也有相互寫的,不過(guò),這個(gè)過(guò)程中,兩個(gè)人是共同完成的代碼。也不違反誰(shuí)寫代碼誰(shuí)寫單元測(cè)試的原則。
  • 另一個(gè)觀點(diǎn)是單元測(cè)試應(yīng)該由其它的研發(fā)人員或測(cè)試人員來(lái)進(jìn)行編寫,理由大概可以理解為對(duì)于非代碼編寫人員來(lái)說(shuō),在設(shè)計(jì)單元測(cè)試用例的時(shí)候,對(duì)應(yīng)的是一個(gè)黑盒。在這樣的背景下,設(shè)計(jì)出來(lái)的用例覆蓋程度更高。

2. 單元測(cè)試的行業(yè)現(xiàn)狀

如果研發(fā)來(lái)負(fù)責(zé)單元測(cè)試的編寫,很多時(shí)候研發(fā)人員都不編寫單元測(cè)試。研發(fā)人員不編寫單元測(cè)試的原因其實(shí)也是比較容易理解的,因?yàn)榫帉憜卧獪y(cè)試用例工作太耗時(shí)。有時(shí)候研發(fā)的經(jīng)理或項(xiàng)目的業(yè)務(wù)方會(huì)認(rèn)為單元測(cè)試用例會(huì)減緩項(xiàng)目的整體進(jìn)度。有時(shí)候甚至整個(gè)公司層面都不認(rèn)可花費(fèi)大量的時(shí)間在單元測(cè)試上是合理的,尤其是在項(xiàng)目周期緊張和業(yè)務(wù)變動(dòng)較大的項(xiàng)目上。因?yàn)閱卧獪y(cè)試從一定程度上來(lái)說(shuō)確實(shí)增加的研發(fā)人員的編碼量,同時(shí)還會(huì)增加代碼的維護(hù)成本。

如果測(cè)試來(lái)負(fù)責(zé)單元測(cè)試的編寫,目前的現(xiàn)狀是測(cè)試人員需要時(shí)間理解代碼,寫單元測(cè)試的時(shí)間會(huì)變長(zhǎng)。有代碼修改之后,在項(xiàng)目的測(cè)試壓力之下,有的測(cè)試人員,就選擇不維護(hù)單元測(cè)試,而選擇趕緊完成傳統(tǒng)的手工測(cè)試。

3. 單元測(cè)試用例自動(dòng)生成

人工編寫測(cè)試用例成本增加,那么我們考慮是否可以通過(guò)自動(dòng)生成的方式來(lái)實(shí)現(xiàn)單元測(cè)試呢?EvoSuite是由Sheffield等大學(xué)聯(lián)合開發(fā)的一種開源工具,用于自動(dòng)生成測(cè)試用例集,生成的測(cè)試用例均符合Junit的標(biāo)準(zhǔn),可直接在Junit中運(yùn)行。

對(duì)于非業(yè)務(wù)相關(guān)的模塊,在單元測(cè)試的實(shí)踐中,就可以直接使用上述工具來(lái)自動(dòng)生成單元測(cè)試代碼。雖然該工具只是輔助測(cè)試,并不能完全取代人工,測(cè)試用例的正確與否還需人工判斷,但是通過(guò)使用此自動(dòng)測(cè)試工具能夠在保證代碼覆蓋率的前提下極大地提高測(cè)試人員的開發(fā)效率。

下面來(lái)詳細(xì)介紹如何使用該工具生成單元測(cè)試用例以及如何檢查單元用例的正確性。

EvoSuite為Maven項(xiàng)目提供了一個(gè)插件,該插件的具體配置如下所示:

  1.   <plugin>   
  2.      <groupId>org.evosuite.plugins</groupId>   
  3.      <artifactId>evosuite-maven-plugin</artifactId>   
  4.      <version> ${evosuiteVersion} </version>   
  5.      <executions><execution>   
  6.         <goals>   
  7.            <goal>   
  8.               prepare   
  9.            </goal>   
  10.       </goals>   
  11.       <phase>   
  12.          process-test-classes   
  13.       </phase>   
  14.    </execution></executions>   
  15. </plugin>    

除了需要配置上述plugin外,maven還需要做如下的配置:

  1.   <dependency>   
  2.      <groupId>org.evosuite</groupId>   
  3.      <artifactId>evosuite-standalone-runtime</artifactId>   
  4.      <version>${evosuiteVersion}</version>   
  5.      <scope>test</scope>   
  6.   </dependency>   
  7.   <!--上述依賴主要是用來(lái)自動(dòng)生成單元測(cè)試用例-->   
  8.   <plugin>   
  9.      <groupId>org.apache.maven.plugins</groupId>   
  10.    <artifactId>maven-surefire-plugin</artifactId>   
  11.    <version>${maven-surefire-plugin-version}</version>   
  12.    <configuration>   
  13.       <systemPropertyVariables>   
  14.          <java.awt.headless>true</java.awt.headless>   
  15.       </systemPropertyVariables>   
  16.       <testFailureIgnore>true</testFailureIgnore>   
  17.       <skipTests>false</skipTests>   
  18.       <properties>   
  19.          <property>   
  20.             <name>listener</name>   
  21.             <value>org.evosuite.runtime.InitializingListener</value>   
  22.          </property>   
  23.       </properties>   
  24.    </configuration>   
  25. </plugin>  

上述plugin主要是用來(lái)混合執(zhí)行手動(dòng)設(shè)計(jì)的單元測(cè)試用例和使用EvoSuite自動(dòng)生成的單元測(cè)試用例。

以上EvoSuite所需的plugin和maven依賴配置完成之后,就可以使用maven命令來(lái)自動(dòng)生成單元測(cè)試用例并執(zhí)行了。

  1. mvn -DmemoryInMB=2000 -Dcores=2 evosuite:generate evosuite:export test  

生成測(cè)試用例后,可以通過(guò)人工排查生成測(cè)試用例的正確性。

寫在***

不管是研發(fā)還是測(cè)試負(fù)責(zé)集成或單元測(cè)試,選取適合自身項(xiàng)目的mock框架,一方面可以縮短測(cè)試代碼的編寫時(shí)間,另一方面可以加速測(cè)試代碼的執(zhí)行效率,同時(shí)又可以降低測(cè)試代碼的維護(hù)成本。不管是行業(yè)中通用的mock框架還是定制化的框架,都可以廣泛的應(yīng)用的測(cè)試中。

因?yàn)樽鰉ock框架不是目的,目的是為了能高效的設(shè)計(jì)出更多的測(cè)試覆蓋場(chǎng)景,來(lái)進(jìn)一步提升測(cè)試效率、保證產(chǎn)品質(zhì)量和將測(cè)試人員從繁重的手工測(cè)試中得以解放。

當(dāng)單元測(cè)試代碼已經(jīng)準(zhǔn)備完畢,如何才能發(fā)揮測(cè)試代碼的作用以及如何評(píng)價(jià)測(cè)試代碼的效率和做單元測(cè)試的投入產(chǎn)出比如何來(lái)衡量等等這些問(wèn)題,將在后續(xù)的文章中給大家一一解答。

【本文來(lái)自51CTO專欄作者張開濤的微信公眾號(hào)(開濤的博客),公眾號(hào)id: kaitao-1234567】

戳這里,看該作者更多好文

責(zé)任編輯:趙寧寧 來(lái)源: 51CTO專欄
相關(guān)推薦

2024-07-29 12:12:59

2022-05-12 09:37:03

測(cè)試JUnit開發(fā)

2017-01-14 23:42:49

單元測(cè)試框架軟件測(cè)試

2017-03-23 16:02:10

Mock技術(shù)單元測(cè)試

2011-11-30 22:03:49

ibmdwJava

2023-10-28 10:10:41

2010-12-23 15:55:00

上網(wǎng)行為管理

2011-06-20 16:41:59

單元測(cè)試

2009-06-01 10:47:32

jboss seam例jboss seam開jboss seam

2023-12-24 10:00:35

Java單元測(cè)試

2024-10-16 16:09:32

2017-01-14 23:26:17

單元測(cè)試JUnit測(cè)試

2017-01-16 12:12:29

單元測(cè)試JUnit

2024-08-19 00:35:00

Pythondict遍歷列表推導(dǎo)式

2010-08-27 09:11:27

Python單元測(cè)試

2024-12-02 18:16:56

2017-03-30 07:56:30

測(cè)試前端代碼

2022-09-15 10:02:58

測(cè)試軟件

2011-05-16 16:52:09

單元測(cè)試徹底測(cè)試

2023-07-26 08:58:45

Golang單元測(cè)試
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 色综合一区二区 | 懂色中文一区二区三区在线视频 | 国产精品一区久久久 | 成人免费视频在线观看 | 欧美日韩国产在线观看 | 91porn国产成人福利 | 日本手机看片 | 毛片av免费看 | 午夜影院免费体验区 | 精品国产乱码久久久久久丨区2区 | 国产aⅴ爽av久久久久久久 | 91视频精选 | 日韩精品在线一区 | 久草欧美视频 | 色综久久 | 黄色一级大片视频 | 久久草在线视频 | 天天想天天干 | 日韩精品激情 | 午夜免费福利电影 | 青青草网站在线观看 | 中文字幕在线视频免费视频 | 成人一区av偷拍 | 久久久久久免费毛片精品 | 狠狠骚| av一区二区三区四区 | 国产精品久久久久久吹潮 | 91免费在线视频 | 成人精品一区亚洲午夜久久久 | 国产精品人人做人人爽 | 99久久婷婷国产综合精品电影 | 成人h动漫亚洲一区二区 | 一级做a爰片久久毛片 | 欧美精产国品一二三区 | 久久免费国产 | 久久免费国产视频 | 三级国产三级在线 | 欧美不卡视频一区发布 | 国产高清在线视频 | 日本 欧美 三级 高清 视频 | 免费看a |