軟件測試實施

軟件測試自動化的一些具體做法

       作者在上篇文章略微談到了軟件測試的自動化,但並沒有把本文的內容也一起寫進去。原因主要是希望讀者先努力考慮在自己的企業或項目內,可以有一些怎麼樣的做法,而不會先入爲主地受到我所寫的具體例子的影響而侷限了思路。

   因爲軟件測試的工作量很大(40% 到60% 的總開發時間),而又有很大部分適於自動化,因此,測試的改進會對整個開發工作的質量、成本和週期帶來非常顯著的效果。

   首先,談談在測試自動化的情況下,帶有圖形界面的產品的測試用例的設計問題。因爲圖形界面的輸出顯示不是很容易做到測試結果自動化比較,所以一般的做法是把圖形界面輸出的部分單獨建立測試用例,以手工運行。而所有非圖形輸出則可進行自動測試。

   下面舉出一些測試自動化的例子:

   1.測試個案(test case ,或稱爲測試用例)的生成:

   用編程語言或更方便的劇本語言(script language 例如Perl等)寫出短小的程序來產生大量的測試輸入(包括輸入數據與操作指令)。或同時也按一定的邏輯規律產生標準輸出。輸入與輸出的文件名字按規定進行配對,以便控制自動化測試及結果核對的程序易於操作。

   這裏提到測試個案的命名問題,如果在項目的文檔設計中作統一規劃的話,軟件產品的需求與功能的命名就應該成爲後繼開發過程的中間產品的命名分類依據。這樣,就會爲文檔管理和配置管理帶來很大的方便,使整個產品的開發過程變得更有條理,更符合邏輯。任何新手半途加入到開發工作中也會更容易進入狀態。

   2.測試的執行寫控制:

   單元測試或集成測試可能多用單機運行。但對於系統測試或迴歸測試,就極有可能需要多臺機在網絡上同時運行。記住一個這樣的原則,在開發過程中的任何時候,如果你需要等候測試的運行結果的話,那就是一個縮短開發時間的機會。

   對於單個的測試運行,挖潛的機會在測試的設置及開始運行和結果的對比及顯示。有時候,需要反覆修改程序,重新彙編和重新測試。這樣,每一個循環的各種手工鍵入的設置與指令所花費的時間,加起來就非常可觀。如果能利用make或類似的軟件工具來幫助,就能節省大量的時間。

   對於系統測試或迴歸測試這類涉及大量測試個案運行的情況,挖潛的的機會除了利用軟件工具來實現自動化之外,就是怎樣充分利用一切硬件資源。往往,就算是在白天的工作時間內,每臺計算機的負荷都沒有被充分利用。能夠把大量測試個案分配到各臺機器上去同時運行,就能節省大量的時間。另外,把大量的系統測試及迴歸測試安排到夜間及週末運行,更能提高效率。

   如果不購買商品化的工具的話,應當遵從正規的軟件開發要求來開發出好的軟件測試自動化工具。在實踐中,許多企業自行開發的自動化工具都是利用一些現成的軟件工具再加上自己寫的程序而組成的。這些自己開發的工具完全是爲本企業量身定做的,因此可用性非常強。同時,也能根據需要隨時進行改進,而不必受制於人。當然,這就要求有一定的人力的投入。

   在設計軟件自動測試工具的時候,路徑(path)控制是一個非常重要的功能。理想的使用情況是:這個工具可以在任何一個路徑位置上運行,可以到任何路徑位置去取得測試用例,同時也可以把測試的結果輸出放到任何的路徑位置上去。這樣的設計,可以使不同的測試運行能夠使用同一組測試用例而不至於互相干擾,也可以靈活使用硬盤的空間,並且使備份保存工作易於控制。

   同時,軟件自動測試工具必須能夠有辦法方便地選擇測試用例庫中的全部或部分來運行,也必須能夠自由地選擇被測試的產品或中間產品採作爲測試對象。

   3.測試結果與標準輸出的對比:

   在設計測試用例的時候,必須考慮到怎樣才能夠易於對此測試結果和標準輸出。輸出數據量的多少及數據格式對比較的速度有直接影響。而另一方面,也必須考慮到輸出數據與測試用例的測試目標的邏輯對應性及易讀性,這將會大大有利於分析測試所發現的不吻合,也有利於測試用例的維護。

   許多時候,要寫一些特殊的軟件來執行測試結果與標準輸出的對比工作,因爲可能有部分的輸出內容是不能直接對比的(比如,對運行的日期時間的記錄,對運行的路徑的記錄,以及測試對象的版本數據等),就要用程序進行處理。

   4.不吻合的測試結果的分析、分類、記錄和通報:

   上一點所談到的,用於對測試結果與標準輸出進行對比的特殊軟件,往往也同時擔任對不吻合的測試結果進行分析、分類、記錄和通報的任務。

   “分析”是找出不吻合的地方並指出錯誤的可能起因。“分類”包括各種統計上的分項,例如,對應的源程序的位置,錯誤的嚴重級別(提示、警告、非失效性錯誤、失效性錯誤;或別的分類方法),新發現的還是已有記錄的錯誤,等等。“記錄”,是按分類存檔。“通報”,是主動地對測試的運行者及測試用例的“負責人”通報出錯的信息。

   這裏提到測試用例的“負責人”的概念。是用以指定一個測試用例運行時發現的缺陷,由哪一個開發人員負責分析(有時是另外的開發人員引進的缺陷而導致的錯誤)及修復。在設立測試用例庫時,各用例均應有指定的負責人。

   最直接的通報方法是由自動測試軟件發出電子郵件給測試運行者及測試用例負責人。郵件內容的詳細程度可根據需要靈活決定。

   5.總測試狀況的統計,報表的產生:

   這些都是自動測試工具所應有的功能。目的是提高過程管理的質量,同時節省用於產生統計數據的時間。

   產生出來的統計報表,最好是存放到一個約定的路徑位置,以便任何有關人員都知道怎樣查閱。同時,可按需要用電子郵件向適當的對象(如項目經理,測試經理和質量保證經理)寄出統計報表。

   6.自動測試與開發中產品每日構建(build )的配合:

   自動測試應該是整個開發過程中的一個有機部分。自動測試要依靠配置管理來提供良好的運行的環境,同時它必須要與開發中的軟件的構建緊密配合。

   在開發中的產品達到一定程度的時候,就應該開始進行每日構建和測試。這種做法能使軟件的開發狀態得到頻繁的更新,以及及早發現設計和集成的缺陷。

   爲了充分利用時間與設備資源,下班之後進行自動的軟件構建,緊接着進行自動測試(這裏多數指的是系統測試或迴歸測試),是一個非常行之有效的方法。如果安排得好,到第二天上班時,測試結果就已經在各人的電子郵箱裏面面了,等待着新的一天的開發工作。

   總結:以上只是根據經驗和體會舉了一些軟件測試自動化的做法。

   由於企業開發環境的不同、產品的不同,測試自動化的實施方法會有很大的差異。希望大家從這些具體例子中掌握到這項工作的基本精神及思路,然後結合自己的情況,大膽創新。同時千萬不要忘記向大家介紹好經驗。祝大家測試愉快

posted @ 2004-07-07 00:36 NetBee 閱讀(93) | 評論 (0)編輯 收藏

測試、測試、測試

--軟件測試的理論和實踐

 

 

題記:測試是交付成功的優質的產品的保證

 

我們每個人,不會都是軟件測試人員,但都是某些軟件的用戶。缺省或默認情況下,用戶都會覺得買到的軟件是沒有問題的,一般不會去想這樣的軟件可能會有問題,用戶只要使用這些軟件來解決他們需要解決的問題就可以了。當他們發現問題的時候,甚至會感到震驚。存在的問題很多都和測試的成效有關係,一般的軟件產品存在的問題確實比較少,但我覺得即使是以前買的正版的金山快譯2000都有着一些顯而易見的bug。如果測試不充分,那麼這些問題會潛伏在軟件中,等到用戶發現以後,再有開發人員進行維護,改正錯誤的費用一般是開發階段的40倍到60倍。

人們對測試存在着一些誤區,例如:
1 測試是想象到可能出現的問題,然後試圖驗證這些問題。
實際上能想象到的只是一部分的情況,隨意性太大,還要取決於開發人員的經驗,對業務的熟悉程度和他想象到的程度。
2 讓時間有富裕的員工去做一些測試
表面上看這體現了管理的效率和靈活性,但實際上也體現了管理者對測試的輕視。測試和測試的人有很大關係。測試工作人員應該是勤奮並富有耐心,善於學習、思考和發現問題,細心有條理,總結問題,如果具備這樣的優點,做其它工作同樣也會很出色,因此這裏還有一個要求,就是要喜歡測試這項工作。如果他是專職的,那麼肯定更有經驗和信心。國內的小夥子好象都喜歡做程序員,兩者工作性質不同,待遇不同,地位不同,對自我實現的價值的認識也不同,這是行業的一個需要改善的問題。如果只是爲了完成任務而完成任務,或者發現了幾個問題就覺得滿意了,這在任何其它工作中都是不行的。
3 測試是相對簡單的工作。
實際上並非如此,要真正做好一件事都不容易。測試也有很多相關技術和工具。而對測試的輕視問題,也許要通過痛苦的經歷和結果纔可能確切體會到。很多專家都在對測試的理論進行深入的探討和研究。

測試的基本知識

讓我們一起快速過一遍:

什麼是軟件測試:在軟件投入運行前,對軟件需求分析、設計規格說明和編碼的最終複審,是軟件質量保證的關鍵步驟。
測試的目標:以較少的用例、時間和人力找出軟件中潛在的各種錯誤和缺陷,以確保系統的質量。
從測試的類型來看,測試分爲2種:黑盒測試和白盒測試。
黑盒測試又稱爲功能測試或數據驅動測試,把系統看成一個黑盒子,不考慮程序的內在邏輯,只根據需求規格說明書的要求來檢查程序的功能是否符合它的功能說明。
白盒測試又稱爲結構測試和邏輯驅動測試,允許測試人員對程序內部邏輯結構及有關信息來設計和選擇測試用例,對程序的邏輯路徑進行測試。
測試用例由測試輸入數據以及與之對應的輸出結果組成。測試用例設計的好壞直接決定了測試的效果和結果。
從測試實際的前後過程來看,軟件測試上是由一系列的不同測試所組成,這些軟件測試的步驟分爲:單元測試、組裝測試(集成測試)、確認測試和系統測試。軟件開發的過程是自頂向下的,測試則正好相反,以上這些過程就是自底向上,逐步集成的。

單元測試(模塊測試):針對每個模塊進行的測試,可從程序的內部結構出發設計測試用例,多個模塊可以平行地對立地測試。通常在編碼階段進行,必要的時候要製作驅動模塊和樁模塊。
集成測試:在單元測試的基礎上,將所有模塊按照設計要求組裝成爲系統,必須精心計劃,應提交集成測試計劃、集成測試規格說明和集成測試分析報告。
確認測試:驗證軟件的功能和性能及其它特性是否與用戶的要求一致。
系統測試:將軟件放在整個計算機環境下,包括軟硬件平臺、某些支持軟件、數據和人員等,在實際運行環境下進行一系列的測試。

測試工作的文檔主要有:測試計劃、測試模型和用例設計或規格說明、測試分析報告等。從軟件工程上說,這是屬於軟件配置的一部分。(我不知道,如果什麼報告都沒有,只是不斷地擺弄執行程序,看到錯誤和問題就記下來,算不算真正的測試?)

測試需要一定的技術和工具

在用例設計過程中,可以考慮到很多方面,並且也有很多的指導方法和技術。

黑盒測試用例設計包括:

等價類劃分:劃分等價類--確立測試用例--設計用例
邊界值分析:通過分析,考慮如何確立邊界情況
錯誤推測法:靠經驗和直覺來推測程序中可能存在的各種錯誤,從而有針對性地編寫用例。可以列舉出可能的錯誤和可能發生錯誤的地方,然後選擇用例。
因果圖:通過畫因果圖,在圖上標明約束和限制,轉換成判定表,然後設計測試用例。這適合於檢查程序輸入條件的各種組合情況。

功能圖FD:通過形式化地表示程序的功能說明,並機械地生成功能圖的測試用例。

白盒測試用例設計包括:

1 邏輯覆蓋,以程序內在邏輯結構爲基礎的測試,包括以下5種類型:

1.1 語句覆蓋:每一條可執行語句至少覆蓋一次;
1.2 判定覆蓋(分支覆蓋):設計若干個測試用例,運行所測程序,使程序中每個判斷的取真分支和取假分支至少執行一次;
1.3 條件覆蓋:設計足夠多的測試用例,運行所測程序,使程序中每個判斷的每個條件的每個可能取值至少執行一次;
1.4 判定-條件覆蓋:設計足夠多的測試用例,運行所測程序,使程序中每個判斷的每個條件的所有可能取值至少執行一次,並且每個可能的判斷結果也至少執行一次;
1.5 條件組合測試:設計足夠多的測試用例,運行所測程序,使程序中每個判斷的所有可能的條件取值至少執行一次;
1.6 路徑測試:設計足夠多的測試用例,運行所測程序,要覆蓋程序中所有可能的路徑。

2 基本路徑測試

在程序控制流圖的基礎上,通過分析控制構造的環路複雜性,導出基本可執行路徑集合,從而設計測試用例。包括以下5個方面:
2.1 程序的控制流圖:描述程序控制流的一種圖示方法。
2.2 程序環境複雜性:McCabe複雜性度量。從程序的環路複雜性可導出程序基本路徑集合中的獨立路徑條數,這是確定程序中每個可執行語句至少執行依次所必須的測試用例數目的上界。
2.3 導出測試用例
2.4 準備測試用例,確保基本路徑集中的每一條路徑的執行
2.5 圖形矩陣:是在基本路徑測試中起輔助作用的軟件工具,利用它可以實現自動地確定一個基本路徑集。

程序的靜態分析方法

1 生成各種引用表、靜態錯誤分析

2 人工測試:桌前檢查、代碼評審等

3 軟件測試工具:包括靜態分析工具、動態測試工具、測試數據自動化生成工具、模塊測試臺、測試合成環境

3.1 靜態分析工具:語言程序的預處理器、數據庫工具、錯誤分析器和報告生成器。直接掃描所測試的正文,對程序的數據流和控制流進行分析,然後送出測試報告。

3.2 動態測試工具:通過選擇適當的測試用例,實際運行所測程序,比較實際運行結果和預期結果,發現錯誤。

3.3 測試數據自動化生成工具:包括路徑測試數據生成程序、隨機測試數據生成程序以及根據數據規格說明生成測試數據

3.4 模塊測試臺是一種專門的測試用例描述語言,負責將輸入數據傳送到所測試模塊中,然後將實際輸出結果與在描述測試用例的語言中所表述的期望結果進行比較,發現錯誤。另外,也包括其它的功能:語句跟蹤、動態斷句、覆蓋度量、用戶自定義符號表、內容表和輸出格式。

3.5 測試合成環境:包括環境模擬程序,代碼檢查程序,測試文檔生成程序,測試執行嚴整程序,輸出比較程序,程序正確性證明程序等,以及各種調試工具。而且還有集成系統,集成了多種工具,如SADAT、Microsoft Test for Windows和PureArtria等。

 

***********************************************************

 

測試的管理

作爲項目或產品開發的一個必要的組成部分,需要良好的組織和管理。使用軟件質量規範,編寫和實現測試用例和模型,可以有效地組織測試。

一般的測試工作過程也可以是:計劃-->配置(必要的軟硬件資源下)-->開發(構造或配置測試工具、創建測試套件和測試方案庫、準備適當的報告工具並記錄測試系統如何運轉)-->測試執行(進行測試、記錄測試條件和問題,報告結果)。

測試管理也可以從測試經理和測試小組2個方面去看:

測試經理要管理好團隊,很多人認爲測試是枯燥乏味的事情,而且似乎低級的事情,所以測試經理應該不斷地激勵小組成員,爲他們爭取利益。在時間進度上保證穩步前進。就象賽跑,一開始就加班加點,只會導致極限的過早到來。
作爲測試經理,應該有足夠的質量意識。評價質量風險的方法是“失敗模式和效果分析”(Failure Mode  and Effect Analysis, FMEA)。這種方法可以允許您在特定的質量風險和結果上映射需求、規範,以及項目小組假設。然後,按照風險級別進行分類,並按序排列。
實際上如果能得到充分的資源已是很困難的了,能用好臨時的測試人員也已經不錯了。一般企業的主管和技術經理都並不怎麼真正重視測試工作的意義和價值。也許他們認爲臨時的投入一次性的強力測試足以發現絕大部分問題,而實際上這對產品的長遠發展,以及質量改進都沒有太大好處。

測試過程中軟件功能可能進行調整和變化,測試發現問題也會導致變化,需要重新的測試。對這些變更也需要進行管理。
另外,由於上層管理部門的不重視,必須想辦法與之進行清楚而有效的溝通;同開發部門的溝通也非常重要,因爲開發和測試在性質上是有些對立的,很容易在相互之間產生一些不必要的矛盾。和開發部門不同的是,一般質量或測試部門和市場或銷售部門的立場倒是比較一致的,如果雙方都認爲高質量的產品是市場戰略中重要的品牌戰略,徹底的測試對於達到這樣的目標來說意義重大。因此,有必要和市場部門保持協作和交流。

測試經理可以經常問自己一些問題:

計劃做哪些測試?實際完成了哪些測試?使用了多少用例?其中多少沒有通過?管理部門是否有足夠的支持?他們是否向你要過測試報告?開發部門的聯絡是否及時?等等。如果你是測試管理人員,應該可以想到更多的問題。

測試小組:

測試小組有多大的規模,一般取決於項目規模、測試人員與開發人員的比例、項目經理對質量保證的認識和期望等,也取決於你的準確的測試計劃。
對一些項目來說,最好是在開始階段就有測試人員有所介入。

如本文一開始所提到的,在測試小組中測試人員必須具備的素質包括:有效的坦率真誠的交流的能力、清晰簡明的表達能力、一定的好奇心(但不至於太強,以至於花太多精力去探究一個微小的問題),不應害怕提出尖銳問題引起麻煩,一定的責任心,
注意力能夠高度集中,是職業悲觀主義者(但不是抱怨和憎惡)。

以下是一些測試的方法和基本工具:

測試方案、測試模型和測試用例
測試就象是做實驗一樣,實驗對於象我這樣的理工科畢業生來說真是太熟悉不過了。做實驗之前必然有實驗的方案、內容和步驟,測試似乎也是同樣的。另外,基於測試用例的測試和常見的隨機性的測來測去也是完全不同的,儘管習慣於隨機性測試的人,如果注意力集中的話,他的頭腦裏也是有一些測試用例的。

關於測試實驗室,進行測試工作首先要爭取到儘可能好的環境。如果可能,應該建立測試實驗室,實驗室包括必要的裝備、工具軟件(包括測試工具)和各種操作系統平臺,保持實驗室的實用、整潔,避免他人干擾甚至破壞測試環境。

關於測試跟蹤軟件,製作一個簡單的測試問題跟蹤軟件,記錄測試的結果,將測試發現的問題分類,並對測試發現的問題和模塊、開發人員進行關聯,有助於分析問題,並可有效記錄測試的結果,形成測試報告,並從中找出一些規律性的東西來。因此測試問題跟蹤軟件還是有一定的價值的。

關於測試自動化,有一定的風險。對一個穩定的系統,甚至可以自己開發自動化軟件,而對於正處於快速變形中的軟件開發過程,接口、主要功能和支持環境在發展變化中。爲測試配置環境也要付出很多的時間。

以下是關於測試的一些技巧和經驗:

在制定測試計劃的時候,就要考慮到測試的風險,並抉擇要執行哪些測試,並放棄哪些測試;測試計劃的評審應該讓開發人員參與;
測試模型的製作應該儘可能貼近用戶,或者站在用戶的使用立場上來觀測軟件,此時應該能發現更多的問題。

由於測試發現問題,在解決問題後還要重新測試,因此測試的時間可能會比實際更長一些

識別和注意少數重要的方面,而忽略多數次要的方面,有時候少數的問題足以致命,這些問題將是軟件測試結果中重要性最高的錯誤。

錯誤的定位有時是很難的,要找出必然發生的前因後果,而不至於因爲描述錯誤而誤導開發人員。有時候確實存在錯誤不能重建的問題。解決辦法之一是在錯誤報告中給予說明。

對錯誤的描述,應該是準確、完整而簡練。因爲描述的問題或者不完整的描述會引起開發人員的誤解,其後果是可以想見的。

有時有經驗的測試人員憑藉直覺就可以發現一些問題,這可稱爲“錯誤猜測”。

測試人員容易犯2種錯誤:一是測試人員發生判斷錯誤,將本沒有錯誤的系統行爲報告爲錯誤,或者將錯誤指定了過高的嚴重級別,或者過高估計了問題的嚴重性,這樣會引起開發人員的不信任,產生一種象“狼來了”一樣的效果;二是測試人員將錯誤的嚴重性或優先級定得過低,從而產生“測試逃逸”,這樣會造成產品質量的風險。以上兩種錯誤應該儘量避免。

 

最後,我忽然想,測試實際上可以覆蓋到硬件,甚至非計算機產品的測試,也許可以相互借鑑。

還有一種很奇特的感想,這種感想使我反而有些困惑不清了。我發現對測試來說,理論和實踐的距離好象非常遙遠,我先看了一本軟件工程的書,然後寫下了前面的一半內容,然後我又匆匆翻看了一本美國人的書,叫做《測試流程管理》,然後整理出了本文後一半的內容,該書中有着比本文多得多的各方面的實踐經驗。歌德說過,理論是蒼白的,生命之樹常青。我稍稍改變一下,就變成了:理論是蒼白的,實踐之樹常青。也許測試是一種實踐性很強的工作,大學教授們一般也不可能熱衷於參加測試工作吧。

posted @ 2004-07-07 00:35 NetBee 閱讀(93) | 評論 (0)編輯 收藏

測試是一件有趣的事情?真的嗎?

測試。討厭!我一直討厭做測試。測試(單元測試和功能測試)是防礙“真正”工作的事情。每個人都確信自己的代碼是完美的,不是嗎?在確實需要更改代碼的極少數事件中,註釋編寫得如此之好,以致每個人都能領會其中的含義。我需要提高(或許還需要作一些諮詢)。

在過去的幾年裏,單元測試已成爲我編寫軟件的核心環節,多虧了一種稱爲極限編程 (XP) 的簡便編程方法(請參閱參考資源)。這種方法要求我爲添加的每個函數編寫單元測試,並且要維護這些測試。如果單元測試失敗,我就無法整合任何代碼。隨着代碼庫的不斷增大,這些測試將使開發人員能夠很有把握地完成更改。

起初,我認爲有了單元測試,就沒必要再進行功能測試。噢,又錯了。功能測試與單元測試相差甚遠。我花了很長一段時間理解二者的區別,以及如何結合使用兩者來改進開發過程。

本文探究單元測試與功能測試之間的區別。並概述了在日常開發中使用這兩種測試的方法。

測試與開發過程
測試對於開發人員極爲重要,您必須在開發過程中不斷進行測試。測試不應該只屬於開發週期的某個特定階段。它絕不應該是您將系統交給客戶前要完成的最後一項任務。如何才能知道您何時就完成了所有任務呢?如何才能知道對一個小錯誤的修正是否破壞了系統的主要功能呢?目前想像中的系統如何才能演化爲實實在在的系統呢?單元測試和功能測試都應該是開發過程中不可分割的一部分。

單元測試應成爲您編寫代碼的核心環節,當您所做的項目時限很緊並且您希望控制開發進度時尤其如此。由於單元測試是如此重要,所以您應該先編寫測試,再編寫代碼。

一套適當的單元測試具有以下功能:

  • 說明可能的最實用設計
  • 提供類文檔的最佳格式
  • 確定一個類何時完成
  • 增強開發人員對代碼的信心
  • 作爲快速重構的基礎

 

單元測試創建隨系統自然發展的設計文檔。再讀一遍上一句話。文檔隨系統自然發展,這是軟件開發的“聖盃”。有什麼方法比通過提供一個用例編碼集來記錄一個類效果更好呢?那就是單元測試:一系列記錄類所做工作的用例代碼,提供輸出控制。這樣,由於單元測試必須通過,所以設計文檔總是最新的。

您應該首先編寫測試,然後再編寫代碼。這樣就爲要測試的類提供了一種設計,這種設計使您每一時刻都只需集中考慮一小塊代碼。這種做法也使設計變得不再複雜。您沒有試圖爲以後着想而實現一些不必要的功能。先編寫測試還使您知道該類何時完成。一旦通過所有測試,任務也就完成了。

最後,單元測試可使您高度自信,這又會轉化爲開發人員的滿意度。如果只要更改代碼即運行單元測試,您立即就能發現您所做的更改是否對系統造成了破壞。

功能測試比單元測試更重要,因爲功能測試將驗證系統是否可以發行了。功能測試以一種有用的方式對您的工作系統進行說明。一套適當的功能測試具有以下功能:

  • 以有效方式捕獲用戶需求
  • 增強小組(用戶和開發人員)在系統滿足用戶需求方面的信心

 

功能測試以有效方式捕獲用戶需求。傳統開發通過用例來捕獲需求。通常,人們討論用例並花很長時間對它們進行細化。他們最後所得到的只是一紙空文。功能測試就像自驗證式用例。極限編程方法可解釋這一概念。XP Stories 將成爲未來用戶與開發人員進行溝通的協議。功能測試便是這種溝通的結果。未經功能測試的 Stories 不可能很完善。

功能測試填補單元測試留下的空白,並可增強小組對代碼的信心。單元測試漏掉許多錯誤。儘管它可以提供您所需的全部代碼,但它可能無法提供您所需的全部系統功能。功能測試將暴露單元測試遺漏的問題。一套適當的自動化功能測試也不可能捕捉到每個錯誤,但是它能比最好的單一單元測試捕捉更多的錯誤。

單元測試與功能測試
單元測試向開發人員表明代碼正確執行操作;而功能測試向開發人員表明代碼執行正確的操作

單元測試
單元測試是從程序員的角度編寫的。它確保類的某個特定方法成功執行一系列特定的任務。每個測試都確保只要給定輸入,方法將輸出預期的結果。

如果沒有測試框架,編寫一套可維護的自動化單元測試幾乎是不可能的。在開始編寫測試之前,請選擇一個小組公認的框架。您將經常性地使用這個框架,因此您最好對它有點好感。極限編程網站提供了幾個單元測試框架(請參閱參考資源)。我最熟悉的框架是 JUnit,它專門用來測試 wuhuif 代碼。

功能測試
功能測試是從用戶的角度編寫的。這種測試確保系統執行用戶期望它執行的工作。

很多時候,系統開發好比建築房屋。儘管這種類比不很恰當,但爲了理解單元測試與功能測試的區別,我們可以擴充這種類比。單元測試好比房屋建築現場的建築監理員。他關心房屋的各個內部系統,如地基、構架、供電系統和管道設備等。他確保(測試)房屋每一部分的工作都安全、正常,即符合建築說明。這種情況下,功能測試類似於視察同一建築現場的房主。他假定內部系統將正常運作,並假定建築監理員在執行其任務。房主關心的是住在這所房子裏將會怎樣。他關心房子的外觀如何,各個房間的大小是否合適,房子能否滿足家庭的需要,以及窗戶的位置是否有利於採光。房主對房子執行功能測試。他從用戶的角度考慮問題。建築監理員對房子執行單元測試。他從建築工人的角度考慮問題。

就像單元測試一樣,如果沒有測試框架,編寫一套可維護的自動化功能測試實際上是不可能的。JUnit 非常適合編寫單元測試;但是,當試圖編寫功能測試時,它就顯得力不從心了。就功能測試而言,沒有與 JUnit 相當的框架。也有幾種用於功能測試的產品,但我從來沒見過它們應用於生產環境。如果找不到滿足您的需要的框架,您就必須創建一個。

無論我們多麼擅長於構建手頭的項目,也不管我們正在創建的系統多麼靈活,如果我們的產品不合用,那我們就是白費時間。因此,功能測試是開發最重要的部分。

由於兩種測試都必不可少,您就需要了解編寫它們應遵循的原則。

如何編寫單元測試
剛開始編寫單元測試時很容易恢心。最佳的入手方式就是爲代碼創建單元測試。(儘管爲現有代碼創建單元測試比較困難,但並非無法實現)。首先從新代碼着手,待您習慣了整個過程以後,再針對現有代碼創建測試程序。

如上文所述,應該首先編寫單元測試,然後再編寫這些單元測試要測試的代碼。如何爲尚不存在的代碼編寫測試呢?問得非常好。掌握這一方法需要 90% 的思維加 10% 的技術。我的意思是,您只需假定您正在爲其編寫測試的類已經存在。接下來的任務就是編寫測試。起初會犯很多語法錯誤,但您先別管它。這一步您要做的就是定義該類要實現的接口。下一步就是運行您的單元測試,修正語法錯誤(即,編寫一個類,使它實現您的測試剛定義的接口),並再次運行測試。重複這一過程,每次僅編寫修正故障的代碼。運行測試,直到測試全部通過爲止。一旦通過全部單元測試,代碼也就完成了。

一般而言,類的每個公共方法都應有一個單元測試。但是,功能簡單的方法(例如,getter 方法和 setter 方法)不需要單元測試,除非它們以某種特別的方式進行獲取和設置。應該遵循下面這條很好的原則:即只要您認爲有必要對代碼中的某個行爲加註,就編寫一個單元測試。如果您像其他許多程序員一樣不喜歡爲代碼加註,則單元測試是記錄代碼行爲的一種方法。

將單元測試與被測試的相關類放在同一個包內。這種組織方式使每個單元測試都能訪問被測試類中帶有 packageprotected 訪問修飾符的方法和引用變量。

在單元測試中避免使用域對象。域對象是特定於某個應用程序的對象。例如,一個電子表格應用程序可能包含一個註冊對象;這個註冊對象就是一個域對象。如果您有一個已知這些域對象的類,則在測試中完全可以使用這些對象。但是如果您有一個根本不使用這些域對象的類,在測試中就不要將這些對象聯繫到該類上。應該避免這種情形完全是因爲代碼重用。爲某一項目創建的類經常要用於其他項目。重用這些類可能很簡單。但是,如果對重用類的測試中用到了另一個項目的域對象,則使測試能夠正常運行這一工作就會相當耗時。通常情況下,這個測試將被刪除或重寫。

這些機制爲您提供很好的幫助,但是如果您不運行這些測試,一套綜合的單元測試就變得一文不值。儘早運行測試通常使您在任何時候都對代碼充滿信心。您將隨着項目進展不斷添加功能。運行這些測試將會通知您剛剛實現的新功能是否對系統造成了破壞。

在您掌握了編寫單元測試的技巧之後,我們再來看看現有代碼。爲現有代碼編寫測試可能是個挑戰。不要爲測試而測試。當您發現有必要對一個未經很好測試(或者根本就沒有測試)的類進行修改時,請“隨時”編寫測試。現在是添加測試的時候了。像往常那樣,該類的單元測試應該捕獲其每個方法的功能。找出應該進行哪些測試的最容易的方法之一是:查看現有代碼中的註釋。任何註釋都應在單元測試內捕獲。將位於方法開頭、說明該方法所起作用的註釋塊翻譯爲單元測試。

如何編寫功能測試
儘管功能測試很重要,但它卻沒有受到足夠的重視。多數項目都有單獨的一個組來做功能測試。通常有一大羣人不斷地與系統交互,以確定系統是否正確工作。這種觀念和設置專門的功能測試小組的做法很不明智。

對功能測試的處理與對單元測試的處理不應該有太大的區別。只要您編寫的代碼用來產生要求用戶與之交互的組件(如對話框),就要編寫測試,但實際上編寫測試要在編寫代碼之前進行。請與用戶一起編寫獲取用戶需求的功能測試。無論何時開始一項新任務,都要在功能測試框架中描述此任務。您的開發工作將繼續向前發展,當添加新代碼時,請執行單元測試。當所有的單元測試都結束以後,運行最初的功能測試,看看它是否能夠通過,或者是否需要修改。

從理論上講,功能測試小組的概念該消失了。開發人員應與用戶共同編寫功能測試。在對系統所做的一系列功能測試結束之後,開發組中負責功能測試的成員就應該用初始測試的各種變化形式來轟擊系統。

單元測試與功能測試的界限
通常單元測試與功能測試之間並沒有明確的界限。老實說,有時我也不清楚這個界限在什麼位置。在編寫單元測試時,我根據以下原則來確定當前編寫的單元測試實際上是否是功能測試:

  • 如果單元測試跨越類邊界,則它就可能是功能測試。

  • 如果單元測試變得很複雜,則它可能是功能測試。

  • 如果單元測試很脆弱(也就是說,雖然它是一個有效測試,但它必須不斷改變以處理不同的用戶組合),則它可能是功能測試。

  • 如果編寫單元測試比編寫其所測試的代碼更難,則它可能是功能測試。

 

請注意“它可能是功能測試”這一措辭。本文無法提供硬性而快速的規則。單元測試與功能測試中之間有一個界限,但界限的具體位置要由您來確定。您用單元測試用得越熟練,某個特定測試是單元測試還是功能測試的界限就越明顯。

小結
單元測試是從開發人員的角度出發編寫的,並且關注的是所測試的類的特定方法。當編寫單元測試時,請使用以下這些原則:

  • 首先編寫單元測試,然後再編寫要測試的類代碼

  • 在單元測試中捕獲代碼註釋。

  • 測試所有執行“令人感興趣的”功能(即,不是 getter 和 setter,除非它們以某種獨特的方式執行獲取和設置操作)的公共方法。

  • 將每個測試實例與它要測試的類放在同一個包內,以獲得對包成員和保護成員的訪問權。

  • 避免在單元測試中使用特定於域的對象。

 

功能測試是從用戶的角度出發編寫的,並且關注用戶感興趣的系統行爲。找一個優秀的功能測試框架,或者開發一個測試框架,並使用這些功能測試識別用戶的真實需求。這樣,功能測試人員即可獲得一種自動化工具以及使用這一工具的着手點。

使單元測試和功能測試成爲您開發過程中的中心環節。如果您這樣做了,您將對系統的運行及擴展充滿信心。如果您沒有這樣做,您對系統就沒有十足的把握。測試可能不那麼有趣,但是在開發過程中進行單元測試和功能測試使開發變得相當有趣。

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章