顧錚,10年+測試及測試開發相關經驗,2014年加入京東,曾主導設計開發UI測試框架,參與CI測試平臺建設,現負責iOS側的工具,框架建設。在UI自動化,性能測試,單元測試方面有較深刻研究,在App,web端等有較豐富的測試開發和設計經驗。php
>>>>android
寫在前面web
關於UI測試的文章,多數是經過架構的演進,或是重構,或是推翻重作來說述的。今天我想講述個人「一步到位」的測試框架設計。固然,這個「一步到位」是加引號的,並非說沒有持續的優化或改進,而是指基礎結構的穩定;這個「一步到位」是基於以前的失敗經歷和不少思考而得出的,總結我的經驗,避免其餘接觸很少的同窗走彎路、踩坑。架構
UI自動化測試,即經過模擬手動操做用戶UI界面的方式,以代碼方式實現自動操做和驗證的一種自動化測試手段。在十年前,那時候仍是PC web的天下,以Selenium驅動web UI的自動化測試仍是主流。五年前,當測試人員逐漸熟悉了Selenium API編寫UI自動化用例時,互聯網的主戰場已經從web端逐漸過渡到了app端。如今,app在UI自動化方面的框架已經比較成熟,例如咱們已經使用了三年多的appium,還有諸如uiautomator、espresso、robotium等等。app
>>>>框架
UI能解決什麼問題?運維
一、重複性的功能測試及驗證函數
二、避免疲憊操做時的人爲測試遺漏工具
三、經過UI自動化操做獲取其餘測試數據的能力性能
>>>>
UI的優缺點是什麼?
在實際應用中,UI自動化能夠幫助咱們節省人工測試成本,提升功能測試的測試效率。
缺點也是比較明顯,隨着敏捷迭代的速度愈來愈快,UI控件的頻繁變動致使控件定位不穩定,提升了用例腳本的維護成本,同時定位的不穩定致使用例的可信度下降。
>>>>
UI的應用場景
主要應用於冒煙測試、迴歸測試、Dailybuild等階段。
>>>>
UI存在的意義
存在即合理,咱們能夠先看下軟件測試的金字塔模型。
這個模型描述了從單元測試、集成測試,到UI測試的漸進式測試過程。越是底層,用例的執行速度越快,維護成本越低。到了最上層的UI時,執行速度處於比單元測試、接口測試慢,比手工測試快的這種階段。維護成本上比單元測試,接口測試要高。
那麼爲何須要作UI呢?
一、實施起來較容易:不少同窗都有過這種經歷,剛開始接觸測試開發時,都是先接觸UI的自動化。UI的框架比較成熟,容易上手,相關學習文檔比較全面。實施起來通常都不依賴於源碼,是比較容易落地的一種自動化測試手段。
二、覆蓋範圍廣:此項是重點。UI上的一次操做的函數觸發數量可能會很是多,點擊一個按鈕,可能觸發了內部的幾十個或者更多的函數調用。從函數調用數量來看,和單元測試的一個單測用例檢查一個函數的邏輯是不一樣的。UI操做檢查的各個模塊集成後模塊之間的聯動邏輯。是集成測試的有效手段,而單元測試是模塊內部邏輯的檢查。
>>>>
框架優勢
>>>>
框架如何避免或下降UI的問題呢?
首先看下架構圖
一、用例編寫簡單,下降上手門檻
因爲測試人員的代碼編寫能力良莠不齊,讓業務同窗能夠快速上手編寫是基本訴求。在operation層,使用了業界通用的Page-Object模式,即針對頁面或模塊封裝操做方式,這也符合咱們的正常認知,在哪一個模塊應該有什麼樣的功能操做。因此咱們在case層調用operation提供的接口時是很是方便的。下圖是一條比較複雜的購物車測試用例。page是模塊集合,main是首頁接口,switchView爲封裝的切換操做。
2. 下降用例維護成本
當UI控件發生改動時,咱們須要對對應的控件定位方式進行修改。通常地,一個控件會被多條甚至幾十條用例引用到,那麼維護成本與引用數量成正比,引用的地方越多,維護成本越大。如何下降控件修改爲本是很是關鍵的。
首先,須要作的是當封裝的邏輯發生改變時,不會影響咱們用例層的邏輯組織。解決辦法:
抽取各個模塊的功能接口,在用例層調用統一接口進行操做,與具體的實現無關。具體是執行android的操做邏輯,仍是iOS的操做邏輯須要在運行時判斷來選擇對應的實現類。既能保持調用的一致性,也能夠屏蔽不一樣端的邏輯差別性。當android和iOS操做邏輯一致時能夠卸載Adaptor裏,當兩端操做邏輯不一致時,須要分別在各自端的Operation中實現。
而後,當控件定位發生改變時,不會影響咱們在操做層的方法封裝代碼,把一處控件改動對應多處引用修改的一對多關係變爲一對一關係,即不管引用了多少處此控件,只須要修改一處代碼。
解決辦法:爲了使操做層在獲取控件時與控件的定位方式解耦,在操做層經過獲取自定義ID的方式來獲得控件對象。此ID須要在控件的配置文件中定義好,再經過操做層之下的代理層來統一處理。
操做層的操做封裝示例以下:
如上圖所示,自定義ID爲SearchBar,經過調用代理層的getTextBox方法來獲得一個文本輸入框類型的對象,並調用該接口的清除文本方法。
而後,在對應模塊的XML配置文件中添加ID名及控件的定位方式。
其中dependMethod爲控件查找方式,內嵌元素爲查找的值。因爲在編寫操做方法時引用的是自定義ID,且ID不會改變。因此在Operation層封裝的全部操做是不會由於控件改變而修改代碼的。一對一的關係即:控件修改 —> xml配置修改。
經過以上這些設計,大大下降咱們在用例編寫完成以後的維護成本。
三、底層識別框架(Appium)的可替換性,屏蔽不一樣框架的差別性API
有的時候,咱們須要不止一套控件的識別驅動來幫助咱們定位控件或執行操做。好比:若是不用appium,那麼使用其餘框架勢必會帶來一些底層的改動,好比因爲API的不一樣而須要重寫大部分的查找和操做方法。形成較大的替換成本。那麼設計一套自定義的控件接口,與控件識別驅動解耦是一個好的選擇,上層統一調用自定義接口進行操做,而控件的實現類能夠根據你須要的驅動類進行選擇或封裝。
四、失敗重試機制,提升用例穩定性
因爲用例執行的穩定性直接決定用例在業務落地時的可信度,因此提升用例穩定性是必要的,框架提供了失敗重試的機制來間接保證穩定性。即當監聽到用例執行失敗異常時,從新執行當前用例邏輯,若是執行成功,覆蓋當前用例的執行結果;若是失敗,從新執行,直到超太重試次數。
五、協助快速定位問題的能力
框架提供了日誌和失敗時截圖進行分析和定位問題的能力。
六、數據統計的能力
用例的執行信息等數據都是由TestNG提供,再作自定義處理。
>>>>
UI測試的落地指標
一、用例執行經過率(穩定性)
通常地,執行經過率達到95%以上時,對功能測試同窗的幫助纔是有意義的。經過率達不到的時候會大大增長執行用例同窗的運維成本。把大量時間放在了排查不穩定用例的問題上。
經過率的定義:(成功數 / 成功+失敗+跳過數 )* 100%
二、核心用例覆蓋率
覆蓋率定義:已實現自動化用例數 / 功能測試核心用例總數 * 100%
通常地,總有一小部分手工用例是沒法經過UI來實現的,或者就算實現了也很是不穩定。也就是說達到100%的覆蓋率是基本不可能的。此項指標的意義在於能夠客觀的反應經過自動化手段代替手工勞動的覆蓋比例。一味的提升覆蓋率是不可取的,保持用例的經過率,提升用例的穩定性是重點。
三、資源投入度
這個指標實際上是一個通用指標,但它與咱們具體的落地密切相關。更多的時候,前2個指標都會依賴於此項指標。自動化測試須要的是持續資源投入,只有自上而下的推進才能取得更好的效果,體現它該有的做用。
>>>>
UI測試對接CI平臺
因爲appUI框架是線下本機環境執行和操做手機,能夠搭建一個線上的公共平臺來選擇和觸發UI的執行。做爲一種常規的,自動化得測試類型嵌入到敏捷測試流程中。
如下是對接CI平臺的執行簡圖: