首先要申明,其實這句話是十分有道理的,但我發現很多人都曲解了這句話的原意,一心要設計出發現“難于發現的缺陷”而陷入盲目的片面中去,忘記了測試的目的所在,這是十分可怕的。我傾向于將測試用例當作一個集合來認識,對它的評價也只能對測試用例的集合來進行,測試本身是一種“V&V”的活動,測試 需要保證以下兩點: 程序做了它應該做的事情 ·測試用例應該詳細記錄所有的操作信息,使一個沒有接觸過系統的人員也能進行測試; 不知道國內有沒有公司真正做到這點,或者說,不知道有國內沒有公司能夠將每個測試用例都寫得如此詳細。在我的測試經歷中,對測試用例描述的詳細和復雜程度 也曾有過很多的彷徨。寫得太簡單吧,除了自己沒人能夠執行,寫得太詳細吧,消耗在測試用例維護(別忘了,測試用例是動態的,一旦測試環境、需求、設計、實 現發生了變化,測試用例都需要相應發生變化)上的時間實在是太驚人,在目前國內大部分軟件公司的測試資源都不足的情況下,恐怕很難實現。但我偏偏就能遇到 一些這樣的老總或者是項目負責人,甚至是測試工程師本身,全然不顧實際的資源情況,一定要寫出“沒有接觸過系統的人員也能進行測試”的用例。 在討論這個問題之前,我們可以先考慮一下測試的目的。測試的目的是盡可能發現程序中存在的缺陷,測試活動本身也可以被看作是一個Project,也需要在 給定的資源條件下盡可能達成目標,根據我個人的經驗,大部分的國內軟件公司在測試方面配備的資源都是不足夠的,因此我們必須在測試計劃階段明確測試的目 標,一切圍繞測試的目標進行。 除了資源上的約束外,測試用例的詳細程度也需要根據需要確定。如果測試用例的執行者、測試用例設計者、測試活動相關人對系統了解都很深刻,那測試用例就沒有必要太詳細了,文檔的作用本來就在于溝通,只要能達到溝通的目的就OK。在我擔任測試經理的項目中,在測試計劃階段,一般給予測試設計30% - 40%左右的時間,測試設計工程師能夠根據項目的需要自行確定用例的詳細程度,在測試用例的評審階段由參與評審的相關人對其把關。 ·測試用例設計是一勞永逸的事情; 這句話擺在這里,我想沒有一個人會認可,但在實際情況中,卻經常能發現這種想法的影子。我曾經參與過一個項目,軟件需求和設計已經變更了多次,但測試用例 卻沒有任何修改。導致的直接結果是新加入的測試工程師在執行測試用例時不知所措,間接的后果是測試用例成了廢紙一堆,開發人員在多次被無效的缺陷報告打擾 后,對測試人員不屑一顧。 這個例子可能有些極端,但測試用例與需求和設計不同步的情況在實際開發過程中確是屢見不鮮的,測試用例文檔是“活的”文檔,這一點應該被測試工程師牢記。 ·測試用例不應該包含實際的數據; 測試用例是“一組輸入、執行條件、預期結果”、毫無疑問地應該包括清晰的輸入數據和預期輸出,沒有測試數據的用例最多只具有指導性的意義,不具有可執行 性。當然,測試用例中包含輸入數據會帶來維護、與測試環境同步之類的問題,關于這一點,《Effective Software Test》一書中提供了詳細的測試用例、測試數據的維護方法,可以參考。 ·測試用例中不需要明顯的驗證手段; 我見過很多測試工程師編寫的測試用例中,“預期輸出”僅描述為程序的可見行為,其實,“預期結果”的含義并不只是程序的可見行為。例如,對一個訂貨系統, 輸入訂貨數據,點擊“確定”按鈕后,系統提示“訂貨成功”,這樣是不是一個完整的用例呢?是不是系統輸出的“訂貨成功”就應該作為我們唯一的驗證手段呢? 顯然不是。訂貨是否成功還需要查看相應的數據記錄是否更新,因此,在這樣的一個用例中,還應該包含對測試結果的顯式的驗證手段:在數據庫中執行查詢語句進行查詢,看查詢結果是否與預期的一致。 七、從用例中生成測試用例
例如,下圖中經過用例的每條不同路徑都反映了基本流和備選流,都用箭頭來表示?;玖饔弥焙诰€來表示,是經過用例的最簡單的路徑。每個備選流自基本流開始,之后,備選流會在某個特定條件下執行。備選流可能會重新加入基本流中(備選流 1 和 3),還可能起源于另一個備選流(備選流 2),或者終止用例而不再重新加入某個流(備選流 2 和 4)。
遵循上圖中每個經過用例的可能路徑,可以確定不同的用例場景。從基本流開始,再將基本流和備選流結合起來,可以確定以下用例場景:
注:為方便起見,場景 5、6 和 8 只描述了備選流 3 指示的循環執行一次的情況。 生成每個場景的測試用例是通過確定某個特定條件來完成的,這個特定條件將導致特定用例場景的執行。 例如,假定上圖描述的用例對備選流 3 規定如下: “如果在上述步驟 2‘輸入提款金額’中輸入的美元量超出當前帳戶余額,則出現此事件流。系統將顯示一則警告消息,之后重新加入基本流,再次執行上述步驟 2‘輸入提款金額’,此時銀行客戶可以輸入新的提款金額?!?/FONT> 據此,可以開始確定需要用來執行備選流 3 的測試用例:
注:由于沒有提供其他信息,以上顯示的測試用例都非常簡單。測試用例很少如此簡單。 下面是一個由用例生成測試用例的更符合實際情況的示例。
一臺 ATM 機器的主角和用例。 下表包含了上圖中提款用例的基本流和某些備用流:
可以從這個用例生成下列場景
注:為方便起見,備選流 3 和 6(場景 3 和 7)內的循環以及循環組合未納入上表。 對于這 7 個場景中的每一個場景都需要確定測試用例??梢圆捎镁仃嚮驔Q策表來確定和管理測試用例。下面顯示了一種通用格式,其中各行代表各個測試用例,而各列則代表測試用例的信息。本示例中,對于每個測試用例,存在一個測試用例 ID、條件(或說明)、測試用例中涉及的所有數據元素(作為輸入或已經存在于數據庫中)以及預期結果。 通過從確定執行用例場景所需的數據元素入手構建矩陣。然后,對于每個場景,至少要確定包含執行場景所需的適當條件的測試用例。例如,在下面的矩陣中,V(有效)用于表明這個條件必須是 VALID(有效的)才可執行基本流,而 I(無效)用于表明這種條件下將激活所需備選流。下表中使用的“n/a”(不適用)表明這個條件不適用于測試用例。
在上面的矩陣中,六個測試用例執行了四個場景。對于基本流,上述測試用例 CW1 稱為正面測試用例。它一直沿著用例的基本流路徑執行,未發生任何偏差?;玖鞯娜鏈y試必須包括負面測試用例,以確保只有在符合條件的情況下才執行基本流。這些負面測試用例由 CW2 至 6 表示(陰影單元格表明這種條件下需要執行備選流)。雖然 CW2 至 6 對于基本流而言都是負面測試用例,但它們相對于備選流 2 至 4 而言是正面測試用例。而且對于這些備選流中的每一個而言,至少存在一個負面測試用例(CW1 - 基本流)。 每個場景只具有一個正面測試用例和負面測試用例是不充分的,場景 4 正是這樣的一個示例。要全面地測試場景 4 - PIN 有誤,至少需要三個正面測試用例(以激活場景 4):
注:在上面的矩陣中,無需為條件(數據)輸入任何實際的值。以這種方式創建測試用例矩陣的一個優點在于容易看到測試的是什么條件。由于只需要查看 V 和 I(或此處采用的陰影單元格),這種方式還易于判斷是否已經確定了充足的測試用例。從上表中可發現存在幾個條件不具備陰影單元格,這表明測試用例還不完全,如場景 6 - 不存在的帳戶/帳戶類型有誤和場景 7 - 帳戶余額不足就缺少測試用例。 一旦確定了所有的測試用例,則應對這些用例進行復審和驗證以確保其準確且適度,并取消多余或等效的測試用例。 測試用例一經認可,就可以確定實際數據值(在測試用例實施矩陣中)并且設定測試數據
以上測試用例只是在本次迭代中需要用來驗證提款用例的一部分測試用例。需要的其他測試用例包括:
在將來的迭代中,當實施其他事件流時,在下列情況下將需要測試用例:
在確定功能性測試用例時,確保滿足下列條件:
八、從補充規約中生成測試用例并不是所有的測試目標需求都將在用例中有所反映。非功能性需求(如性能、安全性和訪問控制)以及配置要求等將會說明測試目標的其他行為或特征。補充規約是為其他行為生成測試用例的主要來源。 關于如何生成這些其他測試用例的指南說明如下:
為性能測試生成測試用例性能測試用例的主要輸入是補充規約,補充規約中包含了非功能性需求(請參見工件:補充規約)。為性能測試生成測試用例時,請使用下列指南:
與功能性測試的測試用例類似,通常對于每個用例/需求都會存在不止一個測試用例。常見的情況是:存在一個低于性能閾值的測試用例、一個處于閾值上的測試用例,還有一個測試用例高于閾值。 除了以上性能標準以外,確保已確定影響響應時間的特定條件,包括:
將用于性能測試的測試用例記錄在類似于功能測試所使用的矩陣中。 以下是各種性能測試的一些示例: 對于負載測試:
對于強度測試:
為安全性/訪問控制測試生成測試用例主角和用例一同說明系統外部用戶與系統所執行的動作之間的交互,以便為特定主角生成測試結果。復雜系統包含許多主角,所以我們編制測試用例時必須確保只有指定執行用例的主角可以進行此操作,這一點非常關鍵。在基于主角類型的用例事件流存在差別時,尤其如此。 例如,在 ATM 用例中,如果主角“銀行客戶”的卡和帳戶有的屬于擁有這個 ATM 機的銀行,有的是競爭銀行的銀行卡(和帳戶),或是企圖使用該 ATM 不支持的銀行卡,則將對該主角“銀行客戶”執行不同的用例事件流。 對于功能性測試用例,請同樣遵循上面列舉的指南。 關于安全性和訪問控制測試用例的示例:
為配置測試生成測試用例在典型的分布式系統中,允許存在許多種受支持的硬件和軟件組合。為了核實測試目標在不同的配置情況下(如不同的操作系統、瀏覽器或 CPU 的速度)能否正常工作或執行,應該對此進行測試。此外,測試還應涵蓋構件的組合,以便檢測在不同構件的交互中產生的缺陷。例如,確保由應用程序安裝的 DDL 版本不會與另一個應用程序需要的相同 DDL 的版本發生沖突。 采用下列指南來生成用于配置測試的測試用例:
為安裝測試生成測試用例安裝測試需要核實測試目標可以在所有可能的安裝情況下安裝。安裝情況可以指首次安裝測試目標,或是在裝有較早版本的機器上安裝測試目標的某個較新的版本或工作版本。安裝測試還應確保在遇到異常情況時(如磁盤空間不足),測試目標的執行情況仍可接受。 測試用例應包含以下各種軟件的安裝情況:
客戶機服務器軟件的安裝程序具備一組特定的測試用例。不同于基于主機的系統,服務器和客戶機上的安裝程序是有所不同的。因而,安裝測試應執行構成測試目標的所有構件的安裝,包括客戶機、中間層以及服務器,這一點至關重要。 為其他非功能性測試生成測試用例理論上,應找到所有必需的輸入來生成測試用例模型、設計模型以及補充規約工件的測試用例。不過,如果此時您需要補充已有的輸入,那也不足為奇。 示例如下:
大多數情況下,您可以通過先前所確定的測試用例生成的某些測試用例來構建其變體或聚合關系體,借此來查找測試用例。
九、為單元測試生成測試用例 單元測試要求既測試單元的內部結構同時還要測試其行為特征。測試內部結構要求了解實施單元的方式,基于這種了解的測試被稱為白盒測試。對單元行為特征的測試側重于從外部可觀察的單元行為,而不需要了解或考慮其實施方式?;谶@種方法的測試稱為黑盒測試?;谶@兩種方法所生成的測試用例的說明如下。 白盒測試 理論上,應通過代碼測試每一條可能的路徑。在所有這些非常簡單的單元內實現這樣的目標是不切實際或幾乎是不可能的。作為最基本的測試,應將每個決定到決定路徑(DD 路徑)測試至少一次,這樣可確保將所有語句至少執行一次。決定通常是指 if 語句,而 DD 路徑是兩個決定之間的路徑。 要達到這種程度的測試覆蓋,建議您在選擇測試數據時應使每個決定都可以用每種可能的方法來評估。為達到上述目標,測試用例應確保: 每個布爾表達式的求值結果為 true 和 false。例如,表達式 (a<3) OR (b>4) 的求值結果為 true/false 的四種組合 示例: 假設您對類 Set of Integers 中的 member 函數執行結構測試。該測試在二進制搜索的幫助下,將檢查該集合是否包含了某個指定的整數。 成員 (member) 函數以及相應的流程圖。虛線箭頭指示出如何通過采用兩個測試用例將所有語句至少執行一次。 理論上,對于徹底測試的某個操作,測試用例應遍歷代碼內路徑的所有組合情況。在 member 函數的 while-loop 中存在三個可選擇的路徑。測試用例可以多次遍歷該循環,或是根本就不遍歷。如果測試用例根本就沒有遍歷循環,則在代碼中只能找到一條路徑。如果遍歷循環一次,您將發現有三條路徑。如果遍歷兩次,則您將發現存在六條路徑,如此類推。因而,路徑的總數應該是:1+3+6+12+24+48+...,在實際情況中,這個路徑組合總數根本無法無法處理。這就是為什么必須選擇所有這些路徑的子集的原因。本示例中,可以采用兩個測試用例來執行所有的語句。其中一個測試用例中,您可以選擇 Set of Integers = {1,5,7,8,11},而且測試數據 t = 3。在另一個測試用例中,您可以選擇 Set of Integers = {1,5,7,8,11},且 t = 8。 黑盒測試 黑盒測試的目的是為了在不了解單元將如何實施指定行為的情況下,對指定行為進行驗證。黑盒測試側重并依賴于單元的輸入和輸出。 等價類劃分是一種用來減少所需測試數量的技術。對于每一個操作都應確定參數和對象狀態的等價類。等價類是一組值的集合,對這組值來說,對象的行為應類似。例如,一個集合可有三個等價類:空、若干元素以及滿。 可使用代碼覆蓋工具來確定白盒測試未測試到的代碼。在進行黑盒測試的同時應進行可靠性測試。 接下來的兩個小節說明了如何通過選擇特定參數的測試數據來確定測試用例。 基于輸入參數的測試用例 每個等價類的正常值。 基于輸出參數的測試用例 每個等價類的正常值。 如果對象受狀態控制(根據對象的狀態產生不同的反應),您應利用狀態矩陣,如下圖所示: 用于測試的狀態矩陣。您可以在此矩陣的基礎上測試激勵和狀態的所有組合。 十、為產品驗收測試生成測試用例 |
原文轉自:http://www.anti-gravitydesign.com