測試用例是否應該包含所有的細節?

中心思想:關注“測試思想”而不是關注操作步驟。

______________________________________________________________

 

測試用例寫的太細化了,則適應不了系統的變更需求;寫的太粗糙,則可操作性不強,太隨意。
如果文檔中的對操作步驟描述的過於具體,像下面這樣:
01.  在“用戶名”項中輸入“user”;
02.  在“密碼”項中輸入“password”;
03.  點擊“確定”按鈕。
這樣的描述方式表面看起來可操作性似乎是增強了,任何人拿到這個文檔都可以充當測試人員,檢查一下這個功能是否存在缺陷。但是我們不要忘記,在開發過程中,變更的存在是必然的。一旦需求、設計或者應用程序中的某些細節發生了變化,比如“用戶名”變成了“操作員”,“密碼”變成了“口令”,“確定”變成了“登錄”,或者輸入項所接受的數據類型發生了變化,那麼同這部分內容相關的所有的測試用例都需要修改。否則,我們憑什麼可以保證這些描述不同的測試用例說的是同一樣東西?如果我們只有這麼一個測試用例,也許一切都不是問題,但是對於一個業務複雜、功能完整的系統,如果按照這樣的方法描述測試用例,最終要麼產生大量的測試用例文檔,要麼產生過長的單個文檔。無論是那一種,如果發生了類似於上面說的變化,維護文檔都將變成一次地獄式的體驗。這也是爲什麼在網絡上頻頻出現的這個問題,而且每次出現都會受到測試同行們的關注的原因。
那麼這個問題應該任何解決呢?測試用例是不是把所有的流程寫出來就可以了呢?如何在減少測試用例文檔中包含過多瑣碎的細節的同時保證測試用例的可操作性呢?又有什麼方法可以提高我們維護測試用例文檔的效率呢?

筆者的建議是:關注“測試思想”而不是關注操作步驟。

要理解這個問題,首先要弄明白測試用例的作用。就像用例一樣,測試用例並不是用來描述具體的實現的,而是着重描述處理問題的思路——對於一項明確的測試內容進行測試的思路。作爲測試用例的設計人員,如何理解基本流和備選流?如何深入分析並找到所有需要覆蓋的路徑和需要檢查的特性?我們在測試用例中應該用容易理解的自然語言清晰的來描述我們將要如何進行測試,而不是簡單的把在應用程序上如何操作的煩瑣的步驟記錄下來。把測試用例設計當成填寫具體操作步驟的表格是人們對測試用例最大的誤解。傳統的測試用例文檔編寫有兩種方式。一種是填寫操作步驟列表:將在軟件上進行的操作步驟一步一步詳細的記錄下來,包括所有被操作的項目和相應的值。另一種是填寫測試矩陣:將被操作項作爲矩陣中的一個字段,而矩陣中的一條條記錄,則是這些字段的值。網絡上對於這兩種方式孰優孰劣的爭論,將大家錯誤的引導向了兩個極端:要麼採用A,要麼採用B。而大家卻忽視了一點,對於工作方法的爭論,本質上同工具的爭論並不是一回事(例如曾經的VC、BCB之掙)。如果不同的方法各有優勢,我們完全可以通過變通的方法,把優勢的部分組合在一起來使用。操作步驟列表的優勢在於對基本流和備選流進行分析後,它可以清晰的描述您的測試思路。而測試矩陣則更適合於用來存放測試數據,特別是那些需要人工賦予一個確定的值的特性。下面,我們來看一個例子,當然,這個例子同樣是杜撰的。


需求名稱:用戶登錄安全驗證
需求描述:用戶登錄安全驗證是爲了保證所有登錄到系統中的用戶,都是由系統管理員預先在系統中設定的。使用系統中不存在的用戶名,或者用戶名輸入正確,但密碼輸入錯誤情況,都無法登錄到系統中。當用戶使用了不存在的用戶名或錯誤的密碼時,系統應分別給出適當的提示。如果用戶連續三次無法使用正確的用戶名和密碼登錄到系統,則系統應給出適當的提示,並退出當前程序。如果用戶使用正確的用戶名和密碼登錄到系統,則退出界面,轉到系統主界面。對於用戶登錄界面和程序主界面,請參考相應的UI設計文檔。
測試需求:
01. 檢查能否使用正確的用戶名和密碼登錄到系統;
02. 檢查能否使用錯誤的用戶名或密碼登錄到系統;
03. 檢查使用錯誤的用戶名和密碼登錄失敗超過三次,是否會自動退出當前程序。
測試用例:
序號 操作過程描述
1 輸入用戶名。
2 輸入密碼。
3 確認登錄。
序號 用戶名 密碼 預期結果
1 正確的用戶名 正確的密碼 登錄到系統並轉到系統主界面
2 正確的用戶名 錯誤的密碼 無法登錄到系統並提示密碼錯誤
3 錯誤的用戶名 正確的密碼 無法登錄到系統並提示用戶名錯誤
4 錯誤的用戶名 錯誤的密碼 無法登錄到系統並退出當前程序
5 空用戶名 …… ……
這個例子並不是按照RUP提供的標準模板編寫的,它的目的只是要爲大家展示,用前面所講的方法,整理出來的測試需求和設計完成的測試用例到底是個什麼樣子。所以省略了很多細節,不過大家在實際編寫測試用例文檔的時候,可以根據自己的需要把相應的內容添加上去。同時,也可以在用戶名和密碼兩個字段中填寫準備使用的具體數據。相信大家已經看到,在我們的例子中,測試需求同測試用例之間並非是一一對應的關係因爲一條測試需求未必是明確的對應到一個有效功能的(其實測試需求本身同軟件需求和用例之間也未必是一一對應的)。而我們的測試用例所關注的,應該是一個有效功能。


不過不用擔心,這種情況並不會增加管理測試需求和測試用例的成本,現在市面上提供的測試工具中已經有些是專門用來維護軟件需求、測試需求同測試用例之間的關係的,並且它們提供的強大的視圖功能還可以讓您很容易的查看到測試用例對測試需求的覆蓋情況。對於例子中的測試用例文檔,已經被分成了兩個部分,一部分是描述了測試用例執行者所應遵循的操作過程,一部分則是在操作中需要使用到的測試數據。這樣做的原因是在我們的實際工作中,尤其是在進行功能測試時,很多時候都是使用雷同的操作過程和不同的測試數據來進行的。而使用上面的方法,可以不用再對原本在多個用例中重複出現的操作過程再次描述,而可以把更多的精力放到測試數據的設計和準備上。這樣作帶來的副產品,就是提高了測試用例的可維護性。怎麼?還有人對筆者的觀點持懷疑態度?那好吧,那麼我們來嘗試着證明一下。


我們的郵遞員要在5個城市內奔波,並且每個城市都有些郵件需要投遞,他需要找到可以一次走遍5個城市的所有路線。這聽起來似乎並不是太複雜,利用我們已有的數學知識,很容易就可以得到答案。但是對於我們要測試的內容,通常都會包含更多複雜的規則。例如,我們有三個文本框,每個文本框每次都只能輸入一個英文大寫字母,允許輸入的值只包括:A、B、C三個字母,當三個文本框輸入不同的值的時候,我們不知道會發生什麼,也不知道它們之間是否會互相影響,所以需要您來設計可以覆蓋所有輸入情況的測試用例來測試它。瞧,這很簡單不是嗎?如果我們希望每個測試用例在執行時一旦出現缺陷都可以很快的找到導致缺陷的原因,那麼最好的辦法就是每個測試用例只包括一個同其他測試用例不同的輸入值。那麼可供我們輸入的值都有哪些呢?嗯,對於每個文本框,都至少有A、B、C三種已經聲明的不同的值,另外,我們還要考慮當文本框爲空、輸入空格、輸入非英文字符以及輸入A、B、C之外的英文字符的情況。那麼按照上面的方法,我們會有多少測試用例呢?答案是343個。這只是一個很簡單的例子,我們工作中遇到的軟件的業務規則和特性決不會比這少的,那會有多少個測試用例呢?God knows. 不過至少有一點可以肯定,我們無法在原有業務規則發生變化時高效的、無差錯的維護完343個測試用例。但是如果使用我們前面所描述的方法,對於操作過程的改變,您只需要重新維護一次,而對測試數據的維護,也同樣是非常簡單的,而且並不會因爲連續大量修改時出現的錯誤導致測試用例本身出現歧意。


在將主要精力從“設計”操作步驟轉移到設計測試數據之後,我們還將從這種方法中獲得更大的益處——通過“逆向測試數據分析”來提高測試工作的整體效率。這種“逆向測試數據分析”的方法,是假設軟件中存在多個互相依賴的功能,而且這些功能中包含在“依賴鏈”最末端,並且不再被其他功能依賴的功能。在我們準備測試數據時,首先從這個“依賴鏈”最末端的功能開始,分析這個功能會對不同的輸入產生哪些不同的結果。然後將所有的輸入進行整理,分清哪些輸入是來源於其前一個功能的輸出。之後,對該功能的上一個功能進行同樣的分析,整理出所有的輸入和輸出,但是這個功能的輸出至少應該包含“依賴鏈”最末端功能接收到的全部輸入。繼續按照這樣的思路循環向上,直到到達“依賴鏈”開始端的功能。不知道您在工作中有沒有遇到這樣的情況:在對那些“依賴鏈”上的功能進行測試時,一開始並沒有嚴格的規範測試數據的使用,結果前一個功能測試時產生的數據根本無法在下面的工作中被很好的利用起來,反而因爲大量無效數據增加了後面功能的測試難度。最終不得不對每一個功能重新準備測試數據。大量的時間,浪費在了這些重複而低效的勞動上。


當然,如果希望可以進一步提高某個階段測試工作的效率,還可以考慮應用“設計測試過程”的方法。這裏所說的測試過程,指的是我們在執行測試時所設定的執行測試用例的先後順序。之所以這樣作,是因爲可以充分的利用不同功能之間的耦合性,儘量通過一次操作來檢查儘量多的內容,從而降低已完成工作的無效性或低效性,最終提高某個階段的整體工作效率。不過,這項工作同樣要求操作者必須對被測的系統所涉及的所有業務以及這些業務之間的關係都非常熟悉才行。?如果您正被測試工作的低效問題所困擾,那麼建議您嘗試一下上面的方法,希望會對您的工作有所幫助。

 

發佈了11 篇原創文章 · 獲贊 3 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章