寫更好的自動化測試用例!


  抱歉, 文章的開頭我需要先給這個[自動化測試用例]設一個范圍. 自動化用例的形式有很多, 根據測試對象和測試環境的不同, 有各種script和自動化框架來支持你開發出各式各樣的用例.
而本文是基於Robot Framework, 一種keyword driven(關鍵字驅動)的自動化測試框架來講的. 如果你是被題目給騙進來的, 那就說明我的第一個目的已經達到了, 哈哈!
關於更多Robot Framework的信息請google.
 
工作中我經常需要去review其他同事的自動化用例(是的,像軟件代碼那樣被review). 我通常從4個方面來審查用例的質量:Readability, Maintainability, Reliability, Performance,
而這4個方面可以具體到下面這些具體工作:
  • Coding Style
     良好的規范可以極大的增強用例的可讀性和可維護性. 當這些用例被轉交給他人時, 也會因為相同的coding style增加對方的接受度.
     當一位"新人"參與用例編寫時我會首先把注意力放到Coding Style上, 因為這也是最容易做到的. 為此我們定義了一些規范:
  a.好的命名規范
    文件名不能包含特殊符號並且遵照特定的格式. 不同作用域的變量采用不同的命名方式, 變量名描述的更有意義, 全局變量要在Variables表中定義..
  還有case的命名、keyword、case setup、teardown.
  b.documentation
    作為用例的補充信息documentation是必不可少的,如果測試用例本身或者背景太過復雜, 我們還可以給suite、test case、keyword分級加注釋.
  c.tags
    給用例打上正確的標簽.標簽的應用非常的廣泛和靈活既可以拿來做用例篩選、版本管理、統計、調度策略,還可以為一些測試策略如[基於風險的測試]提供方案.
  d....
  • 讓case讀起來像文檔
    在考慮Coding Style時我們可以設置一些固定的規則,大家只要按照這個規則來做,實踐幾次之后Coding Style就會趨於統一. 而考慮將case寫的如同文檔一般則需要更多的主觀能動性.
  為什么需要這樣的mindset? 公司開始推行敏捷之后,測試也在不斷的追求更敏捷的測試.敏捷強調 "快速進入, 不斷迭代", 而文檔在整個開發過程中不可避免的被弱化, 需求設計不斷的更新,
  文檔往往不能被很及時的更新. 那么怎樣可以讓測試人員如何快速的掌握某個功能或者產品的需求和當前狀態呢? 答案是用例.
 
  a.簡潔明了的documatation
  通過增加[用例注釋]來增強用例的可讀性是一個不錯的辦法.一個suite文件往往包含了一組測試用例,suite level的documation通常可以包含該組測試的背景信息、這組測試的目的、特殊的環境配置說明等.
  要控制documatation的長度,可以通過添加link來擴展更多信息.不要過多的描述測試的詳細內容,用例本身應該對其有很好的描述.也不要因為文檔而文檔,將case名或者重復的信息放在上面.
  case level的documatation我們覺得一般情況下是不需要的, 因為case的結構本身應該足夠清楚的描述.
 
  b.清晰的用例名
  用例文件名應該能簡單描述文件內所有case的測試目的.我們建立一個目錄來存儲測試點相近的測試用例, 目錄名可以更抽象, 然后我們給這個用例一致的命名規則.
  這樣當在你瀏覽一組用例時,僅僅通過用例名就能大致了解里面的測試內容,也方便你尋找某個case. 應該更多的從用戶角度來思考文件名,對比下面兩個文件名:
  Suite Name1: creation handling after remove unnecessary fatal error.html
  Suite Name2: Avoid DSP restart by removing unnecessary fatal error when timeout happened during call creation.html
 
  c.條例清晰的case step
     case name
     case step
     keyword
  • case的獨立性
  通常一個test suite包含了一組相近的或者有關聯的test case. 而每一個test case應該只測試一種場景,根據case復雜程度的不同場景同樣可大可小,可以是某個功能的測試也可以是端到端的完整測試.(當然也有特殊的寫法比如工作流測試和數據驅動.) case的獨立性又有哪些需要關注的點呢? 
  首先一個test suite內的test case在執行時不應該相互影響, 應該將通用的背景部分提取出來放到suite setup中, 允許我隨機的跑某一個case或者亂序的跑這些case. 如果case的步驟有造成環境被破壞的風險,那應該在case teardown中將環境恢復,並且在case setup中做環境監察以及時的終止case. suite level和folder level同樣要注意獨立性的問題,在CRT中通常會將數百數千的case放在一起跑,robot並不會規定case執行的順序所以從某種程度上來說它是隨機的.獨立性還體現在case fail時信息的抓取上,經過一個晚上大批case的執行之后,環境通常已被破壞, 希望通過保留現場來用作case失敗問題定位是不現實的.
所以每個case都應該准確的收集其開始和結束之間的信息.
  • case的可遷移性
  case的可遷移性主要考慮:case對執行環境的依賴,case對外部設備的依賴,case對測試對象的依賴.
   a.避免依賴執行環境,你一直在個人PC上編寫的用例並執行測試,但是不久之后你的用例就會被遷移到組內的測試執行服務器上,之后又被部署到持續集成服務器上,
中途也有可能被其他同事下載到他的個人PC上來執行測試.所以在編寫用例時我們要避免支持不同平台的不同庫(windows,linux)和或者不同的腳本命令(CentOS,RedHat,MacOS) 
總之要像Java宣揚的那樣"一處編譯處處運行".
 
  b.在通信領域為了測試需要或者擴展測試覆蓋,我們會引入一些外部設備如Spirent、Cisco的一些輔助測試設備,各種網絡設備交換機、路由器,還有一些自行開發的模擬設備.
外部設備會不斷的升級或者更換,在編寫用例時我們就需要考慮如何用一套case更好的兼容這些測試設備. 我有如下幾點建議:
  i.首先將外部設備的操作從測試用例步驟中剝離出去,組織成組級別的庫.
  ii.
 
     c.對測試對象的依賴,這里我考慮到的是如果測試對象是一個軟件平台,軟件平台通常需要適配多種的設備.而設備的硬件配置可能是多種多樣的,CPU、內存、組件的性能和數量都可能不同.
     對測試對象的依賴不僅要考慮在不同設備上的可執行性,重點要考慮測試覆蓋率,由於設備組件的增多你的用例可能無法覆蓋到這些組件,或者捕捉不到某個性能瓶頸,這樣測試結果的可靠性也大打折扣.
  • case的可重用性
  自動化用例的開發通常是一項費時的工作,它需要的時間會是手動執行用例的10倍、20倍甚至更多. 我們通過搭建測試框架和封裝資源庫來實現最大范圍的可重用性.
這里我考慮用例的可重用性包括兩塊:邏輯層的抽象和業務層的重用.
  對一個產品或者功能進行自動化工作時,我們要考慮這些可用性:首先根據測試邏輯的不同對測試用例進行分類,根據邏輯的不同選擇搭建有針對性的case框架,Work Flow, Data Driven等.
  建立公共的庫,將業務的原子操作抽象出來,並且鼓勵其他同事對庫進行補充和調用,避免duplicated庫開發.抽象的API通常需要足夠的原子和靈活才會被大眾所接受. 基於底層API編寫的業務操作也具備可重用性,比方說測試場景(背景資源)的建立、工作流的操作組合、檢查點都可以被復用. 層次分明的抽取時重用性的基礎,提高可重用性可以減少開發時間,也方便日后的維護中的迭代修改.
  • case的效率
  不同的case執行時間相距甚遠,短則數秒長則數小時甚至數天,數秒鍾的簡單功能測試用例和穩定性測試耗時數天的用例本身是沒有什么可比性的.但是我當我們放眼某一個或者某一組case時,我們需要重視效率.不論是敏捷還是持續集成都講究快速的反饋,開發人員能在提交代碼后快速的獲得測試結果反饋,測試人員能在最短的時間內執行更大范圍的測試覆蓋,不僅能提高團隊的工作效率也可增強團隊的信心.
  在編寫用例時我們應該注意哪些方面來提高用例的性能?
 
  對於單一的case我的注意點多放在一些細節上,例如:
  1.執行條件的檢查,如果檢查失敗,則盡快退出執行.
  2.將執行環境搭建或者資源建立和清除 抽取到suite甚至folder level, 抽取時可能需要做一些組合, 但決不允許出現重復的建刪操作.
  3.用例中不允許出現sleep,sleep通常緊接着hard code的時間,不僅效率低還會因為環境的切換使得執行失敗.建議用"wait until ..."來代替.
  4.如有不可避免的sleep,我通常會再三確認其是否清楚它的必要性.
 
  對於批量的case,我們要如何才能獲得更高的效率呢?
  1.首先我們考慮到可以並行的執行一組case來提高效率,並行方案總有着嚴苛的條件:
測試背景 測試步驟 檢查點 同步 注意點
不同 不同 不同 N 對於完全沒有交集的case,通常是件困難的事,你很難做到將所有東西隔離出來,做到互不影響.
不同 相同 不同 適用 唯一要做到的是將兩者的測試背景融合在一起.
不同 不同 相同 N 融合背景;不同的測試步驟需要避免相互影響;相同的檢查點可能導致case因為相同的原因fail,或者無法明確fail的原因.
相同 相同 不同 最佳 這種情況完全可以考慮合並case,或者並行.
相同 不同 相同 N 同第三種情況.
     2.為了獲得更快的反饋,我們將軟件質量分為0~10級,對應的把測試用例分為6~10級,從普通的功能測試開始測試復雜度逐級遞增.
     不同的開發階段或者是針對不同的測試目的我們就可以有選擇的調用不同級別的用例.比方說我們調用6級的cases來測試新功能代碼作為冒煙測試的用例集;軟件人員修改了BUG,我可以根據BUG的復雜度選擇7和8級的用例來驗證,系統級測試時我們又會主要測試8和9級的用例.
     分級可以靈活調度用例,並給出更快的反饋,加速迭代過程.
     3.基於風險的測試
     基於風險的測試簡單的說就是根據優先級來選擇需要運行的測試,優先級根據兩個最基本的維度:
     功能點發生錯誤的概率,以及發生錯誤后的嚴重性,根據兩者分值的乘積來排序優先級.
     一般從用例失敗率,bug統計,出錯的代碼段,更新的代碼段來考慮調度.比方說根據BUG修改的代碼段和功能區域來選擇對應的測試.開發人員通常反對這種方式,只有100%的測試覆蓋才能給他們足夠的信心.
 
  以上是個人的一些積累,由於框架的限制一些建議不一定適用於你的實際工作. 如果你有什么建議歡迎留言. Thx!
 
                                                                             D on Fire 寫於2014.9.11晚

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM