1. 程式人生 > 其它 >淺析設計測試用例的四條原則:單個用例覆蓋最小化原則、測試用例替代產品文件功能原則、單次投入成本和多次投入成本原則、使測試結果分析和除錯最簡單化原則

淺析設計測試用例的四條原則:單個用例覆蓋最小化原則、測試用例替代產品文件功能原則、單次投入成本和多次投入成本原則、使測試結果分析和除錯最簡單化原則

  測試用例設計的最基本要求:覆蓋住所要測試的功能。這是再基本不過的要求了,別看只是簡單的一句話,要能夠達到切實覆蓋全面,需要對被測試產品功能的全面瞭解、明確測試範圍(特別是要明確哪些是不需要測試的)、具備基本的測試技術(如:等價類劃分等)等。

  那麼滿足了上述這條要求是不是設計出來的測試用例就是好的測試用例了呢?答案:在理論上是,但在實際工程中還遠遠不是。之所以理論和實際會有這樣的差別,是因為在理論上不要考慮的東東,而在實際工程中是不得不考慮的 - 成本。這裡的成本包括:測試計劃成本、測試執行成本、自動化測試用例、測試自動化成本,測試分析成本,以及測試實現技術侷限、測試環境的Bug、人為因素和不可預測的隨機因素等引入的附加成本等。

  由於成本因素的介入,決定了工程中設計好的測試用例原則不只有“覆蓋住所要測試的功能”這一條,下面是我根據自己的工作經驗總結出的其它四條原則,在這裡拋磚引玉,希望大家拍磚和指正。這些原則特別是針對那些需要被自動化,並且是要被經常執行的測試用例。

一、單個用例覆蓋最小化原則

  這條原則是所有這四條原則中的”老大“,也是在工程中最容易被忘記和忽略的,它或多或少的都影響到其它幾條原則。

  下面舉個例子來介紹,假如要測試一個功能 A,它有三個子功能點 A1,A2 和 A3,可以有下面兩種方法來設計測試用例:

  方法1 :用一個測試用例覆蓋三個子功能 -Test_A1_A2_A3,

  方法2 :用三個單獨的用例分別來覆蓋三個子功能 - Test_A1,Test_A2,Test_A3

  方法1適用於規模較小的工程,但凡是稍微有點兒規模和質量要求的專案,方法2則是更好的選擇,因為它具有如下的優點:

(1)測試用例的覆蓋邊界定義更清晰

(2)測試結果對產品問題的指向性更強

(3)測試用例間的耦合度最低,彼此之間的干擾也就越低

  上述這些優點所能帶來直接好處是,測試用例的除錯、分析和維護成本最低。每個測試用例應該儘可能的簡單,只驗證你所要驗證的內容,不要“摟草打兔子”捎帶著把啥啥啥啥都帶進來,這樣只會增加測試執行階段的負擔和風險。David Astels在他的著作《Test Driven Development:A Practical Guide》曾這樣描述 : " 最好一個測試用例只有一個Assert語句"。此外,覆蓋功能點簡單明確的測試用例,便於組合生成新的測試。

二、測試用例替代產品文件功能原則

  通常我們會在開發的初期(Scrum每個Sprint的頭兩天)用Word文件記錄產品的需求、功能描述、以及當前所能確定的任何細節等資訊,勾勒將要實現功能的輪廓樣貌,便於團隊進行交流和細化,並在團隊內達成對將要實現的產品功能共識。

  假設我們在此時達成共識後,描述出來的功能為A,隨著產品開發深入,經過不斷地迭代之後,團隊會對產品的功能有更新的認識,產品功能也會被更具體細化,在一個迭代或者Sprint結束的時候最終實現的功能很可能是A+。

  如此往復,在不斷傾聽和吸收使用者的反饋,修改產品功能,多個迭代過後,原本被描述為A的功能很可能最終變為了Z。這是時候再去看曾經的Word文件卻仍然記錄的是A。之所以會這樣,是因為很少有人會去(以及能夠去)不斷更新那些文件,以準確反映出產品功能當前的準確狀態。不是不想去做,而是實在很難!這裡需要注意:早期的Word文件還是必要的,它至少能保證在迭代初期團隊對要實現功能有一致和準確的認識。

  就沒有什麼東西能夠一直準確地描述產品的功能了嗎?答案:當然有,那就是產品程式碼和測試用例。產品程式碼實現了產品功能,它一定是準確描述了產品的當前功能,但是由於各種程式設計技術,如:面向物件、抽象、設計模式、資原始檔等等,使得產品程式碼很難簡單地就能讀懂,往往是在知道產品功能的前提下去讀程式碼,而不是反過來看程式碼來了解功能。好的程式碼會有詳細的註釋來記錄為什麼程式碼要這樣寫 (Why you did it?),但這裡的註釋是對實現程式碼的解釋和備註,並不是對產品功能的描述。這裡有一篇Eric Lippert 的部落格 Reading Code Is Hard,介紹了為什麼說閱讀程式碼比寫程式碼更難,以及如何能夠使程式碼更可讀一些編寫技巧。

  那麼就只有測試用例了,測試也應該忠實反映了產品的功能,否則的話測試用例就會執行失敗。以往大家只是就把測試用例當作測試用例而已,其實對測試用例的理解應該再上升到另一個高度,它應該是能夠扮演產品描述文件的功能

  這就要求我們編寫的測試用例足夠詳細、測試用例的組織要有調理、分主次,單靠Word、Excel或者OneNote這樣通用的工具是遠遠無法完成的,需要更多專用的測試用例管理工具來輔助。

  此外,對於自動化測試用例(無論是API或者UI級別的)而言,程式碼在編寫上也應該有別產品程式碼編寫風格,可讀性和描述性應該是重點考慮的內容。在測試程式碼中,當然可以引入面向物件、設計模式等優秀的設計思想,但是一定要適度使用,往往面向過程的編碼方式更利於組織、閱讀和描述。

三、單次投入成本和多次投入成本原則

  與其說這是一條評判測試用例的原則,不如說它是一個思考問題的角度。

  成本永遠是任何專案進行決策時所要考慮的首要因素,軟體專案中的開發需要考慮成本,測試工作同樣如此。對成本的考慮應該客觀和全面地體現在測試的設計、執行和維護的各個階段。當你在測試中遇到一些左右為難的問題需要決策時,嘗試著從成本角度去分析一下,也許會給你的決策帶來一些新的啟發和靈感。

  測試的成本按其時間跨度和頻率可以分為:單次投入成本和多次投入成本。

  例如:編寫測試用例可以看作是單次投入成本,因為編寫測試用例一般是在測試的計劃階段進行(Scrum每個Sprint的開始階段)的,雖然後期會有不斷的調整,但絕大多數是在一開始的設計階段就基本上成型了;自動化測試用例也是如此,它也屬於是一次性投入;

  測試用例(包括:手工和自動化測試用例)的執行則是多次投入成本,因為每出一個新版本Build時都要執行所有的測試用例(或者進行BVT測試僅執行高優先順序的測試用例)、分析測試結果、除錯失敗測試用例、確定測試用例的失敗原因(產品缺陷、測試用例缺陷、測試框架缺陷還是隨機問題導致了測試用例的失敗),以驗證該版本整體質量是否達到了指定的標準。

  之所以要引入單次和多次成本的思考,是希望能夠通過區分測試中不同活動對測試成本的影響,從而進行幫助我們合理佈局在不同階段的投入和做出正確的決策,以保證在有限可負擔測試成本的前提下,最大限度地有效開展測試工作

  例如,當我們意識到了,測試用例的設計和自動化屬於是一次性投入,而測試用例的執行則是反覆多次的投入時,就應該積極思考如何能夠提高需要反覆投入的測試執行的效率,在一次投入和需要多次活動需要平衡時,優先考慮多次投入活動的效率,其實這裡是有很多工作可以做。

  例如:第一條原則-單個用例覆蓋最小化原則 - 就是一個很好的例子,測試A功能的3個功能點A1,A2和A3,從表面上看用Test_A1_A2_A3這一個用例在設計和自動化實現時最簡單的,但它在反覆執行階段會帶來很多的問題:

  首先,這樣的用例的失敗分析相對複雜,你需要確認到底是哪一個功能點造成了測試失敗;

  其次,自動化用例的除錯更為複雜,如果是A3功能點的問題,你仍需要不斷地走過A1和A2,然後才能到達A3,這增加了除錯時間和複雜度;

  第三,步驟多的手工測試用例增加了手工執行的不確定性,步驟多的自動化用例增加了其自動執行的失敗可能性,特別是那些基於UI自動化技術的用例;

  第四,(Last but not least)將不相關功能點耦合到一起,降低了儘早發現產品迴歸缺陷的可能性,這是測試工作的大忌。例如:如果Test_A1_A2_A3是一個自動測試用例,並按照A1->A2->A3的順序來執行的,當A1存在Bug時,整個測試用例就失敗了,而A2和A3並未被測試執行到。

  如果此時A1的Bug由於某些原因需要很長時間才能修復,則Test_A1_A2_A3始終被認為是因為A1的Bug而失敗的,而A2和A3則始終是沒有被覆蓋到,這裡存在潛在的危險和漏洞。當你在產品就要釋出前終於修復了A1的Bug,並理所當然地認為Test_A1_A2_A3應該通過時,A2和A3的問題就會在這時爆發出來,你不得不繼續加班修復A2和A3的問題。不是危言聳聽,當A2/A3的程式碼與A1的Bug修復相關時,當你有很多如此設計的測試用例時,問題可能會更糟,真的。

  綜上所述,Test_A1_A2_A3這樣的設計,減少地僅是一次性設計和自動化的投入,增加地卻是需要多次投入的測試執行的負擔和風險,所以需要決策時(事實上這種決策是經常發生的,尤其是在設計測試用例時)選擇Test_A1_A2_A3還是Test_A1、Test_A2和Test_A3,請務必要考慮投入的代價。

四、使測試結果分析和除錯最簡單化原則

  這條原則實際上是上一條 - 單次投入成本和多次投入成本原則 - 針對自動化測試用例的擴充套件和延續。

  在編寫自動化測試程式碼時,要重點考慮如何使得測試結果分析和測試調更簡單,包括:用例日誌、除錯輔助資訊輸出等。往往在測試專案中,測試用例的編寫人和最終的執行者是不同的團隊的成員,甚至有個能測試的執行工作被採用外包的方式交給第三的團隊去進行,這在當下也是非常流行的。因為測試用例的執行屬於多次投入,測試人員要經常地去分析測試結果、除錯測試用例,在這部分活動上的投入是相當可觀的。有時候,測試框架提功能的一些輔助API等就可以幫助很好實現這個原則。

  測試理論為日常的測試工作指明瞭前進的方向,但在實際工程中還需要我們不斷地“活化”這些理論,使理論和實踐更好地契合在一起。在我看來,軟體工程專案不論成敗和好壞,對我們每個參與者都是無比寶貴的經歷。

  作為有心人,從中我們體會到很多書本上不曾提到過的東西,只要不斷地去觀察、體會和總結,你會有更多自己的認識、理解和發現。有很多人寫書稱讚,程式碼之美、測試之美,其實工程專案也是很美,只是看你能不能更客觀和專業的角度地去看待它。

  這篇部落格轉載至:https://blog.csdn.net/quicknet/article/details/6111882,雖然看到是十年前的文章,但是其思想和思維考慮還是很有借鑑意義的,值得轉載學習。