自動化測試思路

zouhui1003it發表於2019-05-11

學習+總結+記錄=成長!

自動化測試介紹

自動化測試(Automated Testing),是指把以人為驅動的測試行為轉化為機器執行的過程。實際上自動化測試往往通過一些測試工具或框架,編寫自動化測試用例,來模擬手工測試過程。比如說,在專案迭代過程中,持續的迴歸測試是一項非常枯燥且重複的任務,並且測試人員在每天重複勞動的工作之下,也絲毫得不到成長。此時開展自動化測試就能夠幫助測試人員從重複、枯燥的手工測試中解放出來,提高測試效率,縮短迴歸測試時間。一般來說,自動化測試通常都會跟持續整合系統(比如Jenkins)配合使用。

但在自動化實踐過程中,往往會發現理想和現實之間的差距很大。自動化測試的劣勢,主要體現在以下幾方面:

  1. 相對手工測試,自動化測試對測試人員的要求相對較高;
  2. 測試用例需要根據版本迭代進行更新,有一定維護成本;
  3. 不能指望自動化測試去發現更多新的BUG,自動化測試能發現的缺陷遠遠比手工測試少;
  4. 自動化測試的產出價值往往在於長期的迴歸測試,短期內發揮的作用可能不明顯;

希望藉助自動化流程解決的問題

  1. 測試時間緊張,手工測試可能覆蓋不全,容易錯過某些邊界情況;
  2. 模組間強耦合時,單純從頁面進行測試時,比較難深入的發現問題;
  3. 迴歸測試時,需要投入較大的人力/工時;
  4. 實現手工測試無法達成的測試任務;
  5. 通過編寫測試用例,加深對業務/資料的認知,有助於下階段迭代中發現隱藏的問題;

引入自動化測試的前提條件

專案週期長,需求變動不頻繁
測試用例的穩定性決定了自動化測試的維護成本。如果軟體需求變動過於頻繁,測試人員需要根據變動的需求來更新測試用例以及相關的測試指令碼,而指令碼的維護本身就是一個程式碼開發的過程,需要修改、除錯。如果所花費的成本不低於利用其節省的測試成本,那麼自動化測試便是失敗的。

專案中的某些模組相對穩定,而某些模組需求變動性很大。我們便可對相對穩定的模組進行自動化測試,而變動較大的仍是用手工測試。

自動化測試指令碼可重複使用
如果費盡心思開發了一套近乎完美的自動化測試指令碼,但是指令碼的重複使用率很低,致使其間所耗費的成本大於所創造的經濟價值,自動化測試便毫無意義。

測試任務手工測試難以實現
比如壓力測試,大資料或者大量重複資料測試,必須有自動化工具的支援。

做自動化測試需要具備的能力

  • 擁有編碼能力
    至少要熟悉自動化工具/框架的程式碼語言,最好有一定的編碼能力,同時程式碼邏輯要清晰,否則不僅不能保證用例的邏輯性、業務性與健壯性等要素,也不能保證效率;
  • 熟悉被測系統;
    熟悉被測系統對任何測試人員來說都是最起碼的要求;
  • 掌握一個自動化測試框架/工具;
    可以根據所掌握的程式碼,學習一門自動化測試的框架,如 Selenium/Appoum/Robot Framework/Nunit/TestNG等;
  • 不斷學習,善於學習,知其然知其所以然;
    “落後就要捱打。”

自動化用例一般在哪個階段完成

一般落後於新功能的手工測試階段,可以在手工用例執行完成或功能上線後,再去補充自動化的用例。
自動化不是跟著新需求走,而是測變化的東西對不變東西的影響,一定不要做為了自動化而自動化的工作。

分層自動化測試

在理解分層自動化之前,我們先看一下經典的測試金字塔。

 
 
  • UI層:介面自動化測試。可以看出它的價值最小,它最接近使用者真實場景,也容易發現問題,但它的實現成本最高且太容易受外部依賴,容易影響指令碼成功率。總體來說,適當的介面自動化測試是有必要的,但是沒有必要在UI層投入太多;

  • Service層:介面自動化測試。它的價值居中,覆蓋大多數主要的介面是比較合適的。這一層要求測試人員對系統的結構和系統間的排程非常清楚,同時要了解介面邏輯關係,否則介面測試程式碼很容易遺漏一些異常場景;

  • Unit層:單元測試。最有價值的測試,但是對測試人員要求比較高,一般由開發人員完成,否則只能採用結對程式設計。
    通常來說,手工測試是最基本的,可以做到接近100%,而對於自動化測試來說,它更像是一件”防彈衣”,用來防護身體的主要部位。有人認為自動化率提高了,就可以節省人力,這實際是非常片面的,因為提高自動化率,意味著需要投入更大的人力在維護的成本上。因為系統的需求是在不斷變化的,每一個變化都會導致自動化測試用例需要更新調整。

    所以,自動化測試做到什麼樣才算好,也要結合上面的測試金字塔來分析。對於UI層面的自動化測試,保證少量必要的主流程即可,切勿在這一層面將自動化測試的”防彈衣”變成臃腫的”宇航服”;Service層面的介面自動化測試,可以考慮覆蓋大部分的流程;Unit層面的單測,做到100%是最好的,即使有需求變化,一般也很少影響到已有的用例。一般來說,單元測試可以發現80%的缺陷。

設計自動化用例的原則

基本原則

  • 自動化測試用例的範圍必須是相對核心的業務流程,即覆蓋主體功能的核心測試點和重複執行率較高的模組;
  • 在測試指令碼和被測程式碼都保持不變的情況下,測試用例的結果應該是穩定的,這一點非常重要;
  • 除非是必要的情況,否則任何用例都應當避免做持久化的操作,以保證環境始終是乾淨的;
  • Once Written, Run Anytime as Desired ;
  • 不是所有的手工測試用例都可以使用自動化測試來實現,自動化測試替代不了手工測試,兩者的有效結合是保證專案質量的關鍵。
  • 迴歸測試場景中,測試用例的選擇一般以正向為主,逆向為輔;

用例設計原則

保持Case的獨立性

通常來說,一個Test Suite下包含了一組相近的或者有關聯的Test Cases。而每一個 Test Case 應該只測試一種場景,根據case複雜程度,不同場景同樣可大可,可以是某個單元的測試,也可以是端到端的測試(E2E),當然也有特殊的寫法比如工作流測試和資料驅動。

Case的獨立性有哪些需要關注的點呢?

首先Test Suite內的Cases在執行時不應該相互影響,意思是說當我們有隨機的跑其中某個Case或亂序的跑這些Cases時,測試的結果都應該是準確的。Suite level和Directory level同樣要注意獨立性的問題。系統較為龐雜時,可能會將數百上千的Cases放在一起跑,Robot本身不會規定Case執行的順序,所以從某種程度上來說同一層級的Cases是隨機執行的。很典型的情況就是,測試用例在本地除錯時怎麼跑怎麼過,放到Server上所有Cases一起跑的時候就會Fail,還可能是偶發的,這種情況下就很可能是由於其他Case的痕跡影響到了它,查詢問題的根源往往比較耗時。

保持Case的可遷移性

Case的可遷移性主要考慮三點 : Case對執行環境的依賴 ; Case對外部裝置的依賴;Case對測試物件的依賴。

Case對執行環境的依賴
儘量減少對執行環境的依賴。舉一個例子,你在本地PC上使用rf框架編寫、除錯用例後,上傳到Git,然後你的領導可能會拉取你的用例在他的本地執行,隨後又被部署到持續整合伺服器上。所以你編寫的用例時就要儘量避免使用不同平臺的庫或者shell命令。

再舉個例子,如果你因為業務需要而修改了測試庫原始碼的話,此時不管是組內其他人還是CI伺服器,肯定都會執行失敗,這種情況該怎麼解決呢?這裡提供兩個解決方法:

  1. 將修改後的庫做成測試庫,上傳到Git或者Pypi,對方可以通過pip安裝更新;
  2. 使用robotremoteserver做一個共享庫放在遠端主機上,具體請參考蟲師的文章

Case對外部裝置的依賴
有時為了業務測試需要,我們會引入一些外部裝置來輔助測試,外部裝置可能會持續升級或者更換,在編寫用例時我們就需要考慮如何用一套Case更好的相容這些測試裝置。比如可以將外部裝置的操作從測試用例中抽離出去,封裝成測試庫或關鍵字;

Case對測試物件的依賴
如果測試物件是一個軟體平臺,軟體平臺通常需要適配多種的裝置,而裝置的硬體配置可能是多種多樣的:CPU、記憶體、元件的效能和數量都可能不同。對測試物件的依賴不僅要考慮在不同裝置上的可執行性,重點還要考慮測試覆蓋率。由於裝置元件的增多你的用例可能無法覆蓋到這些元件,或者捕捉不到某個效能瓶頸,這樣測試結果的可靠性也大打折扣。

提升Case執行效率

不同的case執行時間相距甚遠,短則數秒長則持續數天。數秒鐘的簡單功能測試用例和耗時數天的穩定性測試用例本身是沒有什麼可比性的。但是我當我們放眼某一個或者某一組case時,我們就需要重視Case的執行效率。不論是敏捷流程還是持續整合都講究快速的反饋,開發人員能在提交程式碼後快速的獲得測試結果反饋,測試人員能在最短的時間內執行更大範圍的測試覆蓋,不僅能提高團隊的工作效率,也可增強團隊的信心。

以使用rf為例,在編寫用例時可以通過以下方面來提高用例的執行效率。

1.如果有對執行條件的檢查,若檢查失敗,則儘快退出執行;
2.將資料準備或環境清除等工作抽取成關鍵字放到更高的層級中,,抽取時可能需要做一些組合, 但不允許出現重複的建刪操作;
3. 用例中儘量少的出現sleep,建議用”wait until …”來代替;
4. 可以採用併發執行用例的方法來提升效;

自動化用例編寫規範

命名規範

Keyword命名

第一個單詞應以小寫字母作為開頭,後面的單詞則用大寫字母開頭。 如:getProjectId, connectDB

常量命名

常量的名字應該都使用大寫字母,並且指出該常量完整含義。如果一個常量名稱由多個單片語成,則應該用下劃線來分割這些單詞。 如:MAX_CHAR_LENGTH

引數命名

引數的命名規範和方法的命名規範相同,請在儘量保證引數名稱為一個單詞的情況下使引數的命名儘可能明確。如:${account} , ${investorName}

使用Tags

RF提供了通過在Settings中設定tags來管理用例的方法。Tag的應用非常的廣泛和靈活,比如可以用來做用例篩選、版本管理、統計策略等。

 
 

怎麼打tag看起來會更便捷?

  • 可以在各個資料夾下打資料夾名字的tag,這樣就可以根據tag單獨的跑該資料夾下的用例,檢視測試報告也更好看些;
  • 在一些重要的用例上打上tag,可以單獨跑關鍵用例;
  • 某些用例如果不想執行,可以打上tag,設定不執行。
 
image

讓case具有文件性

在考慮Coding Style時我們可以設定一些固定的規則,大家只要按照這個規則來做,實踐幾次之後Coding Style就會趨於統一. 而考慮將Case寫的如同文件一般則需要更多的主觀能動性。

敏捷開發(Agile Development)在國內的發展已經越完善,伴隨之而來的便是敏捷測試(Agile Testing)。敏捷思想強調以人為核心,在整個開發流程中,只寫有必要的文件或儘量少寫文件,這也是它與傳統的瀑布模型的差別。

為了不造成誤解,這裡有必要插入的說一下敏捷測試的幾個特點:

  • 敏捷測試應該是敏捷開發的一部分;
  • 敏捷測試具有鮮明的敏捷開發的特徵,如測試驅動開發(TDD),驗收測試驅動開發(ATDD)。也就是說,單元測試是敏捷測試的基礎,如果沒有足夠的單元測試,就無法應對將來需求的快速迭代,也無法實現快速而穩定的持續交付;
  • 優秀的敏捷測試是基於自動化測試的;
  • 敏捷測試無時不在,無處不在。

需求設計不斷的更新,而文件往往不能被很及時的更新,那這樣的話怎麼才能讓測試人員如何快速的掌握某個功能或者產品的需求和當前狀態呢?

“Tests as Documentation.”

清晰易懂的用例名

在實際的工程中,我們可能會新建一個目錄來儲存測試點相近的測試用例。每一個Case都對應一個測試點,而用例名則應該概括總結對應測試點的核心內容,這樣當我們在瀏覽一組用例時,僅僅通過用例名就能大致瞭解裡面的測試內容,也方便尋找某個Case。

 
 

清晰易懂的用例名

在實際的工程中,我們可能會新建一個目錄來儲存測試點相近的測試用例。每一個Case都對應一個測試點,而用例名則應該概括總結對應測試點的核心內容,這樣當我們在瀏覽一組用例時,僅僅通過用例名就能大致瞭解裡面的測試內容,也方便尋找某個Case。

 
 

 



作者:Rethink
連結:https://www.jianshu.com/p/143d592933ae
來源:簡書
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。


相關文章