團隊隊員:201421123043 邱文鑫 + 201421123045 念其鋒
碼市的位址連結:https://git.coding.net/qwx_hh/Test.git
一、背景介紹
1.什麼是單元測試?
在《建構之法》課本的第二章對于“單元測試”有如下的解釋:絕大部分軟體都是由多人合作完成的,大家的工作互相有依賴關系。最典型的例子就是,某人負責的子產品的功能被其他人調用。軟體的很多錯誤都來源于程式員對子產品功能的誤解、疏忽或不了解子產品的變化。如何能讓自己負責的子產品功能定義盡量明确,子產品内部的改變不會影響其他子產品,而且子產品的品質能得到穩定的、量化的保證呢?這時候就需要單元測試來解決這個問題。
2.為什麼需要單元測試呢(需求分析)?
單元測試是由程式員自己來完成,最終受益的也是程式員自己。可以這麼說,程式員有責任編寫功能代碼,同時也就有責任為自己的代碼編寫單元測試。執行單元測試,就是為了證明這段代碼的行為和我們期望的一緻。
在一般情況下,一個功能子產品往往會調用其他功能子產品完成某項功能,如業務層的業務類可能會調用多個DAO完成某項業務。對某個功能子產品進行單元測試時,我們希望屏蔽對外在功能子產品的依賴,以便将焦點放在目标功能子產品的測試上。這時模拟對象将是最有力的工具,它根據外在子產品的接口模拟特定操作行為,這樣單元測試就可以在假設關聯子產品正确工作的情況下驗證本子產品邏輯的正确性了。
單元測試的意義主要有以下幾點:
- (1)減少bug
- 一個機器,由各種細小的零件組成,如果其中某件零件壞了,機器運作故障。必須保證每個零件都按設計圖要求的規格,機器才能正常運作。一個可單元測試的工程,會把業務、功能分割成規模更小、有獨立的邏輯部件,稱為單元。單元測試的目标,就是保證各個單元的邏輯正确性。單元測試保障工程各個“零件”按“規格”(需求)執行,進而保證整個“機器”(項目)運作正确,最大限度減少bug。
- (2)快速定位bug,減少調試時間
如果程式有bug,我們運作一次全部單元測試,找到不通過的測試,可以很快地定位對應的執行代碼。修複代碼後,運作對應的單元測試;如還不通過,繼續修改,運作測試.....直到測試通過。
對于Android項目,要測試某個功能點,不用單元測試的話,必須運作在真機、模拟器上,慢慢debug找到問題點。運作程式到真機,快則半分鐘,慢則幾分鐘。junit隻需在本地運作即可,就幾秒的事(robolectric需要十幾秒)。有時,寫那個功能子產品的員工已離職,APP運作出錯(邏輯錯誤,非crash or exception),你根本就不知道調試哪個類。如果離職的員工之前寫了單元測試,運作一下立馬就找到問題點了。單元測試大大減少調試時間,進而達到節約時間成本的效果。
- (3)提高代碼品質
- 由于每個單元有獨立的邏輯,做單元測試時需要隔離外部依賴,確定這些依賴不影響驗證邏輯。因為要把各種依賴分離,單元測試會促進工程進行元件拆分,整理工程依賴關系,更大程度減少代碼耦合。這樣寫出來的代碼,更好維護,更好擴充,進而提高代碼品質。
(4)放心重構
重構,每個開發者都會經曆,重構後把代碼改壞了的情況并不少見。以往,寫完一個架構,運作APP,沒什麼問題,完事。由于最初的架構并不是你寫的,可謂牽一發動全身,你改1個方法導緻整個架構運作失敗....
如果你有單元測試,情況大不相同。寫完一個類,把單元測試寫了,確定這個類邏輯正确;寫第二個類,單元測試.....寫100個類,道理一樣,每個類做到第一點“保證邏輯正确性”,100個類拼在一起肯定不出問題。你大可以放心一邊重構,一邊運作APP;而不是整體重構完,提心跳膽地run。
3.怎樣才算是一個好的單元測試呢?
- (1)單元測試一個在最基本的功能/參數上驗證程式的正确性;
- (2)單元測試必須由最熟悉代碼的人(程式的作者)來寫;
- (3)單元測試後,機器狀态保持不變;
- (4)單元測試要快(一個測試的運作時間是幾秒鐘,而不是幾分鐘);
- (5)單元測試應該産生可重複、一緻的結果;
- (6)單元測試應該覆寫所有代碼路徑;
- (7)單元測試應該內建到自動測試的架構中;
- (8)單元測試必須和産品代碼一起保護和維護。
二、設計測試架構,模拟測試資料
1.請給出計算子產品的測試用例及運作結果,展示單元測試的每個環節
以下的這次計算子產品我們寫在同一個子產品當中,但是測試的時候我們是分開測試的,具體如下:
(1)整數的除法測試:

(2)分數的除法測試:
(3)整數的加法測試
(4)分數的加法測試
(5)整數的減法測試
(6)分數的減法測試
(7)整數的乘法測試
(8)分數的乘法測試
(9)分數的覆寫率測試
(10)整數的覆寫率測試
2.描述測試過程中遇到的問題及解決方案
(1)對代碼測試幾乎不了解,在插件的安裝上花費了很多時間,特别是代碼覆寫率這一塊。具體指令并不熟悉,花了時間研究了基礎操作,基本上都是通過百度來獲得解決的辦法;
(2)原本計算的類包含了随機數選擇、分數計算與整數計算這三個,是以剛剛知道實驗要求的時候我們無從下手。後來經過我們的讨論之後,還是決定将原先的一個類拆分成三個類,然後把其中的分數計算類和整數計算類分别摘出來測試,這也給我們帶來了較大的工作量;
(3)因為在原先的類中,取值已經避免了0當除數與分子的産生,是以沒有必要測試這兩種情況的異常報錯。
(4)當我們在進行分數運算的時候,我們發現有的時候結果本應該顯示成整數,但是程式運作的結果卻是假分數,這不符合化簡的要求,是以我們添加了幾句代碼,使得當分子與分子與分母的公約數相除等于1或者-1時,輸出分母除分子,即從假分數轉換成整數。
三、關于結對程式設計
1.使用結對程式設計模式的感受
這是我們第二次使用結對程式設計的合作模式,在我們還沒有接觸結對程式設計的時候,我們都認為兩個人一起做一個項目,就應該是一個人負責實作這幾種功能,另一個人負責實作另外幾種功能,最後再将這些功能合并到一起,就形成我們倆一起合作完成的項目。幸虧有了第一次結對程式設計的經驗,我們這次一開始就找到了自己“駕駛員”和“領航者”的定位,兩個人同時坐在同一台電腦前,一個人敲代碼另一個幫忙複審和提建議,監督一下有沒有什麼錯誤,一段時間後再對調角色,循環往複。這次結對程式設計與第一次結對程式設計的感覺不同,具體有以下幾點:
(1)、當我作為“領航員”的時候,我就坐在我隊友的旁邊看着他敲代碼(我們倆就是上下鋪,電腦桌也就在隔壁,是以異常友善),他經常嘴上念的是正确的代碼,敲上去的時候卻敲成另外一種名稱的代碼,還好我就盯着他敲,及時指出了這個低級錯誤,不然他一個人的話可能要浪費很多時間才能找出這個問題;
(2)、當我們在結對程式設計的時候,隻要對方遇到問題,都不用解釋問題的前因後果,我們就能一下子知道對方指的是什麼,這就是結對程式設計給雙方帶來的對互相程式設計思路的熟悉度,這也是以前那種各做各的的模式所體驗不到的感覺;
(3)、我們兩個人在結對程式設計的時候,還是遇到了一些我們倆都無法解決的問題,不過這種感覺跟自己一個人遇到難題時的感覺完全不一樣,竟然有一種“完全不虛,我們遲早會解決”的蜜汁自信,可能這就是兩個人的力量與一個人力量的差别。
2.給我隊友的“漢堡包”
(1)、我們兩個人本來就是很親密的舍友,但在宿舍一般是比較了解對方的生活習慣和課餘時間的興趣愛好,通過這次的結對程式設計,讓我在宿舍看到了他“學霸”的那一面,他打起代碼來跟平時的他完全不一樣,整個人沉浸在發現問題和解決問題的過程當中,讓我對他“肅然起敬”,對他的專業技能也是欽佩不已;
(2)、我們在程式設計過程中經常遇到很多問題,是很多我們從來沒有學過的問題,我往往都手足無措,而他卻很沉着,精通各種查找資料的途徑,不管是部落格還是貼吧,他總能找到他需要的資源,這一點也是讓我欽佩不已的;
(3)、不過在程式設計的過程我也發現了他的一些“bug”,他的英語水準較低,是以在寫代碼過程中經常出現英語拼寫錯誤導緻報錯,這一點我在當“領航員”的時候見識過了非常多次,希望他能在課餘時間多提高一下自己的英語水準,這對程式設計技術會有一定的提高。
3.結對程式設計照片
四、一周之後看代碼
1.良好的設計
一開始的設計真的很重要,一開始的設計可以多花一點時間,這叫“磨刀不誤砍柴工”,否則會出現很多的麻煩。比如一開始設計的時候,沒有用字元串來封裝式子,導緻在主函數中,要對輸入的字元串進行各種拆分各種判斷,導緻邏輯結構不清晰,代碼備援大。是以這一點的改進使得後續的一些函數編寫容易多了。
2.編碼規範
我們的編碼規範在第一次結對程式設計的時候就定好了,在後面有添加變量的時候我們會立即跟對方通氣,是以我們在一周之後再看代碼的時候,隻要對照着之前我們簽訂的代碼規範文檔來看,就可以很快地看懂一周前的那些代碼,進而節省了很多時間。
3.必要的注釋
注釋這方面我們倆做得還是有點少,我們一般都會在宿舍直接向對方提出來,有的時候大家會聽完就忘了,比如一周後往往記不起之前當面說的那些注釋,是以把一些注釋記錄下來還是非常有必要的,也可以節省一些時間。
五、PSP展示
PSP2.1 | personal sofware process stages | time(%)senior student | time(%) |
planning | 計劃 | 10 | 15 |
estimeate | 估計這個任務需要多少時間 | 200 | 320 |
development | 開發 | 15 | 20 |
analysis | 需求分析 | 20 | 10 |
design spec | 生成設計文檔 | ||
design review | 設計複審 | 30 | |
coding standard | 代碼規範 | ||
design | 具體設計 | 60 | |
coding | 具體編碼 | 100 | 200 |
code review | 代碼複審 | ||
test | 測試 | 50 | 100 |
reporting | 報告 | 40 | 50 |
測試報告 | |||
計算工作量 | 5 | ||
并提出過程改正計劃 | 5 |
六、小結與感受
1.對單元測試的步驟和過程還是很不了解,是以上網查資料的過程中花了大量的時間,這也讓我看出來了自己還存在着許多的不足,還是需要繼續深入學習Java的知識和eclipse軟體的使用,這樣子以後做項目就可以節約不少的時間;
2.雖然我和隊友每天都在溝通,但有時候對他寫代碼的邏輯結構還不是很了解,這一點增加了單元測試的難度,以後要說好在寫的時候要邊敲代碼邊把自己的想法說出來,這樣子大家會更加了解互相的想法;
3.經過這次的單元測試我發現隻有自己寫的代碼測試的時候才會比較有頭緒,如果是隊友寫的有可能會出現懵逼的情況,是以還是推薦誰寫的代碼誰來做測試。