單元測試軟體工程概述

來源:互聯網
上載者:User

標籤:

  

 單元測試簡介   

      單元測試是代碼正確性驗證的最重要的工具,也是系統測試當中最重要的環節。也是唯一需要編寫代碼才能進行測試的一種測試方法。在標準的開發過程中,單元測試的代碼與實際程式的代碼具有同等的重要性。每一個單元測試,都是用來定向測試其所對應的一個單元的資料是否正確。     單元測試是由程式員自己來完成,最終受益的也是程式員自己。可以這麼說,程式員有責任編寫功能代碼,同時也就有責任為自己的代碼編寫單元測試。執行單元測試,就是為了證明這段代碼的行為和我們期望的一致。單元測試還具有一下幾個好處:   

1、 能夠協助程式員儘快找到BUG的具體位置 

2、  能夠讓程式員對自己的程式更有自信    

3、能夠讓程式員在提交項目之前就將代碼變的更加健壯 

4、 能夠協助程式員更好的進行開發 

5、  能夠向其他程式員展現你的程式該如何調用 

6、 能夠讓項目主管更瞭解系統的當前狀況

?1.1    能夠協助程式員儘快找到BUG的具體位置 

     在沒有單元測試的時代,我們大多數的錯誤都是通過操作頁面的時候發現的。當我們發現一個錯誤的時候,會根據異常拋出的地點來確定是哪段代碼出現了問題。但是大多數時候,我們不會所有方法中都使用Try塊去處理異常(這一也是低效的)。因此一旦發現一個異常通常都是最頂層代碼拋出的,但是錯誤往往又是在底層很深層次的某個對象中出現的。當我們找到了這個最初拋出異常的方法的時候,我們可能無法得知這段代碼到底是哪裡出了問題。只能逐行代碼的去尋找,一旦這個方法中使用的某個對象在外部有註冊事件或者有其他的操作正在與當前方法同步進行,那麼就更難發現錯誤真正的原因了。    有經驗的程式員也會知道,大多數的時候,我們並不是真正的在編寫新的代碼,而是在修改舊的代碼出現的錯誤。通常這個比例會大於2比8,這也是編寫代碼的時候的二八現象——編寫代碼的時間是二,而為這段代碼找錯誤、修改錯誤所花費的時間卻是八。    在這種狀態之下,我們在找錯誤的時候會直接編譯整個程式,然後通過介面逐步的操作到錯誤的地方然後再去尋找代碼中是否有錯誤。這樣的找錯誤的方法效率非常低。但是當我們擁有單元測試的時候,我們就不需要通過介面去一步一步的操作,而是直接運行這個方法的單元測試,將輸入的條件類比成出現錯誤的時候輸入的資訊和調用的方法的形式,這樣就可能很快的還原出錯誤。這樣解決起來速度就提高了很多,每次找到錯誤都去修改單元測試,那麼下次就不會再出現相同的錯誤了。如果通過類比,單元測試也沒有出現任何異常,這時也可以斷定,並非該代碼出現的錯誤,而是其他相關的代碼出現的錯誤。我們只需再調試其他幾個相關的代碼的單元測試即可找到真正的錯誤。

?1.2    能夠讓程式員對自己的程式更有自信 

     很多時候,當主管問我們程式會不會再出問題的時候,我們會很難回答。因為我們沒法估計到系統還可能出現什麼問題。但是如果這時我們為所有代碼都編寫了單元測試,而且測試代碼的編寫是按照標準去寫的,這些測試又都能夠成功的通過測試。那麼我們就完全有自信說出我們的把握有多大。因為在測試代碼中,我們已經把所有可能的情況都預料到了,程式碼中也將這些可能預料到的問題都解決了。因此我們會對自己的程式變得越來越自信。

?1.3    能夠讓程式員在提交項目之前就將代買變得更加健壯 

      大多數程式員在編寫代碼的時候,都會先考慮最理想化情況下的程式該如何寫,寫完之後在理想狀態下編譯成功,然後輸入理想的資料發現沒有問題。他們就會自我安慰的說“完成了”。然後可能為了趕進度,就又開始作另外的程式了。時間久了這種理想化的程式就越來越多。一旦提交測試,就發現這裡有錯誤那裡有錯誤,然後程式員們再拿出時間來這裡補個漏洞那裡補個漏洞。而且在補漏洞的過程中,也可能繼續沿用這種理想化的思路,就導致了補了這裡又導致那裡出問題的情況。但是如果在初期,我們就為每段代碼編寫單元測試,而且根據一些既定的標準去寫,那麼單元測試就會提前告訴程式員哪些地方會出現錯誤。那麼他們可能在編寫過程中就提前處理了那些非理想狀態下的問題。這樣我們的代碼就會健壯很多。

?1.4    能夠協助程式員更好的進行開發 

   “碼未動,測試現行。”這是極限編程中倡導的一種編程模式,為什麼要這樣呢?因為我們在編寫單元測試的過程中,其實就是在設計我們的代碼將要處理哪些問題。單元測試寫的好,就代表你的代碼寫的好。而且你會根據單元測試的一些預先設想的情況去編寫代碼,就不會盲目的添加一個屬性、添加一個方法了。

?1.5    能夠向其他程式員展現你的程式該如何調用   

      ?通常情況下,單元測試代碼中寫的都是在各種情況下如何調用那段待測試的代碼。因此這個單元測試同時也向其他人員展示了我們的代碼該如何調用?在什麼情況下會拋出什麼異常?等等。這樣一個單元測試就變成了一個代碼性的協助文檔了。

?1.6    能夠讓項目主管更瞭解系統當前的狀況  

     傳統的管理中,項目的進度、代碼的品質都只是通過口頭的形式傳遞到主管那裡的。因此有時候主管獲得的反饋可能事實。但是如果通過一個完善的單元測試系統,那麼主管就可以通過查看單元測試的運行結果和單元測試的程式碼涵蓋範圍來確定開發人員的工作是否真正完成。

2.1 建立單元測試 

     該工具可以對任何類、介面、結構等實體中的欄位、屬性、建構函式、方法等進行單元測試。建立單元測試大致可以分為兩類:  一、 整體測試,整體測試是在類名稱上右擊滑鼠,在下拉式功能表中點擊建立單元測試選項。這樣就可以為整個類建立單元測試了,這時他會為整個類可以被測試的內容全部添加測試方法。開發人員直接在這些自動產生的測試方法中添加單元測試代碼就可以了。 二、?單獨測試,如果只想單獨對某個方法、屬性、欄位進行測試,則可以將滑鼠焦點放在這個待測試的項目名稱之上,然後點擊滑鼠右鍵,在右鍵菜單中選擇建立單元測試選項。這樣就可以單獨為某個方法建立單元測試了。

?2.2 編寫單元測試代碼 

    建立完單元測試之後,就可以為單元測試編寫測試代碼了。具體的測試代碼的編寫標準會在第三章中介紹。

2.3 運行單元測試 

    單元測試代碼編寫完畢,就可以通過運行單元測試來進行測試了。需要運行單元測試的時候,需要開啟測試管理器視窗。該視窗可以通過菜單中的“測試”-“視窗”——“測試管理器”來開啟。開啟該視窗之後,就可以在該視窗中看到我們所建立的單元測試的列表。我們可以在列表中勾選某個單元測試前面的複選框。然後右擊滑鼠在右鍵菜單中點擊“調試選中的測試”或者“運行選中的測試”。    調試選中的測試的時候,我們可以在測試代碼中或者我們自己的代碼中添加斷點並逐步運行以看其狀態。    運行選中的測試只會運行測試並不能夠進行測試,這時代碼的運行是類比真實軟體啟動並執行時候的情況執行的。我們可以根據我們的實際情況來選中執行哪種測試。

2.4 測試結果 

運行了測試之後,我們需要查看這次測試的結果。我們可以通過點擊菜單中的“測試”——“視窗”——“測試結果”來開啟一個[測試結果] 視窗。每次測試都會在測試結果中向我們顯示一些記錄。我們也可以通過雙擊這個測試結果,來查看詳細的結果資訊。

?2.5 程式碼涵蓋範圍

    單元測試寫的是否合理或者是否達到了要求的一個唯一的標準就是整個測試的程式碼涵蓋範圍。程式碼涵蓋範圍其實就是測試代碼所運行到的實際程式路徑的覆蓋率。在實際程式中可能會有很多的迴圈、判斷等分支路徑。一個好的單元測試應該能夠將所有可能的路徑都將走到,這樣就可以保證大多數情況都測試過了。   VS2005中也提供了查看程式碼涵蓋範圍的工具。我們可以通過點擊菜單中的“測試”——“視窗”——“程式碼涵蓋範圍結果”來開啟程式碼涵蓋範圍查看的視窗。若要進行程式碼涵蓋範圍的檢查,我們必須進行設定,因為系統預設情況下是不進行程式碼涵蓋範圍檢測的。若要開啟某個測試的程式碼涵蓋範圍測試,我們必須點擊菜單中的“測試”——“編輯測試回合配置”——“本地測試回合。。。。。。”來開啟一個測試組態視窗。在該視窗左側的列表中選中“程式碼涵蓋範圍”就會顯示程式碼涵蓋範圍的設定。在這個配置中會顯示當前解決方案中可以用來檢測程式碼涵蓋範圍的程式集,我們將需要進行覆蓋率檢測的程式集選中然後點擊“應用”按鈕就可以了。    設定完畢之後,我們就可以直接運行單元測試,測試通過後。我們就可以開啟程式碼涵蓋範圍結果視窗,在這裡我們就能夠看到這些測試覆蓋了多少代碼。當我們在這裡雙擊某個類的時候,就可以看到VS已經將代碼背景改變了顏色。顯示為深棕色的代碼就是沒有覆蓋到的代碼,我們可以通過在單元測試代碼中添加代碼來想辦法覆蓋這些代碼。這樣一個單元測試的全過程就完成了。

    雖然要進行單元測試的代碼會是各種各樣的,但是編寫單元測試代碼還是有規律可循的。測試的對象一般情況下分為方法(包含建構函式)、屬性,因此我們按照這兩個方向來確定單元測試的標準。    由於現在大多數開發人員還沒有真正使用過.NET的單元測試工具,對於單元測試的瞭解程度也不高。因此我們這裡也不便於制定非常多的標準。我們當前主要針對兩大方面進行規範:   1、哪些代碼需要添加單元測試?  2、 單元測試代碼的寫法?

3.1 ?哪些代碼需要添加單元測試  

 如果項目正處在一個最後衝刺階段,主要的編碼工作已經基本完成。因此要全面的添加單元測試,其實是比較大的投入。所以單元測試不能一次性的全部加上,我們只能通過一步一步的來進行測試。    第一步,應該對所有程式集中的公開類以及公開類裡面的公開方法添加單元測試。    第二步,對於建構函式和公用屬性進行單元測試。    第三步,添加全面單元測試。在產品全面提交之前可以先完成第一步的工作,二三步可以待其他所有功能完成之後再進行添加。由於第二三步的添加工作其實於第一步類似,只是在量上的累加,因此我們先著重討論第一步的情況。    在作第一步單元測試添加的時候,也需要有選擇性的進行,我們要抓住重點進行測試。首先應該針對屬於架構技術中的代碼添加單元測試。這裡就包含操作資料庫的組件、操作外部WebService的組件、郵件接收發送組件、後台服務與前提程式之間的訊息傳遞的組件等等。通過為這些主要的可複用代碼進行測試,可以大大加強底層操作的正確性和健壯性。    其次為商務邏輯層對介面公開的方法添加單元測試。這樣可以讓商務邏輯保持正確,並且能夠將大部分的業務操作都歸納到單元測試中,保證以後產品發布之後,一旦出現問題可以直接通過商務邏輯的單元測試來找到BUG。剩下的代碼大部分屬於代碼產生器產生的,而且大多數的操作都是類似的,因此我們可以先針對某一個商務邏輯對象做詳細的單元測試。通過這樣的規定,單元測試添加的範圍就減少了很多。    如果項目是剛剛開始的,那麼應當對所有公開的方法和屬性都添加單元測試。

?3.2 單元測試代碼的寫法 

 在編寫單元測試代碼的時候需要認真的考慮以下幾個方面:   l、所測試的方法的程式碼涵蓋範圍必須達到100%。   2、所測試的代碼內部的狀態,例如執行了某個方法之後,該方法所在的類中某個屬性或者傳回值是否與預期相同。   3、被測試代碼所使用的外部裝置的狀態,如資料庫是否可讀、網路是否可用、印表機是否可用、WebService是否可用等等。每一段單元測試代碼,必須考慮到以上的三個問題,並且對於這些問題都要有相應的測試。

3.2.1  程式碼涵蓋範圍要求  

    在2.5小節中已經講了什麼是程式碼涵蓋範圍和程式碼涵蓋範圍查看的方法。在這裡我們著重來講怎樣將程式碼涵蓋範圍提升到100%。    一般情況下,程式碼涵蓋範圍低,說明測試代碼中沒有過多的考慮某些特殊情況。特殊情況包括:   l 邊界條件資料,比如實值型別資料的最大值、最小值、DBNull,或者是方法中所使用的條件邊界,例如a>100那麼100就變成了這個資料的邊界。而且在測試的時候還必須把超出邊界的資料作為測試條件進行測試。   2 空資料,一般空資料對應於參考型別的資料,也就是Null值。   3 格式不正確資料,對於參考型別的資料或者結構對象,類型雖然正確但是其內部的資料結構不正確的資料。例如一個資料庫實體物件,資料庫中要求其某個屬性必須為非空,但是這時我們可以屬於一個空。這樣這個對象就屬於一個不正確資料庫。這三種資料都是針對被測試方法中所使用的外部資料來說的。方法中使用的外部資料無非就是方法參數傳入的資料和方法所在的對象的屬性或者欄位的資料。因此在編寫測試代碼的時候就必須將這些使用到的資料設定為上面這幾種情況的資料來檢測方法執行的情況。這才能保證方法編寫是正確的。    在編寫單元測試代碼的時候先瞭解到被測試方法可能會使用的外部資料,然後將這些外部資料一次設定為上面規定的這幾種情況,然後再執行方法。這樣就基本可以達到外部資料所有情況都能夠正確測試到了。通過這種方法編寫的單元測試程式碼涵蓋範圍一般可以超過80%。3.2.2 預期值是否達到 

   在編寫單元測試的時候,不能單純的追求程式碼涵蓋範圍。有時候程式碼涵蓋範圍已經達到了100%,程式也能正常運行,但是可能會出現方法執行完畢之後某些資料並非預期的數值。這時就必須對執行的結果進行斷言。在.NET提供的單元測試模組中,可以在單元測試中直接使用一個類的一些靜態方法來判斷某個值是否達到了預期的情況。這個類是Assert。在這個類中公開了很多判斷等效性、判斷開關性、判斷非空性等一系列方法。這些方法可以讓你提前做出預測,一旦程式執行之後,如果這些斷言不能通過,就代表代碼有錯誤。    在使用斷言的時候,我們要求要達到平均5行測試代碼就要有一個斷言。    通過添加斷言,我們就可以對程式執行過程中資料的正確性做一個檢測,保證我們的程式不出現寫錯資料的情況或者出現錯誤狀態的情況。

3.2.3 外部裝置狀態更改時測試是否正常通過  

     當程式碼涵蓋範圍和預期值都達到了我們的要求之後,整個程式其實就基本達到了品質標準。但是這樣還不全面,因為很多程式都要使用到外部的裝置或者程式,例如資料庫、印表機、網路、串列口、並行口等等。當這些裝置發生改變或者停用時候,程式就可能出現一些不可預知的錯誤。因此一個健壯的程式也必須考慮到這些情況,這時通常都是通過將這些裝置確定的設定為這些不正常狀態來檢測程式可能會出現的問題。然後再在測試程式中將這些條件加上。    上面所介紹的只是簡單的單元測試的入門層級的要求,當然真正的單元測試還有很多更加複雜的要求和測試技巧。但是對於一個初學者而言,如果能達到上述的要求,那麼你的代碼的健壯性應該能夠滿足大部分要求了。只是在比較標準的工業化開發的時候,才需要將單元測試繼續深化。如果有時間的話,我會在以後再詳細闡述較深層次的單元測試方法。 

單元測試軟體工程概述

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.