要減少軟體中的錯誤數目,方法之一就是擁有乙個專業的測試組,其工作就是盡一切可能使軟體崩潰。不幸的是,如果擁有測試組,那麼即使是經驗豐富的開發人員,也會傾向於花費較少的時間來保證**的可靠性。
軟體界有一句俗語:「開發人員不應該測試他們自己的**」。這是因為開發人員對自己的**瞭如指掌,他們很清楚如何採用適當的方法對**進行測試。儘管這句俗語很有道理,但卻忽略了非常重要的一點 - 如果開發人員不對自己的**進行測試,又如何知道**能否按照預期的方式執行?
簡單說來,他們根本無從得知。開發人員編寫那種執行不正常或只在某些情況下執行正常的**是乙個嚴重的問題。他們通常只測試**能否在很少的情況下正常執行,而不是驗證**能夠在所有情況下均正常執行。
發現軟體錯誤的情況有很多:
由首次編寫**的開發人員發現。
由嘗試執行**的開發人員發現。
由組中的其他開發人員或測試人員發現。
作為產品大規模測試的一部分。
由終端使用者發現。
如果在第一種情況下發現軟體錯誤,則修復錯誤比較容易,成本也很低。情況越靠後,修復軟體錯誤的成本就越高;修復乙個由終端使用者發現的軟體錯誤可能要耗費 100 或 1000 倍的成本。更不用說使用者通常因為軟體錯誤導致工作無法繼續,而一直等到下乙個版本才能解決問題。
如果開發人員能夠在編寫**期間發現所有的軟體錯誤,那就再好不過了。為此,您必須編寫能在編寫**時執行的測試。
測試是軟體開發的重要環節之一。按照軟體開發的過程測試可分為:單元測試、功能測試、效能測試、效能測試、整合測試、系統測試、域測試(field test)等。我們這裡將主要研究的是面向程式設計師的單元測試。
什麼是單元測試
單元測試是開發者編寫的一小段**,用於檢驗被測**中的乙個很明確的功能是否正確。通常而言,乙個單元測試是用於判斷某個特定條件(或者場景)下某個特定函式的行為。例如,你可能把乙個很大的值放入乙個有序list 中去,然後確認該值出現在list 的尾部。或者,你可能會從字串中刪除匹配某種模式的字元,然後確認字串確實不再包含這些字元了。
單元測試是由程式設計師自己來完成,最終受益的也是程式設計師自己。可以這麼說,程式設計師有責任編寫功能**,同時也就有責任為自己的**編寫單元測試。執行單元測試,就是為了證明這段**的行為和我們期望的一致。
為什麼要使用單元測試
我們編寫**時,一定會反覆除錯保證它能夠編譯通過。如果是編譯沒有通過的**,沒有任何人會願意交付給自己的客戶。但**通過編譯,只是說明了它的語法正確;我們卻無法保證它的語義也一定正確,沒有任何人可以輕易承諾這段**的行為一定是正確的。
幸運,單元測試會為我們的承諾做保證。編寫單元測試就是用來驗證這段**的行為是否與我們期望的一致。有了單元測試,我們可以自信的交付自己的**,而沒有任何的後顧之憂。
單元測試有下面的這些優點:
1、它是一種驗證行為。
程式中的每一項功能都是測試來驗證它的正確性。它為以後的開發提供支緩。就算是開發後期,我們也可以輕鬆的增加功能或更改程式結構,而不用擔心這個過程中會破壞重要的東西。而且它為**的重構提供了保障。這樣,我們就可以更自由的對程式進行改進。
2、它是一種設計行為。
編寫單元測試將使我們從呼叫者觀察、思考。特別是先寫測試(test-first),迫使我們把程式設計成易於呼叫和可測試的,即迫使我們解除軟體中的耦合。
3、它是一種編寫文件的行為。
單元測試是一種無價的文件,它是展示函式或類如何使用的最佳文件。這份文件是可編譯、可執行的,並且它保持最新,永遠與**同步。
4、它具有回歸性。
自動化的單元測試避免了**出現回歸,編寫完成之後,可以隨時隨地的快速執行測試。
單元測試的範疇
如果要給單元測試定義乙個明確的範疇,指出哪些功能是屬於單元測試,這似乎很難。但下面討論的四個問題,基本上可以說明單元測試的範疇,單元測試所要做的工作。
1、 它的行為和我期望的一致嗎?
這是單元測試最根本的目的,我們就是用單元測試的**來證明它所做的就是我們所期望的。
2、 它的行為一直和我期望的一致嗎?
編寫單元測試,如果只測試**的一條正確路徑,讓它正確走一遍,並不算是真正的完成。軟體開發是乙個項複雜的工程,在測試某段**的行為是否和你的期望一致時,你需要確認:在任何情況下,這段**是否都和你的期望一致;譬如引數很可疑、硬碟沒有剩餘空間、緩衝區溢位、網路掉線的時候。
3、 我可以依賴單元測試嗎?
不能依賴的**是沒有多大用處的。既然單元測試是用來保證**的正確性,那麼單元測試也一定要值得依賴。
4、 單元測試說明我的意圖了嗎?
單元測試能夠幫我們充分了解**的用法,從效果上而言,單元測試就像是能執行的文件,說明了在你用各種條件呼叫**時,你所能期望這段**完成的功能。
不寫測試的藉口
到這裡,我們已經知道了使用單元測試的種種理由。但目前的實際情況是大多數程式設計師不進行單元測試,或只進行簡單的單元測試。下面是一些他們常用的介面:
1、 編寫單元測試太花時間了。
我們知道,在開發時越早發現bug
1)、對於所編寫的**,你在除錯上面花了多少時間。
2)、對於以前你自認為正確的**,而實際上這些**卻存在重大的bug
,你花了多少時間在重新確認這些**上面。
3)、對於乙個別人報告的bug,你花了多少時間才找出導致這個bug 的原始碼位置。
回答完這些問題,你一定不再以「太花時間」作為拒絕單元測試的藉口。
2、 執行測試的時間太長了。
合適的測試是不會讓這種情況發生的。實際上,大多數測試的執行都是非常快的,因此你在幾秒之內就可以執行成千上萬個測試。但是有時某些測試會花費很長的時間。這時,需要把這些耗時的測試和其他測試分開。通常可以每天執行這種測試一次,或者幾天一次。
3、 測試**並不是我的工作。
你的工作就是保證**能夠正確的完成你的行為,恰恰相反,測試**正是你不可缺少的工作。
4、 我並不清楚**的行為,所以也就無從測試。
如果你實在不清楚**的行為,那麼估計現在並不是編碼的時候。如果你並不知道**的行為,那麼你又如何知道你編寫的**是正確的呢?
5、 但是這些**都能夠編譯通過。
我們前面已經說過,**通過編譯只是驗證它的語法通過。但並不能保證它的行為就一定正確。
6、 公司請我來是為了寫**,而不是寫測試。
公司付給你薪水是為了讓你編寫產品**,而單元測試大體上是乙個工具,是乙個和編輯器、開發環境、編譯器等處於同一位置的工具。
7、 如果我讓測試員
或者qa(quality assurance)人員沒有工作,那麼我會覺得很內疚。
你並不需要擔心這些。請記住,我們在此只是談論單元測試,而它只是一種針對原始碼的、低層次的,為程式設計師而設計的測試。在整個專案中,還有其他的很多測試需要這些人來完成,如:功能測試、驗收測試、效能測試
、環境測試、有效性測試、正確性測試、正規分析等等。
8、 我的公司並不會讓我在真實系統中執行單元測試。
我們所討論的只是針對開發者的單元測試。也就是說,如果你可以在其他的環境下(例如在正式的產品系統中)執行這些測試的話,那麼它們就不再是單元測試,而是其他型別的測試了。實際上,你可以在你的本機執行單元測試,使用你自己的資料庫
。總而言之,單元測試會讓我們的開發工作變得更加輕鬆,讓我們對自己的**更加自信。無論是大型專案還是小型專案,無論是時間緊迫的專案還是時間寬裕的專案,只要**不是一次寫完永不改動,編寫單元測試就一定超值,它已成為我們編碼不可缺少的一部分。
單元測試的一些基本概念
我們 程式設計師 多多少少都寫過單元測試,有的可能幾年前寫的幾行 比如我 姑且也算寫過吧,但是有些東西還是不是很清楚,比如什麼是單元測試?怎麼才算是好的單元測試?等等很多,查了些資料,總結一下。1 什麼是單元測試 單元測試是一段 通常是乙個方法 呼叫另外一段 隨後檢驗一些假設的正確性。如果假設的結果...
單元測試的編寫 測試的基本概念(1)
測試的分類 黑盒測試 功能測試,主要驗證功能是否ok 白盒測試 了解 的具體邏輯 單元測試 以最小的單元來實現測試功能,針對小的單元 乙個元件 乙個方法 乙個模組 進行測試。整合測試 放到一起進行測試。常見的測試框架 karma可以把測試跑在真正的瀏覽器上,可以測試ui元件 mocha 提供了乙個測...
單元測試 基礎概念
我們都寫過的某種測試 不要驚訝,你已經進行過某種程度的單元測試。你見過提交 前不做測試的開發人員嗎?在傳統測試中,開發人員使用乙個圖形使用者介面觸發要測試的類的某個行為,然後檢驗結果。那什麼是單元測試,什麼不是單元測試呢?往往說不想的,其實是因為還不會。因為不會,所以想一想就很麻煩,還不如手工測試呢...