從0到1開發自動化測試框架

1、序言

隨着項目版本的快速迭代、APP測試有如下幾個特色:css

  • 首先,功能點多且細,測試工做量大,容易遺漏;
  • 其次,代碼模塊常改動,迴歸測試很頻繁,測試重複低效;
  • 最後,數據環境多樣,用戶場景複雜,功能迴歸覆蓋難全面。
爲節省成本,保證高效及高質量迭代,咱們需採用更高效的測試方式,App自動化測試是較高效的手段。
以前自動測試實踐過程當中遇到的諸多問題(代碼複用率低,Case開發及數據構造繁瑣,問題定位困難,學習成本高等),爲解決相關痛點問題,咱們從新實現了一套APP自動測試框架。本文將着重介紹技術選型、設計思路及百度外賣App的具體實踐。

 

2、自動化測試框架技術選型

一個項目中自動化測試是否能有效的展開,自動化測試框架是關鍵所在。所以,如何如何構建穩定的、易擴展的自動化的測試項目對於敏捷測試有重要的意義。在設計框架的時候應該儘量的沿用自動化測試工具已提供的功能,避免重複開發,以減小開發成本。
經過對現有自動化測試工具的原理進行深刻分析及優缺點比較,並基於Appium和TestNG兩類自動化測試框架解決上述自動化測試中遇到的問題。
  • 首先,經過利用TestNG結合csv的使用,將測試用例數據轉化爲測試代碼中的數據,減小了測試人員錄入數據和準備數據的工具;
  • 再次,經過對appium的封裝,按照面向對象的思想將測試中用到的頁面元素封裝成對象,加強測試代碼的複用率,並減輕測試人員對底層代碼實現的負擔,提升測試代碼編寫效率;
  • 最後,引入失敗重跑、失敗截屏,並經過reportng生成測試報告的方式,逐步完善測試過程,提升定位問題的速度;

TestNGhtml

Testng是一個開源自動化測試框架,引入了許多新的創新功能,如依賴測試,分組概念,使測試更強大,更容易作到。 旨在涵蓋全部類別的測試:單元,功能,端到端,集成等。TestNG框架能夠很好地幫咱們完成WebDriver+java的頁面自動化工做,經過各類註釋的靈活運行,可使你的測試用例更加完美,定製符合要求的測試用例
  1. TestNG是一個設計用來簡化普遍的測試需求的測試框架,從單元測試到集成測試。 這個是TestNG設計的出發點,不只僅是單元測試,並且能夠用於集成測試。設計目標的不一樣,對比junit的只適合用於單元測試,TestNG無疑走的更遠。能夠用於集成測試,這個特性是我選擇TestNG的最重要的緣由。
  2. 測試的過程的三個典型步驟,和junit(4.0)相比,多了一個將測試信息添加到testng.xml文件。 測試信息尤爲是測試數據再也不寫死在測試代碼中,好處就是修改測試數據時不須要修改代碼/編譯了,從而有助於將測試人員引入單元測試/集成測試。
  3. 基本概念,相比junit的TestCase/TestSuite,TestNG有suite/test/test method三個級別,即將test/test method明確區分開了。

Appiumjava

Appium一個開源、跨平臺的測試框架,能夠用來測試原生及混合的移動端應用。Appium支持iOS、Android及FirefoxOS平臺測試。Appium使用WebDriver的json wire協議,來驅動Apple系統的UIAutomation庫、Android系統的UIAutomator框架。相比其餘的移動自動化測試工具,Appium測試因爲調用了Selenium的client庫使其可使用任意的語言,包括Python、Ruby、Node.js、Objective-C等。android

 

3、自動化測試框架的設計思路

測試設計過程和測試自動化框架必須做爲兩個單獨的實體來開發。git

測試框架應該獨立於應用程序;web

測試框架應該易於擴展 、維護和加強;數據庫

測試策略/設計應該對測試者隱藏測試框架的複雜性。json

 

4、自動化框架介紹

該框架基於Selenium WebDriver開源技術開發。本框架使用Maven工具進行Project管理,採用TestNG工具組織測試,應用CSV文件存儲測試數據,實現測試數據與測試用例的分離,方便測試數據管理,下降自動化腳本的維護成本,實現數據驅動。此外,該框架還封裝了豐富的Selenium方法關鍵字,借鑑了QTP語法結構,實現了直觀清晰的結構化代碼語法,如:Page.Item.Operate,下降自動化代碼的冗餘與重複。藉助Jenkins 進行CI測試,實現測試任務的Schedule 和Report功能,經過Jenkins Master/Slave模式管理虛擬機節點,實現多任務多機器分佈式併發的執行管理,從而提升測試效率。設計模式

  • 該框架的好處在於: 一、構建可複用的、穩定的代碼集。經過封裝appium實現用例執行與數據調用分離,參數化配置經常使用信息,並提供統一接口; 二、模塊化管理自動化測試用例。主要根據TestNG工具的支持參數測試和依賴測試的特色實現; 三、測試結果分析和統計。利用jenkins工具創建持續集成,按期運行自動化測試項目,並將測試結果以定製化的形式展示。

測試框架分層安全

基於UI測試,咱們但願除了支持web測試,還能支持app的測試,可能還須要接口測試,咱們就須要考慮分層問題,將測試框架分爲三層。上層是管理整個自動化測試的開發,執行以及維護,在比較龐大的項目中,它體現重要的做用,它能夠管理整個自動測試,包括自動化測試用例執行的次序、測試腳本的維護、以及集中管理測試用例、測試報告和測試任務等。下層主要是測試腳本的開發,充分的使用相關的測試工具,構建測試驅動,並完成測試業務邏輯。

第一層:數據層

即執行用例時所須要的測試數據,如商戶名、空間名、URL等,這些數據用來支撐整個腳本的執行。針對數據層,這裏採了用數據驅動的方式。

第二層:驅動層

這一層主要封裝各類driver。好比咱們針對網頁測試,使用selenium-webdriver開發包,針對app測試,咱們使用appium開發包。咱們在這一層進行封裝,經過調用selenium-webdriver,appium提供的原生方法,封裝成可讀性很強的方法且加上容錯機制。之後就算咱們要換用其餘的第三方包,咱們的測試案例層和支持層的方法也不須要作任何的修改。只須要修改driver層實現的方式就能夠了。在一層,咱們主要實現兩個方面的封裝,一個是driver的封裝,一個是基於基類天然語言函數的封裝。

 

driver封裝

咱們須要封裝,根據參數確實是基於web測試仍是基於app測試。好比:

 

基類封裝

主要是封裝各類可讀性很很強的方法以及將元素定位標識及driver也封裝進去。爲了支持網頁測試和app測試,咱們須要兩個基類,一個是針對網頁操做基類,一個是針對app操做基類。同時爲了web和app操做的一致性,咱們要求對外提供的方法,必需要將經常使用的方法保持一致的名字和同樣的參數類型及參數個數。
APP基類示例以下:

經過對driver和基類的封裝,driver層實現了對網頁測試和app測試的支持,而且針對兩種測試,都提供了統一的方法,可以方便使用者,使用相同的方法,測試app和web。

 

第三層:測試案例層

該層是測試案例的具體實現,就像上面寫的case那樣,用接近天然語言的方式,來實現測試案例。

 

第四層:支持層

該層主要提供workflow,通用工具,元素庫的支持,便於測試案例層直接調用。

  • Workflow:主要封裝測試項目中須要常用的針對項目的公用方法,供測試案例層直接調用。好比用戶登陸,註冊一個用戶,搜索出用戶等等常用的動做;
  • 通用工具:提供一些通用方法,好比生成指定Page類,文件讀取操做,DB操做,http操做支持等等;
  • 元素庫:每個頁面元素的定位表達式(xpath,id,name,css,link_text等等表達式)。 咱們的測試案例,都是針對一個個元素進行操做的。將每個頁面的每個元素,都當作一個繼承了基類的特定類。因此,咱們的第一步,就須要找到這個元素,定位到這個元素。測試項目的全部元素都放到這裏。

 

第五層:結果保存層
將測試腳本的日誌和結果以自定義的方式展現,這裏使用了ReportNG,它能夠豐富測試結果的展示形式,幫助團隊更快定位和解決問題。

 

5、框架技術要點解析

5.一、PO模式

 

5.1.一、遇到的問題

使用webdriver作過一段時間的測試就會發現一個對某一個頁面的元素進行定位的時候,程序行間充斥着id()、name()、xpath()等方法,這樣會形成測試程序的可讀性較差,不便於後期的維護以及修改。

雖然咱們能夠經過添加註釋的方法使程序便於理解,可是仍是不能夠從根本上解決這種問題。咱們能夠經過對這些方法進行二次封裝來避免每次對這些方法的直接調用,經過方法的封裝雖然能夠實現複用。可是咱們發現經過封裝沒法實現頁面元素的邏輯處理和測試數據的獨立。

 

5.1.二、問題的解決辦法:引入PO

Page Object模式是Selenium中的一種測試設計模式,是指UI界面上用於與用戶進行交互的對象。主要是將每個頁面設計爲一個Class,其中包含頁面中須要測試的元素(按鈕,輸入框,標題 等),這樣在Selenium測試頁面中能夠經過調用頁面類來獲取頁面元素,這樣巧妙的避免了當頁面元素id或者位置變化時,須要改測試頁面代碼的狀況。 當頁面元素id變化時,只須要更改測試頁Class中頁面的屬性便可。經過對界面元素的封裝減小冗餘代碼,提升測試用例的可維護性。

通常狀況下,對於一個Page Objects對象,它有兩個方面的特徵:

  • 自身元素(WebElement)
  • 實現功能 (Services)

仔細分析測試場景,抽出UI測試的核心行爲,無非就是:

一、檢查點:

頁面元素是否存在;

頁面元素顯示內容是否正確;

頁面元素是否可用;

……

二、輔助功能:

等待元素出現;

點擊某頁面元素;

給元素輸入內容;

……

 

分析抽出來的核心行爲,發現這些行爲基本都是針對一個個頁面元素進行的操做。那麼咱們就能夠作以下的動做:

 

將頁面元素當作一個對象,封裝成一個類;

將上面分析獲得的核心行爲都封裝成基類方法。而後確保,任何一個頁面元素都繼承該基類;
該基類提供相似於天然語言的方法名字,調用這些方法,就能很明確的知道測試案例在作什檢查,在作什麼行爲,這樣就能極大的提升測試案例的可讀性。

該基類主要目的是在UI測試中,對元素共性的檢查點和輔助方法進行抽取,將它們封裝成一個個很是容易讀懂的方法,且具備異常處理能力。

 

通過上述思路的整理,測試用例能夠改寫成以下:

在實際的使用過程當中,可讓不太熟悉代碼的QA專門負責測試案例的實現,底層的方法包裝能夠由經驗豐富一些的同窗作。

 

5.二、數據驅動

數據驅動的自動化測試框架是這樣的一個框架,從某個數據文件(例如ODBC源文件、Excel文件、Csv文件、ADO對象文件等)中讀取輸入、輸出的測試數據,而後經過變量傳入事先錄製好的或手工編寫的測試腳本中。其中,這些變量被用做傳遞(輸入/輸出)用來驗證應用程序的測試數據。在這個過程當中,數據文件的讀取、測試狀態和全部測試信息都被編寫進測試腳本里;測試數據只包含在數據文件中,而不是腳本里,測試腳本只是一個「驅動」,或者說是一個傳送數據的機制。

  1. 在數據文件中填寫測試數據:
  2. 生成Page類:
  3. Page類中初始化頁面元素:

基於數據驅動的好處在於:

在應用程序開發的同時就能夠同步創建測試腳本,並且當應用功能變更時,只須要修改業務功能部分的腳本;

利用模型化的設計,避免重複的腳本,減小創建或維護腳本的成本。

 

5.三、失敗重跑與失敗截圖機制

自動化測試過程當中,經常因爲網絡、服務器響應過慢、JS特效及頁面渲染時間較長,致使自動化測試失敗。針對此類場景,本框架設計了一套NRetry機制,即某個case運行失敗後,重跑N次,N可自定義。N次中有一次成功,則繼續運行,若N次均失敗,則截圖、拋錯,中止運行。NRetry機制,必定程度上能夠下降因爲網絡、服務器響應過慢致使的自動化執行的不穩定性。

 

5.3.一、失敗自動截圖

  1. 新建一個Java類繼承TestListenerAdapter:
  2. 重寫onTestFailure、onTestSkipped等方法,在這些方法中加入截圖操做:
  3. 在testng.xml文件中配置本身編寫的監聽器類:

 

5.3.二、失敗自動重跑

在運行自動化測試用例的時候,常常會出現一些異常的狀況的狀況致使用例失敗的問題。因此咱們可能會但願對於失敗的測試用例再從新運行一次,框架中咱們結合TestNG來實現這個功能。

  1. 新建TestNGRetry類,實現用例失敗自動重跑邏輯:
  2. 添加用例重跑監聽器RetryListener,用例失敗自動重跑功能:
  3. 在testng.xml文件中配置本身編寫的監聽器:

 

5.四、ReportNG

TestNG默認的HTML報表,其默認的報表雖然信息全面,但不易於理解。所以,咱們利用ReportNG來替代TestNG默認的report。

ReportNG提供了一種簡單的方式來查看測試結果,並可以對結果代碼進行着色。還能夠經過修改CSS文件來替換默認的輸出樣式。此外ReportNG還可以生成Junit格式的XML輸出。
因爲咱們使用的是maven,因此咱們主要來看看pom.xml的狀況:

maven-surefire-plugin 這個插件主要是用於testng的。咱們經過該插件,在對應的目錄下./target/${timestamp}生成咱們的測試報告目錄。咱們能夠看到這個目錄的結構。

這裏實際上就是reportng的測試報告的生成路徑。可是咱們想要經過郵件發送會很難,由於html的內容須要加在額外的css,以及js文件。而郵件其實是不支持外部的css以及js文件的。

HTML的生成

一、定義HTML模版

查看indexMain.html.vm:

在使用ReportNG替換TestNG自帶報告時若是報告中含中文,因爲ReportNG 裏面Log 是不支持中文的,因此經過修改ReportNG.jar源碼來支持報告內中文展現。

 

5.五、日誌收集

日誌是軟件開發的重要組成部分。自動化執行過程的日誌信息,對於失敗用例的分析定位以及全過程的跟蹤記錄是十分重要的。

相對於簡單的輸出打印,本框架集成了主流的日誌收集工具log4j。Log4j是高度可配置的,並可經過在運行時的外部文件配置。經過配置log4j.properties文件,定義日誌級別內容及日誌輸出路徑收集日誌信息(諸如:數據庫,文件,控制檯,UNIX系統日誌等),提供快速的調試,維護方便,以及應用程序的運行時信息結構化存儲。

配置文件

Log4j能夠經過java程序動態設置,該方式明顯缺點是:若是須要修改日誌輸出級別等信息,則必須修改java文件,而後從新編譯,非常麻煩;log4j也能夠經過配置文件的方式進行設置,目前支持兩種格式的配置文件:

xml文件;

properties文件(推薦)。

 

5.六、郵件發送

測試報告的發送能夠結合Jenkins來實現,經過簡單的配置便可實現。但是若是團隊沒有搭建jenkins或者有時jenkins不可用,咱們應該如何去處理這部分的內容呢?

既然郵件不可以依賴jenkins,那確定得本身去實現這部分的內容了。因此咱們仍是得依賴一些第三方的jar包。咱們在pom.xml配置。

 

6、後續TODO

在後續的版本演進中,將把自動化測試、代碼安全掃描、多機並行測試、持續發佈都加入了總體過程,真正的作到全過程持續交付。

 

6.一、夜間構建加入自動化測試

夜間構建會按計劃按期觸發自動化構建過程,但這種構建只是簡單的代碼編譯,沒有可靠的或可重複的功能測試。後續考慮Appium結合Jenkins來實現構建後自動化測試工做。
不管任什麼時候候,只要代碼更新提交到git中,構建服務器就會觸發一個構建,構建運行腳本去編譯應用程序而且運行一系列的自動化單元測試和/或集成測試。經過自動化測試結果可以清晰的展現出那些功能特性是經過的,哪些是失敗的。無論是有改動提交,仍是按期在夜間觸發構建,應用程序都會被自動部署到測試環境當中以便QA團隊進行測試。

 

6.二、Jenkins與STF結合,實現多機並行測試

Jenkins構建腳本完成後,將沒有安裝stf組件電腦上鍊接的android設備,添加映射到裝有stf平臺服務的機器上,將集成測試用例push到STF平臺,再由STF分發到可運行設備上,進行多機並行測試。

STF執行APPIUM測試帶來的優點

第1、能夠在真機上執行並行的Appium測試。因爲最初的Appium使用對象是模擬器上或只是以每次一臺設備的測試方法執行測試,而STF在原有的基礎上擴展了Appium,最多可在數百臺真機上同時執行測試的能力。

第二,不須要配置任何設備的Desired Capabilities。這種方式既簡便,且減小了由於編輯腳本而產生的不一樣類型的錯誤。

第三,在STF上執行測試可讓用戶即時瀏覽測試情況。也就是說,能夠查看到測試執行的進度,即時的錯誤反饋,以及保留和查閱全部測試項目,測試腳本和測試結果(測試截圖,測試日誌,性能數據等)

 

6.三、代碼質量度量

 

6.3.一、爲何要分析代碼

對代碼質量關注時,安排人工進行code review是須要的,但100%的code review卻須要投入人員,消耗大量的工做量,而工具自動檢查只需少許人工配置。

最主要的緣由就是提升代碼質量,瞭解RD在編碼過程當中犯過的錯誤可能對功能邏輯產生的影響,同時也推進RD讓本身的代碼更具備可讀性和維護性,因此咱們借鑑持續改進的流程,但願可以在這個過程當中有所收穫。

 

6.3.二、Jenkins引入Sonarqube進行代碼持續審查

Sonar是一個用於代碼質量管理的開源平臺,用於管理Java源代碼的質量。經過插件機制,Sonar 能夠集成不一樣的測試工具,代碼分析工具,以及持續集成工具,好比pmd-cpd、checkstyle、findbugs、Jenkins。經過不一樣的插件對這些結果進行再加工處理,經過量化的方式度量代碼質量的變化,從而能夠方便地對不一樣規模和種類的工程進行代碼質量管理。

 

6.四、email-ext實現Jenkins郵件通知功能

在Jenkins中配置實現郵件通知,Jenkins提供了兩種方式的配置。

一種是Jenkins內置默認的郵件通知,可是它自己有不少侷限性,好比它的郵件通知沒法提供詳細的郵件內容、沒法定義發送郵件的格式、沒法定義靈活的郵件接收配置等等。

在這樣的狀況下,後續考慮能夠經過Email Extension Plugin來實現自定義郵件通知的方方面面,好比在發送郵件的同時能夠自定義發送給誰,發送具體什麼內容等等。

相關文章
相關標籤/搜索