欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

加速Java應用開發速度3——單元/集成測試+CI

系統 1830 0

《加速Java應用開發速度》系列目錄:

加速Java應用開發速度1——加速spring/hibernate應用調試時啟動速度

加速Java應用開發速度2——加速項目調試啟動速度

加速Java應用開發速度3——單元/集成測試+CI

加速Java應用開發速度4——使用模板技術加速項目開發速度

加速Java應用開發速度5——使用腳本自動化日常操作?

?

?

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

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

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

?

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

1、為什么需要測試?

2、如何進行測試?

3、測試有哪些好處?

4、一切都需要測試嗎?

?

1、為什么需要測試?

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

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

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

?

2、如何進行測試?

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

2.1、測試流程

單元測試流程

加速Java應用開發速度3——單元/集成測試+CI

?

集成測試流程
加速Java應用開發速度3——單元/集成測試+CI
?

集成測試流程?
加速Java應用開發速度3——單元/集成測試+CI
?

?

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

?

測試的步驟:

  1. 準備環境
  2. 調用被測系統
  3. 驗證
  4. 清理環境

環境 :也叫做夾具(fixture)或者固件,表示調用被測系統時需要準備/清理的數據等等;

被測系統 :在Java中就是要測試的類,如UserService;

依賴系統 :測試被測系統時,其依賴的部分,如UserDao;

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

?

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

?

2.2、環境

?環境,也叫做夾具(fixture),表示調用被測系統時需要準備/清理的數據等等;保證測試時環境是干凈的,如不被之前的數據庫數據影響;保證每次測試都是在干凈/新鮮的環境中執行的。所謂干凈的環境表示如當前測試不被之前測試插入/刪除/修改的數據造成影響。在junit中可以使用:

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

使用如上方法,而不是直接在測試方法中安裝/卸載;是因為不管有沒有異常,@After/@AfterClass都會執行,這樣防止出現異常可能造成環境是不新鮮的問題。

?

如果大家使用spring test來測試數據庫相關的系統,可以考慮使用@TransactionConfiguration來支持默認事務回滾,這樣不會對現有系統造成影響。具體可參考《 【第十三章】 測試 之 13.1 概述 13.2 單元測試 ——跟我學spring3 》和《 【第十三章】 測試 之 13.3 集成測試 ——跟我學spring3

?

測試時一定要保證環境是干凈/新鮮 的,才能保證每次測試的結果是一樣的。

?

2.3、被測系統與依賴系統

被測系統:在Java中就是被測試的Java類。

依賴系統:就是被測試Java類依賴的其他類。

?

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

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

?

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

  • 完成聯調;
  • 發現自己的問題;
  • 還可能發現自己使用上問題及使用的API的問題;

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

?

但是集成測試速度是比較慢的,一般提交給CI執行,不影響當前開發進度。

?

2.4、驗證

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

?

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

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

?

驗證主要有兩種:

  • 結果驗證
  • 行為驗證

結果驗證:即驗證被測系統返回的結果是否正確,如:

          @Test
    public void testCount() {
        String ql = "select count(o) from User o";
        long expectedCount = repositoryHelper.count(ql) + 1;

        User user = createUser();
        repositoryHelper.getEntityManager().persist(user);

        long acutalCount = repositoryHelper.count(ql);
        Assert.assertEquals(expectedCount, acutalCount);

    }
    

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

?

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

1、加積分

2、發系統消息

3、……

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

?

3、測試有哪些好處?

我們寫代碼的目的是正確的完成某個功能,如何保證正確呢?測試!所以在不使用如單元測試技術時,我們也是需要測試,但是這個測試是我們人工驗證的。缺點很明顯:

  • 不是自動的,每次需要對比預期結果與實際結果,尤其數據量/邏輯復雜時更痛苦;
  • 不是回歸的,上次測試完成后,下次還得重復自己一遍;

為了解決這個問題,我們使用如單元測試技術來解決這個問題:

  • 測試自動化;即驗證預期結果與實際結果交給計算機吧;
  • 測試回歸性,可以重復執行測試,驗證修改后邏輯是否還是正確的;

即測試的好處,從如上已經提煉出來了:

  • 縮短發現問題到解決問題的時間;
  • 重復使用測試,保證修改后的代碼還是正確的;
  • 如果做開源項目,可以提供給使用人員參考如何使用;
  • 因為單元測試都非常快,所以提升了開發速度;

4、一切都需要測試嗎?

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

  • 你非常熟悉的功能;

  • 一些簡單的CRUD;

  • 你認為不需要測試的;比如你很有把握的東西,就沒有必要浪費時間測試了;

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

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

?

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

?

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

  • 每天下班前跑一遍集成測試,然后修復,下班走人;

  • CI:持續集成,交給持續集成服務器,自動地測試完成后把測試報告以郵件的形式發到開發人員郵箱;

?

------------------------------------分割線----------------------------------

?

?

接下來介紹一下CI吧。

1、為什么需要CI

2、CI如何工作的

3、travis-ci介紹

?

1、為什么需要CI

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

  • 如果寫了一個測試,就要把所有測試跑一遍看看整個系統是否是正確的,那么每次等待時間是非常漫長的;
  • 如果團隊中的其他成員改了功能并提交了,如何快速得到該次提交對當前系統代碼是正確還是失敗的反饋;

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

?

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

  • 本地測試時忽略一些比較慢的測試;
  • CI服務器上執行所有測試;

?

2、CI如何工作的

一個典型的持續集成流程:

?

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

如圖所示:
加速Java應用開發速度3——單元/集成測試+CI
?
?

?

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

?

常見的CI服務器有:

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

?

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

?

3、travis-ci介紹

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

支持的數據庫:

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

更多請參考其官網的介紹。

?

?

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

                  <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>native2ascii-maven-plugin</artifactId>
                <version>1.0-alpha-1</version>
                <executions>
                    <execution>
                        <phase>generate-resources</phase>
                        <goals>
                            <goal>native2ascii</goal>
                        </goals>
                        <configuration>
                            <encoding>UTF-8</encoding>
                            <src>src/main/messages</src>
                            <dest>target/${project.artifactId}/WEB-INF/classes</dest>
                            <includes>messages.properties</includes>
                        </configuration>
                    </execution>
                </executions>
                <!-- native2ascii 使用的tools.jar -->
                <dependencies>
                    <dependency>
                        <groupId>com.sun</groupId>
                        <artifactId>tools</artifactId>
                        <version>1.7.0</version>
                        <scope>system</scope>
                        <systemPath>${java.home}/../lib/tools.jar</systemPath>
                    </dependency>
                </dependencies>
            </plugin>
    

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

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

?

?

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

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

language: java ? ? ? ? ? 語言

?

env: ? ? ? ? ? ? ? ? ? ? ? ? ? 環境

? - DB=mysql ? ? ? ? ? ? ?使用mysql

?

jdk:

? - openjdk ? ? ? ? ? ? ? ?jdk使用openjdk

?

mysql:?

? database: es ? ? ? ? 數據庫名為es

? username: root ? ? 用戶名為root

? password : ? ? ? ? ? ?密碼為空

? encoding: utf8 ? ? ?編碼為utf8

?

install: ? ? ? ? ? ? ? ? ? ? 安裝時執行的腳本

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

?

before_script: ? ? ? ?script之前執行的測試

? - cd web ? ? ? ? ? ? ?

? - mvn db:create ?創建數據庫的mvn命令(此處使用了?maven-db-plugin 插件)

? - mvn db:schema ?創建腳本的mvn命令

? - mvn db:data ? ? ? ?安裝數據的mvn命令

? - cd ..

?

script: ? ? ? ? ? ? ? ? ? ? ?測試時執行的腳步

? - cd common?

? - mvn test ? ? ? ? ? ? ?測試common子模塊

? - cd ..

? - cd web

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

?

notifications: ? ? ? ? ?觸發

? email: ? ? ? ? ? ? ? ? ?測試完成后測試報告發到哪

? ? - zhangkaitao0503@gmail.com ?

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

?

?

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

?

?

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

?

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

?

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

?

?

正如stackoverflow上的一篇帖子《 How deep are your unit tests? 》上 Kent Beck 的回答:

寫道
老板為我的代碼付報酬,而不是測試,所以,我對此的價值觀是——測試越少越好,少到你對你的代碼質量達到了某種自信。

可以前往 coolshell “單元測試要做多細?” 去得到一些經驗。

?? ? ??

?

推薦閱讀:

es——JavaEE快速開發腳手架中的一些測試用例

【第十三章】 測試 之 13.1 概述 13.2 單元測試 ——跟我學spring3

【第十三章】 測試 之 13.3 集成測試 ——跟我學spring3

stamen的單元測試系列

TDD并不是看上去的那么美

“單元測試要做多細?”

持續集成(第二版)

《xUnit測試模式》

《持續集成:軟件質量改進和風險降低之道》
《持續交付--發布可靠軟件的系統方法》

?

下一篇:使用模板加速開發速度

加速Java應用開發速度3——單元/集成測試+CI


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 亚洲天堂免费在线 | 国产精品一区二区三区四区 | 精品视频网 | 色涩亚洲 | 国产精品久久精品 | 一级做a| 清纯唯美亚洲综合激情 | 成人亚洲欧美日韩在线 | 久久国产精品精品国产 | 大片免费看费看大片 | 一区二区欧美视频 | 欧美日韩精品一区二区三区蜜桃 | av影音| 日韩一区二区福利视频 | 中文字幕一区二区三区四区不卡 | 国内自拍视频在线观看 | 亚洲欧美二区三区久本道 | 成人做爽爽爽爽免费国产软件 | 日韩欧美在线视频播放 | 亚洲国产精品久久久 | 精品视频在线观看视频免费视频 | 色哟哟哟在线观看www | 黑人黄色大片 | 欧美日韩一区二区三区免费视频 | 抱着cao才爽免费观看 | 一区二区视频在线 | 久久男人的天堂 | 三级做爰大爽视频 | 亚洲一级毛片中文字幕 | 夜夜艹 | 亚洲精品一区二区三区四区 | 一区二区三区影院 | 久久最新 | 亚洲婷婷综合中文字幕第一页 | 国产精品观看 | 日本中文字幕网站 | 日韩美女av在线 | 成人亚洲精品 | 成人自拍视频网 | 久草手机视频在线 | 国产精品永久免费视频观看 |