為什么要進行單元測試?

發表于:2007-05-05來源:作者:點擊數: 標簽:單元測試測試單元為什么進行
摘要 這篇文章主要闡述這樣一個問題:為什么要進行煩人的單元測試?那些剛剛接觸完全測試概念的 開發 人員常常遇到這個問題。我們這里將采用"反調論證"的方法來回答這個問題, 先提出一些反對單元測試的普遍論點, 然后我們會證明這些論點是站不住腳的。那些
摘要
  這篇文章主要闡述這樣一個問題:為什么要進行煩人的單元測試?那些剛剛接觸完全測試概念的開發人員常常遇到這個問題。我們這里將采用"反調論證"的方法來回答這個問題, 先提出一些反對單元測試的普遍論點, 然后我們會證明這些論點是站不住腳的。那些公開發表的文章和數據充分證實了單元測試的有效性。
  IPL是一個獨立的軟件開發機構,成立于1979年,基地設在Bath。IPL在1988年通過了ISO9001認證,并在1991年通過TickIT認證。IPL開發并提供AdaTEST和Cantata等軟件驗證產品。AdaTEST和Cantata的開發遵循了這些標準的要求。
簡介
  在使新的產品和業務的開發過程工業化的嘗試中,軟件的質量可靠性常常被看作是薄弱環節。
  在最近的十年里,隨著越來越多的人在開發過程中采用了設計方法論和使用CASE工具,軟件質量和可靠性的問題越來越受到重視。大多數軟件設計人員都接受了這方面的培訓,并且在這些正規的軟件設計方法的使用中取得了很多經驗。
  但不幸的是,軟件測試并沒有得到同樣的重視。很多使用這些軟件設計方法的開發活動并沒有使軟件質量和可靠性得到控制。修改最初的軟件開發活動遺留的Bug一般要在軟件維護費用中占到50%的比例,這是不正常的,這些Bug應該在有效的軟件測試過程中被排除掉。
  這篇文章主要闡述這樣一個問題:為什么要進行煩人的單元測試?那些剛剛接觸完全測試概念的開發人員常常遇到這個問題。我們這里將采用"反調論證"的方法來回答這個問題,先列出一些反對單元測試的普遍論點,然后我們會證明這些論點是站不住腳的。那些公開發表的文章和數據充分證實了單元測試的有效性。
什么是單元測試
  單元測試是在軟件開發過程中要進行的最低級別的測試活動,在單元測試活動中,軟件的獨立單元將在與程序的其他部分相隔離的情況下進行測試。
  在一種傳統的結構化編程語言中,比如C,要進行測試的單元一般是函數或子過程。在象C++這樣的面向對象的語言中, 要進行測試的基本單元是類。對Ada語言來說,開發人員可以選擇是在獨立的過程和函數,還是在Ada包的級別上進行單元測試。單元測試的原則同樣被擴展到第四代語言(4GL)的開發中,在這里基本單元被典型地劃分為一個菜單或顯示界面。
  單元測試不僅僅是作為無錯編碼一種輔助手段在一次性的開發過程中使用,單元測試必須是可重復的,無論是在軟件修改,或是移植到新的運行環境的過程中。因此,所有的測試都必須在整個軟件系統的生命周期中進行維護。
  經常與單元測試聯系起來的另外一些開發活動包括代碼走讀(Code review),靜態分析(Static analysis)和動態分析(Dynamic analysis)。靜態分析就是對軟件的源代碼進行研讀,查找錯誤或收集一些度量數據,并不需要對代碼進行編譯和執行。動態分析就是通過觀察軟件運行時的動作,來提供執行跟蹤,時間分析,以及測試覆蓋度方面的信息。
一些流行的誤解
  在明確了什么是單元測試以后,我們可以進行"反調論證"了。在下面的章節里,我們列出了一些反對單元測試的普遍的論點。然后用充分的理由來證明這些論點是不足取的。
它浪費了太多的時間
  一旦編碼完成,開發人員總是會迫切希望進行軟件的集成工作,這樣他們就能夠看到實際的系統開始啟動工作了。 這在外表上看來是一項明顯的進步,而象單元測試這樣的活動也許會被看作是通往這個階段點的道路上的障礙, 推遲了對整個系統進行聯調這種真正有意思的工作啟動的時間。
  在這種開發步驟中,真實意義上的進步被外表上的進步取代了。系統能夠正常工作的可能性是很小的,更多的情況是充滿了各式各樣的Bug。在實踐中,這樣一種開發步驟常常會導致這樣的結果:軟件甚至無法運行。更進一步的結果是大量的時間將被花費在跟蹤那些包含在獨立單元里的簡單的Bug上面,在個別情況下,這些Bug也許是瑣碎和微不足道的,但是總的來說,他們會導致在軟件集成為一個系統時增加額外的工期, 而且當這個系統投入使用時也無法確保它能夠可靠運行。
  在實踐工作中,進行了完整計劃的單元測試和編寫實際的代碼所花費的精力大致上是相同的。一旦完成了這些單元測試工作,很多Bug將被糾正,在確信他們手頭擁有穩定可靠的部件的情況下,開發人員能夠進行更高效的系統集成工作。這才是真實意義上的進步,所以說完整計劃下的單元測試是對時間的更高效的利用。而調試人員的不受控和散漫的工作方式只會花費更多的時間而取得很少的好處。
  使用AdaTEST和Cantata這樣的支持工具可以使單元測試更加簡單和有效。但這不是必須的,單元測試即使是在沒有工具支持的情況下也是一項非常有意義的活動。
它僅僅是證明這些代碼做了什么
  這是那些沒有首先為每個單元編寫一個詳細的規格說明而直接跳到編碼階段的開發人員提出的一條普遍的抱怨, 當編碼完成以后并且面臨代碼測試任務的時候,他們就閱讀這些代碼并找出它實際上做了什么,把他們的測試工作基于已經寫好的代碼的基礎上。當然,他們無法證明任何事情。所有的這些測試工作能夠表明的事情就是編譯器工作正常。是的,他們也許能夠抓住(希望能夠)罕見的編譯器Bug,但是他們能夠做的僅僅是這些。
  如果他們首先寫好一個詳細的規格說明,測試能夠以規格說明為基礎。代碼就能夠針對它的規格說明,而不是針對自身進行測試。這樣的測試仍然能夠抓住編譯器的Bug,同時也能找到更多的編碼錯誤,甚至是一些規格說明中的錯誤。好的規格說明可以使測試的質量更高,所以最后的結論是高質量的測試需要高質量的規格說明。
  在實踐中會出現這樣的情況: 一個開發人員要面對測試一個單元時只給出單元的代碼而沒有規格說明這樣吃力不討好的任務。你怎樣做才會有更多的收獲,而不僅僅是發現編譯器的Bug?第一步是理解這個單元原本要做什么, --- 不是它實際上做了什么。 比較有效的方法是倒推出一個概要的規格說明。這個過程的主要輸入條件是要閱讀那些程序代碼和注釋, 主要針對這個單元, 及調用它和被它調用的相關代碼。畫出流程圖是非常有幫助的,你可以用手工或使用某種工具。 可以組織對這個概要規格說明的走讀(Review),以確保對這個單元的說明沒有基本的錯誤, 有了這種最小程度的代碼深層說明,就可以用它來設計單元測試了。
我是個很棒的程序員, 我是不是可以不進行單元測試?
  在每個開發組織中都至少有一個這樣的開發人員,他非常擅長于編程,他們開發的軟件總是在第一時間就可以正常運行,因此不需要進行測試。你是否經常聽到這樣的借口?
  在真實世界里,每個人都會犯錯誤。即使某個開發人員可以抱著這種態度在很少的一些簡單的程序中應付過去。 但真正的軟件系統是非常復雜的。真正的軟件系統不可以寄希望于沒有進行廣泛的測試和Bug修改過程就可以正常工作。
  編碼不是一個可以一次性通過的過程。在真實世界中,軟件產品必須進行維護以對操作需求的改變作出反應, 并且要對最初的開發工作遺留下來的Bug進行修改。你希望依靠那些原始作者進行修改嗎? 這些制造出這些未經測試的原始代碼的資深專家們還會繼續在其他地方制造這樣的代碼。在開發人員做出修改后進行可重復的單元測試可以避免產生那些令人不快的負作用。
不管怎樣, 集成測試將會抓住所有的Bug
  我們已經在前面的討論中從一個側面對這個問題進行了部分的闡述。這個論點不成立的原因在于規模越大的代碼集成意味著復雜性就越高。如果軟件的單元沒有事先進行測試,開發人員很可能會花費大量的時間僅僅是為了使軟件能夠運行,而任何實際的測試方案都無法執行。
  一旦軟件可以運行了,開發人員又要面對這樣的問題: 在考慮軟件全局復雜性的前提下對每個單元進行全面的測試。 這是一件非常困難的事情,甚至在創造一種單元調用的測試條件的時候,要全面的考慮單元的被調用時的各種入口參數。在軟件集成階段,對單元功能全面測試的復雜程度遠遠的超過獨立進行的單元測試過程。
  最后的結果是測試將無法達到它所應該有的全面性。一些缺陷將被遺漏,并且很多Bug將被忽略過去。
  讓我們類比一下,假設我們要清洗一臺已經完全裝配好的食物加工機器!無論你噴了多少水和清潔劑,一些食物的小碎片還是會粘在機器的死角位置,只有任其腐爛并等待以后再想辦法。但我們換個角度想想,如果這臺機器是拆開的, 這些死角也許就不存在或者更容易接觸到了,并且每一部分都可以毫不費力的進行清洗。
它的成本效率不高
  一個特定的開發組織或軟件應用系統的測試水平取決于對那些未發現的Bug的潛在后果的重視程度。這種后果的嚴重程度可以從一個Bug引起的小小的不便到發生多次的死機的情況。這種后果可能常常會被軟件的開發人員所忽視(但是用戶可不會這樣),這種情況會長期的損害這些向用戶提交帶有Bug的軟件的開發組織的信譽,并且會導致對未來的市場產生負面的影響。相反地,一個可靠的軟件系統的良好的聲譽將有助于一個開發組織獲取未來的市場。
  很多研究成果表明,無論什么時候作出修改都要進行完整的回歸測試,在生命周期中盡早地對軟件產品進行測試將使效率和質量得到最好的保證。Bug發現的越晚,修改它所需的費用就越高,因此從經濟角度來看, 應該盡可能早的查找和修改Bug。在修改費用變的過高之前,單元測試是一個在早期抓住Bug的機會。
  相比后階段的測試,單元測試的創建更簡單,維護更容易,并且可以更方便的進行重復。從全程的費用來考慮, 相比起那些復雜且曠日持久的集成測試,或是不穩定的軟件系統來說,單元測試所需的費用是很低的。
一些圖表
  這些圖表摘自<<實用軟件度量>>(Capers Jones,McGraw-Hill 1991),它列出了準備測試,執行測試,和修改缺陷所花費的時間(以一個功能點為基準),這些數據顯示單元測試的成本效率大約是集成測試的兩倍 系統測試的三倍(參見條形圖)。
  screen.width-461) window.open('/ddimg/uploadimg/20060111/0951250.jpg');" src="http://www.anti-gravitydesign.com/web/attachments/2007/05/8_200705051852591.jpg" onload="if(this.width>screen.width-460)this.width=screen.width-460" border=0>
  (術語域測試(Field test)意思是在軟件投入使用以后,針對某個領域所作的所有測試活動)
  這個圖表并不表示開發人員不應該進行后階段的測試活動,這次測試活動仍然是必須的。它的真正意思是盡可能早的排除盡可能多的Bug可以減少后階段測試的費用。
  其他的一些圖表顯示高達50%的維護工作量被花在那些總是會有的Bug的修改上面。如果這些Bug在開發階段被排除掉的話,這些工作量就可以節省下來。當考慮到軟件維護費用可能會比最初的開發費用高出數倍的時候,這種潛在的對50%軟件維護費用的節省將對整個軟件生命周期費用產生重大的影響。
結論
  經驗表明一個盡責的單元測試方法將會在軟件開發的某個階段發現很多的Bug,并且修改它們的成本也很低。在軟件開發的后期階段,Bug的發現并修改將會變得更加困難,并要消耗大量的時間和開發費用。無論什么時候作出修改都要進行完整的回歸測試,在生命周期中盡早地對軟件產品進行測試將使效率和質量得到最好的保證。 在提供了經過測試的單元的情況下,系統集成過程將會大大地簡化。開發人員可以將精力集中在單元之間的交互作用和全局的功能實現上,而不是陷入充滿很多Bug的單元之中不能自拔。
  使測試工作的效力發揮到最大化的關鍵在于選擇正確的測試策略,這其中包含了完全的單元測試的概念,以及對測試過程的良好的管理,還有適當地使用象AdaTEST和Cantata這樣的工具來支持測試過程。這些活動可以產生這樣的結果:在花費更低的開發費用的情況下得到更穩定的軟件。更進一步的好處是簡化了維護過程并降低了生命周期的費用。有效的單元測試是推行全局質量文化的一部分,而這種質量文化將會為軟件開發者帶來無限的商機。

原文轉自:http://www.anti-gravitydesign.com

国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97