走進單元測試四:單元測試背后的思考和感悟


  二月底就要完成所有的單元測試的任務了,做了將近三個月的時間,如果放在以前我有一肚子苦水要述說,不過經歷了一些思想上的洗禮之后,不在那么單純,只為把手頭工作做的更加出色而已!

    這是單元測試最后一篇了,來做個總結把!  

  目錄:

  好的單元測試應該具有的特點

  單元測試的命名規范

  建立自己的公共調用庫

  單元測試帶給我的思考和感悟

  總結圖示 

 

 1.好的單元測試應該具備的特點                

    一個好的單元測試一定有它具備的特點,下面就來說說那些主要的特點!

    主要概括為 → A-TRIP原則:

    自動化  → Automatic

    徹底性  → Thorough

    可重復性   → Repeatable

    獨立性  → Indepentdent

    專業性  → Professional

    恰到好處的單元測試會使你的工作輕松,代碼整潔干凈,亂用,沒有准則的用會浪費你大量的時間,不但沒有效果還會是工期延誤,所有了解單元測試很重要! 

 

    ① 自動化

      a) 不需要人的參與,有的時候只是輕輕的點擊一個按鈕就能自動執行,所以自動化的標志是不能比點擊一個按鈕的過程還要復雜!

      b) 在簽入其它的測試代碼時不能對現有的代碼造成影響!

      c) 能夠自動識別測試是失敗還是成功(VS2008以后的版本都集成了這個功能)!

      d) 在任何時候,任何地方都能自動運行(所以“Moles”技術就是關鍵)!

      核心:執行測試代碼和檢查測試結果都必須自動化(VS2008以后版本都實現這個功能了)!

        總結:I,不要引入一個由於需要手動步驟而打破單元測試的自動化模型的測試!

              II,對於測試所需要的任何條件(大部分是數據庫)都應該讓它成為自動化測試的一部分,如果有需要可以使用Mole技術!

   

    ② 徹底性

      所謂的徹底性就是說你的測試案例必須要考慮的全面,應該把可能出現的問題都做成測試案例!

      具體從哪些方面着手,可以參數這篇:走進單元測試二:測試需要從哪些方面着手

 

    ③ 可重復性

      a) 每個測試案例應該獨立於所有的其它測試,而且必須獨立於周圍的(系統)環境!

      b) 測試代碼能夠一次又一次的運行,在不修改代碼的前提下都能產生一樣的結果,否則有BUG!

      c) 不要把測試代碼寫死,應該寫的更加靈活一點,運用封裝,重構等等的思想!

      d) 不要讓測試本身也出現BUG,確保測試代碼的正確性!

 

    ④獨立的

      a) 每個測試應該有很強的針對性,也就說一個測試只能測試一個方面的內容!

      b) 每個測試應該獨立於環境(軟件所處的系統環境)和其它測試!

      總結:I,每個測試都不能夠依賴於其它測試,你可以在任何時間運行這個測試而不受其它測試的影響,每一個測試都應該是一座孤島

          II,所以測試一個函數都有很多個測試方法,只有這樣才是真正的測試!

 

    ⑤專業的

      a) 所謂的專業就是你的測試代碼應該跟你的開發代碼保持一樣的風格,如:簡潔明了,封裝,解耦,不要出現“Hard Core”,要靈活一點!

      b) 拒絕編寫冗余的測試代碼,千萬要小心不要掉進這個陷阱,因為像我們這樣的新手在初期都不會注意到這樣的問題,所以我們要牢記在心里!

      c) 遵循普遍規則:1.維護封裝 2.降低耦合!

      總結:不管怎么樣你都應該認認真真的對待單元測試,代碼的質量要求都應該跟開發代碼同等水平,這是作為開發者必備的素質!

 

 2.單元測試的命名規范                    

    在我們項目的中,可能需要測試的方法有成千上百個,而每一個測試方法都有可能寫三個以上的測試案例,那么怎么來維護這么測試案例呢?

    所以我們應該規范方法的命名方式,那么其他人在閱讀你的測試代碼時,直接通過方法名就能知道你的測試案例是測試哪個方面的了!

    Note:單元測試案例類似於一個可執行文檔,可以幫助其它的開發人員了解方法的作用!

    在我們的項目中是這樣規定的:方法名 + _ + 你測試是哪個方面的內容 + _ + 產生的結果!

    下面我就舉個列子,下面的測試方法命名就是針對這個函數來命名的,如:    

1      public DataSet GetDetails(int ID)
2 {
3    // 方法的作用:這個一個獲取數據,並包裝成一個DataSet的方法,傳入的參數是一個bondAppID,那么我們怎么來設計案例和命名方法名呢?
5         }

 

    ①首先設計你的測試案例

      看到這個方法我就會有這幾個想法:1,最大值 2,最小值 3,剛剛好的值 4,隨便一個值 5,還有的測試案例會隨着你代碼中的邏輯而產生!

       下面是我的測試案例以及方法名的命名,測試方法是上面的那個:      

16         /// <summary>
17      /// Input valid bond ,but the cheque is presented Status.
18      ///</summary>
19 [TestMethod()] //如果你預期有數據返回,那么就應該在最后面加上“RecordFound”,這樣別人看的時候就能一目了然了!
20 public void GetDetails_CheckPresentedStatus_RecordFound()
21 {
22 //To Do.
30 }
31
32 /// <summary>
33      ///Cancel Status.
34      ///</summary>
35 [TestMethod()]
36 public void GetDetails_CheckCancelStatus_RecordFound()
37 {
38 //To Do.
45 }
46
47 /// <summary>
48      /// Input max.
49      ///</summary>
50 [TestMethod()]
51 public void GetDetails_CheckDetailsByMaxBoundaryValue_NoRecordFound()
52 {
53 //To Do.
59 }
60
61 /// <summary>
62      /// Input min.
63    ///</summary>
64 [TestMethod()]
65 public void GetDetails_CheckDetailsByMinBoundaryValue_NoRecordFound()
66 {
67 //To DO.
73 }
74
75 /// <summary>
76      /// Any bondID.
77      ///</summary>
78 [TestMethod()]
79 public void GetDetails_CheckDetailsByAnyBondID_NoRecordFound()
80 {
81 //To Do.
89

     

    ② 說一下總的命名規范

      a) 如果返回值是“Bool”型的話,應該在最后面加上“RetrunTrue”或“ReturnFalse”!       

          如:CheckRebateHasNewChange_ExistNewChanges_ReturnTrue

      b) 如果返回值是集合或者DataSet之類的類型話,應該在最后面加上“RecordFound”或者“NoRecordFound”!

          如:GetPurchaseOrder_ByPurchaseOrderId_RecordFound

      c) 如果是測試異常的話,應該在后面加上“ThrowException”!

          如:CreateRebateApplication_ExistSameRebateID_ThrowException

      d) 如果是歲數據庫進行刪除或者更新,插入的操作時,應該在后面寫上“DataUpdated”或“NoDataUpdated”!

          如:UpdateClientIncome_UpdateIncome_DataUpdated

      總結:基本的變動部分都是你中間的描述,中間的描述盡量做到簡潔明了,應該以動詞開頭,如:Update,Input,等等!

 

  總結好的命名方式可以增強代碼的可讀性,尤其是類似於單元測試這樣的可讀性文檔,應該更加注意這方面的考慮! 

 

 3.建立自己的公共調用庫                      

    一個好的單元測試應該都有自己的公共調用庫,這樣能減少很多的冗余代碼,使的代碼簡潔易懂!

    所以建立了公共庫的單元測試符合了單元測試特點中的專業性 → 1.維護封裝,解耦等等特點!

 

    ①建立數據庫訪問庫

      測試中的准備數據從何而來,有的時候數據准備比較簡單,那么如果傳入的參數是DataSet的呢,里面的數據比較多呢,或者更新數據庫呢,我們應該怎么做?

      那么我們應該去數據庫中查找數據,然后在組合到DataSet中去,所以建立必要的數據庫訪問類很重要!

 

    ②建立自己的公共庫

      這些是為了你驗證數據,或者搭建環境等等的一些用處,提高編寫測試代碼的速度!

    如:,這是我們建立的公共調用庫,所以如果建立了庫,對於我們的單元測試將是大有裨益的!

 

 4.單元測試帶給我的思考和感悟                     

    ①感悟

      說實話從一開始做單元測試的時候,我對它真的很鄙視,我覺得它的含金量很少,編寫單元測試代碼太枯燥了,導致了那時候我的心態是多么的浮躁,以至於在思想方面出現了偏差,感興趣的朋友可以看看這篇文章 → 工作的思考,是走還是留

      經過一段時間的自我反省,也確實讓我慢慢的走上了正軌,感興趣的朋友可以看看 → 迷茫后的感悟

      a) 做任何一件事都應該專心,戒驕戒躁,這是我深有體會的!

      b) 事無大小,不要認為你的事很無聊,很枯燥,很不值得一提,但是一旦你做好做精之后你就發現原來你不知道的還有這么多啊!

      c) 努力 + 學習方法 + 工作態度 → 是我這段時間感悟比較深的一件事!

 

    ②思考

      前提:我們做的單元測試是在項目后期寫,而且我對我負責的模塊是一竅不通的(我是剛剛進這個項目組的),業務流程根本不懂!

      在這樣的前提下,每天先熟悉下流程,看一下代碼,找帶頭大哥幫我講解講解,然后才開始寫單元測試代碼,由此我有了下面三點的思考:

      a) 單元測試不應該在后期做,應該在項目的開發時期去完成它,這個可能跟我們的項目本身有原因把!

      b) 對於找一個還不懂業務流程的人來做單元測試自我感覺是有點不合理的,至少會花費更多的時間來熟悉流程。然后再做單元測試!

      c) 項目過程中的代碼編寫習慣也是很重要的,這是我應該要加強和思考的,也是我需要培養的習慣!

 

 5.總結圖示  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM