1. 程式人生 > >廉頗老矣,尚能飯否? (jdk+演算法+spring+netty+大資料+OS+Architect)

廉頗老矣,尚能飯否? (jdk+演算法+spring+netty+大資料+OS+Architect)

測試不能夠證明錯誤不存在,只能夠證明錯誤存在。儘可能測試一切可以測試的東西。


測試是如何驅動開發過程的

測試驅動開發起源於XP法中提倡的測試優先實踐。測試優先實踐重視單元測試,強調程式設計師除了編寫程式碼,還應該編寫單元測試程式碼。在開發的順序上,它改變了以往先編寫程式碼,再編寫測試的過程,而採用先編寫測試,再編寫程式碼來滿足測試的方法。這種方法在實際中能夠起到非常好的效果,使得測試工作不僅僅是單純的測試,而成為設計的一部分。為什麼這麼說呢?

在編寫程式之前,每個人都會先進行設計的工作。可能有些人的設計比較正式,繪製模型,編寫文件。有些人的設計只是存在於腦海之中。且不論是設計是精細還是粗糙,你都為隨後的編碼活動制定了一個標準。這個標準的明確程度和你的設計的細緻程度有關。但應該承認,這個標準是不夠細化的。因為你的設計不可能精細到程式碼級的程度。而標準不夠明確的則會產生一些問題,例如,在編寫程式碼的過程中,你還可能會發現原先的設計出現問題,從而中途改變程式碼的編寫思路。這將會導致成果難以檢驗,進度難以度量。

既然以設計為導向的標準不夠明確,不夠具體。那什麼樣的標準才是合適的呢?只能是程式碼。因為程式碼是最明確、最具體的。所以測試優先的本質其實是目標管理。編寫測試程式碼其實是在制定一個小目標。這個小目標非常的明確,它規定了你需要設計的類、方法。以及方法需要滿足的結果。這些目標制定完成之後,你才開始編寫程式碼來達成該目標。測試的目標要比設計的目標粒度更小,但是成本上卻更為經濟。其原因有四:

細粒度的設計需要花費大量的成本,雖然CASE工具都提供了程式碼自動生成的功能,但結果往往難以令人滿意。所以,設計如果要做到和測試相同的粒度,成本不菲,如果粒度不夠細,指導的意義又不夠。

減輕了測試的工作量。無論是否進行設計工作,測試工作都是不可避免的,先進行單元測試,可以減少後續的測試工作量。
採用測試優先的過程中,設計的粒度較大。因為測試可以實現一部分的設計工作。這樣,設計上可以節省一些工作量。例如,你不再需要將類圖細化到每個方法。


在編寫測試程式碼上花費的成本,會在迴歸測試上得到回報。自動化測試的最大好處就是避免程式碼出現迴歸。兩相權衡,編寫測試的代價其實不高。


你也許會說,我既不進行如此精細的設計,也不事先編寫測試程式碼,這樣的成本不是最低嗎?請注意,我們的前提是在討論高質量的軟體設計。在一些規模較小或是開發人員能力極強的專案中,確實可以如此辦理。但是對於強調質量的大專案,這種處於混沌狀態的開發思路是不可取的。

測試優先是軟體開發中一種細粒度的目標管理方法,通過明確的目標,推動軟體開發的進行。

在業界中,採用測試作為評價軟體標準的做法是非常常見的。例如,sun公司就專門設計了測試軟體,對各個實現J2EE規範的產品進行測試。使用測試作為規範的最大好處就是明確、具體。

使用測試程式碼建立目標,編寫程式碼完成測試目標,再製定下一個目標,如此迴圈,構成了測試驅動開發的工作流程。在接下去的篇幅中,我們開始討論測試驅動開發中需要注意的一些問題。


測試必須是自動化的

和自動化測試相對的是手動測試。手動測試有著自動化測試所沒有的優勢。最明顯的就是簡單。任何一位開發人員都能夠進行手動測試。即便是使用者,也很容易掌握手動測試,他們輸入資料,並觀察軟體的反應(輸出),從而判斷行為是否正確。大部分的手動測試都是對輸入和輸出的檢驗,是一個端到端過程,很能說明問題。

但是手動測試存在的問題比它所帶來的好處要多得多。手動測試可能引入錯誤,人為的輸入錯誤很容易發生,尤其在資料量大的情況下;大量重複性的手動測試可能成本較高,如果考慮軟體發生改動而需要重複手動測試的情況,這個成本還會更高;手動測試的覆蓋面不廣,只能夠測試系統的輸入和輸出;沒有辦法對元件進行隔離的測試,從而導致發現問題和解決問題的成本都太高。

基於上面的討論,我們應該看到,測試應該做到自動化。雖然一開始測試自動化的成本較高,但是從整個的開發過程來看,自動化測試所產生的價值遠遠超過其成本。


自動化測試的範圍

那麼,到底有哪些東西是需要納入到自動化測試的範圍的呢?例如,對於一個典型的分層應用來說,就有資料庫層、資料庫訪問層,業務邏輯層、介面控制層、介面層。這些層次的測試特點各不相同,哪些應該進行自動化測試呢?最理想的情況是全部。測試一切可能是測試的基本原則,讓一切測試都變成自動化則是測試驅動開發的準則。

應該承認,建立自動化測試需要付出成本,有些自動化測試成本較低,有些則較高。例如,對業務方法的自動化測試相對容易,對關聯到資料庫的業務方法的測試則繁瑣一些,因為你需要處理更多的情況。而介面的自動化測試則較困難,因為介面涉及到大量的人機互動,手動測試是非常簡單的,但是自動化測試則相當的困難。

那麼,我們就來看看,像介面測試這樣的成本高昂的測試需不需要進行自動化呢?我們拿駐留的Web介面來作為人機互動介面的範例。

首先,按照分層的原則,介面的層次上不應該擁有業務邏輯,介面層負責的事情是收集使用者的動作,將使用者的動作請求委託給後端的業務層,並對動作進行響應。所以,和業務相關的邏輯已經被剝離到了業務層了。它的自動化測試屬於業務層。同時,我們還發現,在測試的推動下,軟體的結構變得更加的合理。

其次,雖然業務邏輯大量的遷移出介面層,但是介面層中還有狀態,還有控制邏輯。這些因素都是和介面的控制的表現息息相關的。既然有邏輯,就需要測試。根據 MVC的思路,介面層中包含了模型、檢視和控制器。模型是對業務層資料的封裝,在J2EE的應用中,可能是普通的JavaBean,也可能是離線的資料封裝,或是簡單的資料集合。檢視負責表現模型,而控制器的職責則比較多,它需要負責處理和檢查請求引數,負責呼叫業務物件並傳遞請求中所包含的資料,負責建立模型,負責生成檢視並把模型傳遞給它。

所以,在一個真正的MVC介面設計中,測試的重點在於控制器。模型的測試是很容易的,大部分的模型僅僅包含了資料,所以甚至都不需要測試。一個完美的檢視,它應該沒有包含任何的邏輯,僅僅只是將模型以某種方式表現出來而已。一個設計優秀的檢視,可以很容易的進行替換,而不會造成任何的影響。例如,一個JSP檢視可以用一個XSLT檢視進行替換。所以,結構合理的檢視也是不需要測試的(但對頁面要素的檢查是必要的)。注意,這裡的討論也同樣表明,測試驅動設計向合理的方向發展。

大部分的控制器都是基於servlet技術的,servlet技術是典型的容器內應用,這使得Junit不容易使用。而Cactus( http://jakarta.apache.org/cactus/index.html)能夠解決這個問題,它對Junit進行了擴充套件,提供了大量的預置功能,簡化了request、response、session的使用,Cactus通過 Redirector Proxy,建立了一個測試客戶端和測試服務端模型,來實現基於容器內的測試。下圖是典型的Servlet的結構圖:



 
 

除了構造一個容器來進行測試之外,另一種方式則從根本上改變了控制器的測試方法,那就是不將控制器實現在Servlet技術之上。這樣做的好處是測試無需依賴於容器。典型的如springframework( http://www.springframework.org)的Web層就是這樣設計的。

無論採用何種方法,都說明軟體業在對介面的自動化測試已經開始充分的關注,並提出了不少的解決方法了。這樣做的目的無非是兩點:一是通過自動化測試提高軟體質量,二是通過對測試的關注來推動設計的優化。

最後,從開發文化上來看。介面自動化測試的要求意味著開發人員需要先和使用者進行充分的溝通,繪製出滿足需要的頁面,這其實是原型方法的應用,對開發過程是有利的。此外,開發人員需要慎重的思考頁面的設計,保證頁面設計的抗變性和可擴充套件性,否則,你會發現測試程式碼變得非常的不穩定,從而導致一些不必要的麻煩。這種文化將會推動設計的發展。

所以我們看到,在一個成本較高的自動化測試領域,通過合理的設計和引入工具,可以降低自動化測試的成本。而且,在上述的討論中,我們也發現,之所以自動化測試的成本高昂,往往是由於設計不當而造成的。在介面混雜大量的邏輯,導致變化不斷髮生,不但程式碼需要修改,測試程式碼同樣需要修改,設計的隨便才是高成本的真正罪魁禍首。也正是因為這個原因,測試才能夠驅動設計的優化。


測試的分類

單元測試

單元測試是典型的對程式碼邏輯的黑盒測試。在測試驅動方法中,不太強調白盒測試(絕大多數的白盒測試都是通過評審進行的)。這樣做的好處是關注介面勝於關注實現,這是一種分析複雜軟體的有效辦法。這一點我們在後續的文章中還會討論。

單元測試是開發人員的職責。一般來說,測試的編碼最好由不同人來負責,避免出現盲點,以提高測試的有效性。但是單元測試的粒度很小,如果進行分工,溝通的成本會相當高。此外,採用測試優先的實踐,對測試進行適當的培訓,也能夠有效的降低單個人的盲點範圍。

單元測試可以加入到小組日構建中,也可以不加入。如果不加入,那麼需要有一種機制來管理單元測試活動。

整合測試

整合測試的粒度和測試的範圍要比單元測試大。我們拿資料庫測試來做例子。現在需要對一個業務物件進行測試,它需要用到持久化機制。在單元測試中,我們將不涉及資料庫而單獨對業務物件進行測試(使用MO技術,下文中討論);但是在整合測試中,我們需要將資料庫的資料一致性也納入進來,所以測試包括資料庫資料的建立,測試業務方法,使資料庫恢復原狀。

整合測試應該是日構建的重要組成部分,即日構建標準中的測試標準。最好將整合測試交給QA部門負責。QA部門的精力可以放在使用或編寫一些工具(Cactus就是典型的整合測試工具),建立標準的測試資料,安排測試計劃等活動上。

接受測試

有時候很難區分整合測試和接受測試。接受測試的關注點是使用者。使用者通過將資料輸入系統來觀察系統的輸出。所以,瞭解使用者的需要並將使用者的需要轉換為接受測試是接受測試中最關鍵的工作。接受測試處於測試過程的最後環節,是判斷軟體是否滿足使用者需求的試金石。毫不例外。接受測試也應該是自動化的。例如, HttpUnit就是一個自動化接受測試的工具。另外,很多的專業測試工具提供的自動化的指令碼測試工具也屬於這個範疇。


測試推進設計

在介面測試的討論中,我們已經認識到測試是可以推動設計的。在這裡我們打算結合具體的技術來討論測試和設計之間的關係。

針對介面設計

測試驅動方法採用的是黑盒測試,為了保證測試的穩定性,被測程式碼介面的穩定性是非常重要的。否則,變化的成本就會急劇的上升。所以,自動化測試將會要求你的設計依賴於介面,而不是具體的類。這種設計目前被公認是較好的設計思路。

MO技術

這裡不會介紹MO(Mock Object,偽物件)技術,DW專區中已經有這方面的討論文章了。這裡的重點是討論如何正確的使用MO技術。用過MO的人都有這樣的疑惑,MO技術太麻煩了,編寫大量的偽物件僅僅是為了配合被測試物件的測試工作,未免有些小題大做了。

實際上,MO技術最大的好處並不僅僅是測試本身,MO技術將推動設計向著針對介面,可抽換的方向發展。因為MO技術需要做到偽物件和實際物件之間能夠平滑的切換,這個能力對於軟體架構來說是非常重要的,它充分表現了架構可擴充套件性和抗變性。

當然,在實際中,MO技術確實需要增加大量的程式碼。有一些工具能夠簡化你的工作,例如EasyMock等一些工具。

測試覆蓋率

Unit tests drive code quality;
            Clover drives unit test quality.
           
 

上面的兩句話是Clover( http://www.thecortex.net/clover/index.html)的廣告詞,扣除廣告的意味,這句話說得還是非常有道理的。我們的引言中就說明,測試沒有辦法證明錯誤不存在。所以,對測試進行分析是有必要的,而測試覆蓋率就是最重要的一個指標。

測試覆蓋率分析有兩種方法:程式碼覆蓋率和分支條件覆蓋率。對測試進行覆蓋率分析是軟體度量的重要方法,也是測試的組成部分,不少的開源專案已經將其納入到了日構建的過程中。

測試的成本

雖然之前我們討論了大量激動人心的思路和技術。你可能會熱血澎湃的打算在組織中實施測試驅動方法。但是我不得不向你潑冷水了。測試驅動方法的引入不是簡單的過程,對一些企業來說,甚至相當難以做到。這是因為以下這幾個原因:

工作量的估算方式需要改變。在測試驅動方法中,一個開發人員除了需要編寫實現程式碼,還需要編寫測試程式碼,這將會使得工作量上升,此外,為了自動化測試而對設計的改進還將會需要一定的時間。所以,要求開發人員學習測試驅動方法沒有任何的意義,關鍵是需要為他們留出足夠的時間。

專案進度。由於工作量的上升和新知識的使用,專案進度會迅速下落,然後隨著開發人員熟練程度的提升和自動化測試的優勢才會慢慢回升,如果實施成功,最終的專案速度將會超出實施前,這是完全有可能的。

人員的主動性和勇氣。根據我們的經驗,不少的組織和開發人員都能夠認識到測試驅動的好處,但是往往由於現實環境的原因,導致測試驅動方法的實施無以為繼。組織由於專案的時間壓力,導致其不敢對測試驅動方法進行推廣,往往是淺嘗則止。個人由於缺乏足夠的耐心和時間,導致其不願和不敢對設計進行重構,而這恰恰是測試驅動的前提。

測試驅動方法的應用沒有那麼簡單,一個組織如果沒有足夠的勇氣是很難做到的。所以,為什麼一開始我們就強調,本文的讀者是那些應用較負責,對質量非常敏感的專案的相關人員,其中的一個原因就在於此。


建立測試文化

測試驅動方法不是一個簡單的方法論,它也不會和任何的方法論進行競爭。事實上,無論你的組織採用何種方法或過程,都可以從測試驅動中獲利。因為它強調的是質量文化。把測試看作一項核心工作,測試同樣需要重構,以及必須的文件。

固定測試的目錄組織和包組織。例如,一種較好的組織測試的方法是採用和原始碼同樣的包名,但處於完全不同的目錄中。

使測試成為日建立的核心步驟。測試是所有人的事情,而不僅是QA的事。


進一步瞭解

從Junit的網站( http://www.junit.org)上,你可以瞭解到Junit的大量資訊,包括介紹性的文章,Junit的擴充套件等。


關於作者
林星,致力於研究敏捷理論和優秀的軟體設計思想,並將之應用於國內的軟體組織。可以通過 [email protected]和他聯絡,也可以通過訪問www.qca.cn和www. aglichina.org來獲得更多的資訊。

相關推薦

廉頗老矣? (jdk+演算法+spring+netty+資料+OS+Architect)

測試不能夠證明錯誤不存在,只能夠證明錯誤存在。儘可能測試一切可以測試的東西。 測試是如何驅動開發過程的 測試驅動開發起源於XP法中提倡的測試優先實踐。測試優先實踐重視單元測試,強調程式設計師除了編寫程式碼,還應該編寫單元測試程式碼。在開發的順序上,它改變了以往先編寫程式碼,再

70後.net老猿

小夥伴 實力 管理系 優化 實現 人的 第一次 方便 c++ 程序猿的大限 距離上一次主動找工作,快到5年了,到現在的東家,是差不多3年前獵頭挖過來的,而當時東家剛剛被歐洲一家有百年歷史的跨國企業集團收購,所以我也就有幸成了一名“外企員工”

Java 老矣

依然 lin roi 應用領域 原生 但我 type 微服務 支持 22 歲,對於一個技術人來說可謂正當壯年。但對於一門編程語言來說,情況可能又有不同。各類編程語言橫空出世,紛戰不休,然而 TIOBE 的語言排行榜上,Java 卻露出了明顯的頹勢。這個老牌的語言,未來會是怎

IT人老矣

事情 其中 match image 進入 篩選 center 了解 分享圖片 今年剛好 40 歲,在一家著名外企做到技術專家的位置,在親戚朋友眼中,儼然已算半個“成功人士”,但內心深處,卻無一刻不戰戰兢兢。 我知道,自己就像一個風雨中的高蹺人,哪怕一陣風,一

JQuery老矣

我的github地址:Github 發展歷程 write less, do more -- John Resig ​ 在2005年8月的某一天,有一位叫John Resig的美(guo)人,在blog上連發3個栗子公開懟了Prototype的Behaviour的程式碼冗長,在那之後沒

講透資料我只需要一頓(最通俗易懂的資料解釋)

十五年前,剛開始工作,從帝都回老家。 某長輩和藹的問我:“工作了啊,做什麼的?” 我躊躇半天答曰:“挨踢(IT)。” 長輩不假思索的來了一句:“哦,在中關村賣光碟啊!” 我......我.....我......(叔叔,你知道的太多了) 【副菜

資料分析、資料探勘、演算法工程師、資料分析師的區別是什麼?爬招聘網站用資料來全方位分析

大資料行業經過幾年的發展和沉澱,大資料專案崗位細分領域已經趨於完善,本文主要探討在大資料分析這個領域,通過爬蟲爬取各個招聘網站的相關資料,對細分崗位進行深入分析,本文的呈現,感謝科多大資料資料分析培訓班第10期學員“NO.1”團隊的技術支援。 此次分析結果呈現經歷三個階段: 細分查詢目

資料演算法:Hadoop_Spark資料處理技巧》艾提拉筆記.docx 第1章二次排序:簡介 19 第2章二次排序:詳細示例 42 第3章 Top 10 列表 54 第4章左外連線 96 第5

《資料演算法:Hadoop_Spark大資料處理技巧》艾提拉筆記.docx       第1章二次排序:簡介 19 第2章二次排序:詳細示例 42 第3章 Top 10 列表 54 第4章左外連線 96 第5章反轉排序 127 第6章

除了Hadoop其他6個你必須知道的熱門資料技術

      你知道新的市場領導者和曾經的領導者之間的關鍵區別是什麼嗎? 那就是“資料管理”。任何無法處理資料並將其投入使用的企業,很可能會讓位給那些能夠更好處理資料的。 事實上,大資料和其流動性的力量能促使企業發展。 大資料是大量資料的術語

除了Hadoop還有6個你必須知道的熱門資料技術

你知道新的市場領導者和曾經的領導者之間的關鍵區別是什麼嗎?   那就是“資料管理”。任何無法處理資料並將其投入使用的企業,很可能會讓位給那些能夠更好處理資料的。   事實上,大資料和其流動性的力量能促使企業發展。   大資料是大量資料的術語。由於

資源任務排程演算法實現(資料雲端計算作業來的)

實驗目的 本實驗將引導學生對雲端計算任務排程演算法的相關研究現狀進行深入分析和研究,從影響使用者任務的執行效率和系統資源的使用效率的角度出發,在現有的雲端計算任務排程演算法的基礎上,進行理論創新,從模型高效和演算法高效2個層面上設計雲端計算任務排程模型、演算法並實現。 實驗思路 實驗主要

九章演算法 基礎演算法 強化演算法 系統設計 資料 安卓 leetcode 高清視訊

九章網站傳送門:http://sina.lt/eQc5 leetcode 直播視訊講座錄影 九章演算法視訊錄影,PPT 演算法班,演算法強化班,java入門與基礎演算法班,big data專案實戰班,Andriod專案實戰班 九章演算法下載 九章演算

JAVA轉資料的學習之路就該這樣走(內附1T資料資料

如今使用了 23 年的 Java不再免費了,Java程式設計師是時候該轉移了,現在大資料的時代下,更是Java程式設計師們轉型可遇而不可求的機遇。為什麼要這麼說呢? 因為Java程式設計師轉型大資料工程師有著天然進階優勢,不僅僅是前景和薪資。技術層面來說,大資料使用的Hadoop(在分散式伺服器

資料演算法-Hadoop/Spark資料處理技巧》讀書筆記(一)——二次排序

寫在前面: 在做直播的時候有同學問Spark不是用Scala語言作為開發語言麼,的確是的,從網上查資料的話也會看到大把大把的用Scala編寫的Spark程式,但是仔細看就會發現這些用Scala寫的文章

資料演算法-Hadoop/Spark資料處理技巧》讀書筆記(四)——移動平均

移動平均:對時序序列按週期取其值的平均值,這種運算被稱為移動平均。典型例子是求股票的n天內的平均值。 移動平均的關鍵是如何求這個平均值,可以使用Queue來實現。 public class MovingAverageDriver { public

經典演算法題:資料處理常見演算法

第一部分、十道海量資料處理 1、海量日誌資料,提取出某日訪問百度次數最多的那個IP。   此題,在我之前的一篇文章演算法裡頭有所提到,當時給出的方案是:IP的數目還是有限的,最多2^32個,所以可以考慮使用hash將ip直接存入記憶體,然後進行統計。  再詳細介紹下此方案:

長得帥氣有優勢會技術才是本事!盤點這些資料處理技術你會多少?

一 、資料分析處理需求分類 1、事務型處理 在我們實際生活中,事務型資料處理需求非常常見,例如:淘寶網站交易系統、12306網站火車票交易系統、超市POS系統等都屬於事務型資料處理系統。 這類系統資料處理特點包括以下幾點: 一是事務處理型操作都是細粒度操作,每次事務處理涉及資料量都很

Kona JDK 在騰訊資料領域內的實踐與發展

導語 | 近日,雲+社群技術沙龍“騰訊開源技術”圓滿落幕。本次沙龍邀請了多位騰訊技術專家,深度揭祕了騰訊開源專案TencentOS tiny、TubeMQ、Kona JDK、TARS以及MedicalNet。本文是楊曉峰老師關於騰訊基於OpenJDK的自研Kona JDK開源專案的詳細介紹。 一、Tencen

布隆過濾器你也可以處理十幾億的資料

>文章收錄在 GitHub [JavaKeeper](https://github.com/Jstarfish/JavaKeeper) ,N線網際網路開發必備技能兵器譜 ## 什麼是 BloomFilter **布隆過濾器**(英語:Bloom Filter)是 1970 年由布隆提出的。它實際上是

達觀資料王子豪:這5個例子小學生都秒懂分類演算法

分類演算法作為資料探勘、機器學習中重要的研究領域,在新聞分類、黃反廣告識別、情感分析、觀點挖掘等應用實踐中都有著廣泛的應用。如何將樸素貝葉斯、決策樹、支援向量機這些常見的分類演算法通俗易懂地講給對人工智慧感興趣的人?達觀研究院的這篇分類演算法科普文章,以日常生活為例子,讓小學生都能秒懂分