日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
加速Java應(yīng)用開發(fā)3—單元集成測試+CI

大家可能對如下情景比較熟悉:

成都創(chuàng)新互聯(lián)公司服務(wù)項目包括鼓樓網(wǎng)站建設(shè)、鼓樓網(wǎng)站制作、鼓樓網(wǎng)頁制作以及鼓樓網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,鼓樓網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到鼓樓省份的部分城市,未來相信會繼續(xù)擴大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

  • 如果開發(fā)過SSH的web項目,啟動服務(wù)器可能會比較慢,有的項目甚至需要1分多鐘,甚至更多,這個啟動時間的等待一般就浪費了;
  • 在開發(fā)項目時,有些功能比較復(fù)雜,當(dāng)時覺得思路特清晰,但是過了一段時間后,自己也忘了,完善功能時頻繁出現(xiàn)bug,降低開發(fā)速度;
  • 在維護項目時,不知道自己修改的對還是不對,是否存在隱患;維護速度降下來了;
  • 如果開發(fā)一個很多人都使用的接口,典型的如用戶系統(tǒng),要保證比如升級時向下兼容;
  • 在團隊間協(xié)作時,有時候只定義好接口,對方還沒有給實現(xiàn),如何進行同步開發(fā)?

如上問題,估計只要是個開發(fā)人員,都可能遇到過;如果此時有了單元/集成測試,那我們能很好的解決這些問題。(注:加下來如果沒有特殊情況,不刻意強調(diào) 單元測試/集成測試,即提到測試是指的是單元/集成測試)

我從以下幾個方面介紹測試:

  • 1、為什么需要測試?
  • 2、如何進行測試?
  • 3、測試有哪些好處?
  • 4、一切都需要測試嗎?

1、為什么需要測試?

測試的目的是什么?我的理解是:

  • 縮短發(fā)現(xiàn)問題到解決問題的速度;
  • 給程序一個修改后能驗證是否正確的保證;(回歸測試)
  • 如果是開源軟件,我們可以通過單元測試了解其是怎么使用的;比如我之前通過cglib的單元測試學(xué)習(xí)過cglib的使用;

所以如果你遇到如上問題,就需要寫測試。寫測試可能是為了自己(1、2);也可能是為了幫助別人(3)。

2、如何進行測試?

很多朋友不知道如何進行測試,其實測試很簡單,別把它想復(fù)雜了,按照自己的想法測試每個功能點是否正確即可。

2.1、測試流程

單元測試流程

集成測試流程

集成測試流程

可以看出,單元測試與集成測試唯一不同點是一個調(diào)用依賴系統(tǒng)而一個不調(diào)用;因為單元測試是最小粒度的測試,如在Java中是測試一個類,不會測試依賴系統(tǒng);而集成測試是會測試依賴系統(tǒng)的。

測試的步驟:

  1. 準(zhǔn)備環(huán)境
  2. 調(diào)用被測系統(tǒng)
  3. 驗證
  4. 清理環(huán)境

環(huán)境:也叫做夾具(fixture)或者固件,表示調(diào)用被測系統(tǒng)時需要準(zhǔn)備/清理的數(shù)據(jù)等等;

被測系統(tǒng):在Java中就是要測試的類,如UserService;

依賴系統(tǒng):測試被測系統(tǒng)時,其依賴的部分,如UserDao;

測試用例:包含測試方法的類,里邊有很多測試方法來測試被測系統(tǒng)。

接下來仔細(xì)看看各部分都做了哪些工作。

2.2、環(huán)境

 環(huán)境,也叫做夾具(fixture),表示調(diào)用被測系統(tǒng)時需要準(zhǔn)備/清理的數(shù)據(jù)等等;保證測試時環(huán)境是干凈的,如不被之前的數(shù)據(jù)庫數(shù)據(jù)影響;保證每次測試都是在干凈/新鮮的環(huán)境中執(zhí)行的。所謂干凈的環(huán)境表示如當(dāng)前測試不被之前測試插入/刪除/修改的數(shù)據(jù)造成影響。在junit中可以使用:

  • @Before(setUp) 安裝夾具或準(zhǔn)備環(huán)境:在測試用例的每個測試方法之前執(zhí)行;比如創(chuàng)建新鮮的被測系統(tǒng),單元測試時安裝Mock的依賴系統(tǒng);
  • @After(tearDown)卸載夾具或清理環(huán)境:在測試用例的每個測試方法之后執(zhí)行;比如數(shù)據(jù)庫測試時回滾事務(wù),刪除數(shù)據(jù);關(guān)閉文件;
  • @BeforeClass:在整個測試用例之前執(zhí)行;
  • @AfterClass:在整個測試用例之后執(zhí)行;

#p#

使用如上方法,而不是直接在測試方法中安裝/卸載;是因為不管有沒有異常,@After/@AfterClass都會執(zhí)行,這樣防止出現(xiàn)異??赡茉斐森h(huán)境是不新鮮的問題。

如果大家使用spring test來測試數(shù)據(jù)庫相關(guān)的系統(tǒng),可以考慮使用@TransactionConfiguration來支持默認(rèn)事務(wù)回滾,這樣不會對現(xiàn)有系統(tǒng)造成影響。

測試時一定要保證環(huán)境是干凈/新鮮的,才能保證每次測試的結(jié)果是一樣的。

2.3、被測系統(tǒng)與依賴系統(tǒng)

被測系統(tǒng):在Java中就是被測試的Java類。

依賴系統(tǒng):就是被測試Java類依賴的其他類。

如果是單元測試,一般情況下,會對依賴系統(tǒng)進行模擬(Mock),即給它一個假的實現(xiàn);典型的如測試服務(wù)層時注入一個Mock的DAO層,這樣的好處:

  • 加快測試速度;因為不會調(diào)用真實的被測系統(tǒng),所以速度特別快;
  • 測試還沒有完成的功能;尤其在多團隊協(xié)作時,可以只在定義好接口的情況下開發(fā)系統(tǒng);

如果是集成測試時,直接注入真實的依賴系統(tǒng)即可,好處:

  • 完成聯(lián)調(diào);
  • 發(fā)現(xiàn)自己的問題;
  • 還可能發(fā)現(xiàn)自己使用上問題及使用的API的問題;

單元測試雖然好,但是是隔離測試,即不會調(diào)用被測系統(tǒng)來完成測試,因為不是真實的聯(lián)調(diào),所以很可能會潛在有一些問題,因此還是需要集成測試。(所以不是很刻意分單元或集成測試,且有些系統(tǒng)可能只有集成測試)

但是集成測試速度是比較慢的,一般提交給CI執(zhí)行,不影響當(dāng)前開發(fā)進度。

2.4、驗證

驗證的目的:是保證實際結(jié)果和我們預(yù)期的結(jié)果是否一致,說白了就是是否是我們想的那樣。

一般使用斷言來驗證,如:

Assert.assertEquals(expectedResult, actualResult); //驗證預(yù)期結(jié)果和實際結(jié)果是否相等

驗證主要有兩種:

  • 結(jié)果驗證
  • 行為驗證

結(jié)果驗證:即驗證被測系統(tǒng)返回的結(jié)果是否正確,如:

 
 
 
 
  1. @Test  
  2. public void testCount() {  
  3.     String ql = "select count(o) from User o";  
  4.     long expectedCount = repositoryHelper.count(ql) + 1;  
  5.   
  6.     User user = createUser();  
  7.     repositoryHelper.getEntityManager().persist(user);  
  8.   
  9.     long acutalCount = repositoryHelper.count(ql);  
  10.     Assert.assertEquals(expectedCount, acutalCount);  
  11.   
  12. }  

驗證返回的數(shù)據(jù)總數(shù) = 插入之前的總數(shù) + 1; 即結(jié)果驗證。此處我們使用了一種叫做相對(delta)測試;即不關(guān)心數(shù)據(jù)庫里到底多少條,只關(guān)心實際的和預(yù)期的差。

行為驗證:即驗證被測系統(tǒng)是否調(diào)用了依賴系統(tǒng)的某個API ,這個只有當(dāng)我們使用Mock時測試時比較簡單,如當(dāng)用戶注冊時:

1、加積分

2、發(fā)系統(tǒng)消息

3、……

此時我們并不能通過結(jié)果驗證是否調(diào)用了這些方法;那么我們可以使用Mock技術(shù)來完成驗證是否調(diào)用了這些API,比如使用jmock測試框架就支持行為驗證。集成測試是很難進行行為驗證的,如果測試需要預(yù)留間諜接口。

3、測試有哪些好處?

我們寫代碼的目的是正確的完成某個功能,如何保證正確呢?測試!所以在不使用如單元測試技術(shù)時,我們也是需要測試,但是這個測試是我們?nèi)斯を炞C的。缺點很明顯:

  • 不是自動的,每次需要對比預(yù)期結(jié)果與實際結(jié)果,尤其數(shù)據(jù)量/邏輯復(fù)雜時更痛苦;
  • 不是回歸的,上次測試完成后,下次還得重復(fù)自己一遍;
  • 為了解決這個問題,我們使用如單元測試技術(shù)來解決這個問題:
  • 測試自動化;即驗證預(yù)期結(jié)果與實際結(jié)果交給計算機吧;
  • 測試回歸性,可以重復(fù)執(zhí)行測試,驗證修改后邏輯是否還是正確的;

即測試的好處,從如上已經(jīng)提煉出來了:

  • 縮短發(fā)現(xiàn)問題到解決問題的時間;
  • 重復(fù)使用測試,保證修改后的代碼還是正確的;
  • 如果做開源項目,可以提供給使用人員參考如何使用;
  • 因為單元測試都非??欤蕴嵘碎_發(fā)速度;

4、一切都需要測試嗎?

肯定不是,一切都是相對的;哪些不需要測試呢:

  • 你非常熟悉的功能;
  • 一些簡單的CRUD;
  • 你認(rèn)為不需要測試的;比如你很有把握的東西,就沒有必要浪費時間測試了;
  • 哪些需要測試呢:
  • 復(fù)雜的業(yè)務(wù)邏輯/系統(tǒng)核心功能,最典型的如訂單系統(tǒng):一定要有足夠的單元測試保證,這是一個電商系統(tǒng)的核心;還有如用戶系統(tǒng)、積分系統(tǒng)等等;
  • 框架級別/工具級別/通用級別的代碼需要測試,即提供給第三方使用的代碼,因為這些代碼可能被很多系統(tǒng)依賴,應(yīng)該保證其正確性;而且還要保證以后版本升級的向下兼容;
  • 你認(rèn)為需要測試的,比如你沒有把握的東西,還是寫點測試來縮短如開發(fā)web項目的重啟系統(tǒng)的時間吧;

 測試不是不耗時間的,沒意義的測試就是浪費時間,最典型是一些書上的對一個增刪改查進行測試,實際項目沒有任何意義。所以你應(yīng)該只對自己很難駕馭的覺得有必要的代碼進行測試。不要成為一個測試狂,什么都測試。

一些測試可以參考我的《es——JavaEE快速開發(fā)腳手架》中的代碼。通過測試我得到了許多好處。

#p#

到此我們介紹完成了測試,但是如果我們使用了如集成測試時,測試執(zhí)行起來可能比較慢,跑一遍測試可能需要5分鐘,那怎么辦呢?

  • 每天下班前跑一遍集成測試,然后修復(fù),下班走人;
  • CI:持續(xù)集成,交給持續(xù)集成服務(wù)器,自動地測試完成后把測試報告以郵件的形式發(fā)到開發(fā)人員郵箱;

接下來介紹一下CI吧。

1、為什么需要CI

2、CI如何工作的

3、travis-ci介紹

1、為什么需要CI

正如前邊說的,我們單獨測試可能會遇到如下問題:

  • 如果寫了一個測試,就要把所有測試跑一遍看看整個系統(tǒng)是否是正確的,那么每次等待時間是非常漫長的;

  • 如果團隊中的其他成員改了功能并提交了,如何快速得到該次提交對當(dāng)前系統(tǒng)代碼是正確還是失敗的反饋;

那怎么辦呢?自動化地持續(xù)集成(CI)!CI的核心就是干這件事情的。自動化持續(xù)地集成測試。

使用CI后,如果使用Maven,可以新建多個profile:

  • 本地測試時忽略一些比較慢的測試;

  • CI服務(wù)器上執(zhí)行所有測試;

2、CI如何工作的

一個典型的持續(xù)集成流程:

  1. 定期檢測版本服務(wù)器上是否有代碼更新;
  2. 如果發(fā)現(xiàn)代碼更新,從版本服務(wù)器下載最新的代碼;
  3. 自動構(gòu)建并自動化的測試;
  4. 不管錯誤/失敗,生成報告給開發(fā)人員;
  5. 有些CI服務(wù)器還能產(chǎn)生可執(zhí)行的軟件,自動化地部署到測試機器,交給測試人員測試。

如圖所示:

 

持續(xù)集成服務(wù)器其實就是一個定時器,自動幫你下載最新代碼、編譯、測試、集成及產(chǎn)生報告發(fā)給開發(fā)人員。

常見的CI服務(wù)器有:

  • Apache Continuum
  • Hudson
  • CruiseControl
  • Jenkins CI
  • TeamCity
  • Travis CI

我09年時使用過TeamCity社區(qū)版,足夠滿足常見需求;目前我使用github托管項目,使用Travis CI進行分布式的持續(xù)集成,免費,目前看來還是不錯的。

3、travis-ci介紹

我現(xiàn)在開發(fā)的ES-JavaEE項目開發(fā)腳手架就是使用travis ci進行持續(xù)集成;具體參考《Getting started》進行與Github集成,其支持的語言:

  • C
  • C++
  •  Clojure
  • Erlang
  • Go
  • Groovy
  • Haskell
  • Java
  • JavaScript (with Node.js)
  • Objective-C
  • Perl
  • PHP
  • Python
  • Ruby
  • Scala

#p#

支持的數(shù)據(jù)庫:

  • MySQL
  • PostgreSQL
  • MongoDB
  • CouchDB
  • Redis
  • Riak
  • RabbitMQ
  • Memcached
  • Cassandra
  • Neo4J
  • ElasticSearch
  • Kestrel
  • SQLite3

如果是Java開發(fā)人員,支持的JDK包括:OpenJDK 和 OracleJDK。 如果使用的是OpenJDK,Maven中使用ascii2native插件時,需要如下配置:

 
 
 
 
  1.   
  2.     org.codehaus.mojo  
  3.     native2ascii-maven-plugin  
  4.     1.0-alpha-1  
  5.       
  6.           
  7.             generate-resources  
  8.               
  9.                 native2ascii  
  10.               
  11.               
  12.                 UTF-8  
  13.                 src/main/messages  
  14.                 target/${project.artifactId}/WEB-INF/classes  
  15.                 messages.properties  
  16.               
  17.           
  18.       
  19.       
  20.       
  21.           
  22.             com.sun  
  23.             tools  
  24.             1.7.0  
  25.             system  
  26.             ${java.home}/../lib/tools.jar  
  27.           
  28.       
  29.   

如果使用mysql,端口只能是3306。

如果想開端口測試,這是不允許的。

如下是我項目中的一個配置.travis.yml,放到項目的根下即可:

-----------------------------------

language: java           語言

env:                           環(huán)境

  - DB=mysql              使用mysql

jdk:

  - openjdk                jdk使用openjdk

mysql:

  database: es         數(shù)據(jù)庫名為es

  username: root     用戶名為root

  password :            密碼為空

  encoding: utf8      編碼為utf8

install:                     安裝時執(zhí)行的腳本

  - mvn install -Dmaven.test.skip=true     mvn安裝并跳過測試

before_script:        script之前執(zhí)行的測試

  - cd web          

  - mvn db:create  創(chuàng)建數(shù)據(jù)庫的mvn命令(此處使用了 maven-db-plugin 插件)

  - mvn db:schema  創(chuàng)建腳本的mvn命令

  - mvn db:data        安裝數(shù)據(jù)的mvn命令

  - cd ..

script:                      測試時執(zhí)行的腳步

  - cd common

  - mvn test              測試common子模塊

  - cd ..

  - cd web

  - mvn test -Pit       測試web子模塊,并指定使用it profile測試(即集成測試的配置,具體參考pom.xml中的profile/it)

notifications:          觸發(fā)

  email:                  測試完成后測試報告發(fā)到哪

    - zhangkaitao0503@gmail.com

-----------------------------------

持續(xù)集成不能修復(fù)代碼的錯誤,而是和單元測試一樣,縮短發(fā)現(xiàn)問題帶解決問題的時間,這樣可以提高開發(fā)效率,降低項目風(fēng)險,提高項目的穩(wěn)定性。而且尤其是團隊協(xié)作時,可以發(fā)現(xiàn)其他人的代碼是否對自己的代碼產(chǎn)生影響。

到此我們利用單元測試+CI可以加速開發(fā)人員的開發(fā)速度。利用好單元測試和CI,不要純粹為了單元測試和CI而去做這些事情。

本文沒有介紹TDD,TDD并不會那么美好,我認(rèn)為我們可以借鑒TDD的一些思想,但決不能迷信TDD,有時候,尤其如開發(fā)企業(yè)應(yīng)用,先寫功能再寫測試可能效率更高,而且大部分時候是不需要TDD的。而且我也沒能在實際項目中獲取太多TDD的好處,但是我獲得了測試的好處。

本文也沒有介紹測試覆蓋率,我認(rèn)為不要一味的追求覆蓋率,有時候有的覆蓋率沒有任何意義。所以不要讓為了覆蓋率而覆蓋率拖慢了項目開發(fā)進度。


本文標(biāo)題:加速Java應(yīng)用開發(fā)3—單元集成測試+CI
文章路徑:http://www.5511xx.com/article/cdcodjh.html